2013-04-13 14 views

Trả lời

10

Các băm md5 như bytea sẽ chỉ sử dụng 16 byte trong thay vì 32 cho các đại diện hexa:

create table t (d bytea); 
insert into t (d) values 
    (digest('my_string', 'md5')), 
    (decode(md5('my_string'), 'hex')); 

Cả hai hình thức trên sẽ làm việc nhưng để sử dụng đơn giản hơn digest chức năng nó là cần thiết để cài đặt phần mở rộng pgcrypto như superuser:

create extension pgcrypto; 

Sử dụng digest chức năng hoặc sự kết hợp của decodemd5 như trên để tìm kiếm một chuỗi nhất định:

select 
    octet_length(d) ba_length, 
    pg_column_size(d) ba_column, 
    encode(d, 'hex') hex_representation, 
    octet_length(encode(d, 'hex')) h_length, 
    pg_column_size(encode(d, 'hex')) h_column 
from t 
where d = digest('my_string', 'md5') 
; 
ba_length | ba_column |  hex_representation  | h_length | h_column 
-----------+-----------+----------------------------------+----------+---------- 
     16 |  17 | 3d212b21fad7bed63c1fb560c6a5c5d0 |  32 |  36 
     16 |  17 | 3d212b21fad7bed63c1fb560c6a5c5d0 |  32 |  36 

Giá trị pg_column_size là kích thước lưu trữ. Nó là ít hơn một nửa cho bytea so với các đại diện hexa.

1

bytea có chi phí một byte, nhưng với đệm thành tám byte, điều này sẽ dẫn đến lãng phí đáng kể.

Thay vào đó, hãy cân nhắc sử dụng loại uuid, chỉ sử dụng 16 byte. Bạn sẽ phải sử dụng một cái gì đó như REPLACE(md5::text, '-', '') as md5 khi chọn nó, nhưng đó sẽ là một hoạt động nhanh chóng.

+0

Bạn có tham chiếu cho 'padding đến 8 byte' không? Tất cả [tài liệu nói] (http://www.postgresql.org/docs/9.4/static/datatype-binary.html) là dung lượng lưu trữ = "1 hoặc 4 byte cộng với chuỗi nhị phân thực tế" –

+0

Hai vấn đề: a) bạn đang lưu trữ 1 + 16 = 17 byte, cột tiếp theo sẽ được đệm cho mỗi typalign trong [pg_type] (http://www.postgresql.org/docs/9.0/static/catalog-pg-type.html), b) xem [câu hỏi này] (http://stackoverflow.com/questions/2966524/calculating-and-saving-space-in-postgresql) về MAXALIGN và [tham chiếu bố cục trang] (http://www.postgresql.org) /docs/9.4/static/storage-page-layout.html) cho liên kết * hàng *. ["Dữ liệu người dùng thực tế (các cột của hàng) bắt đầu tại mức bù trừ được chỉ ra bởi t_hoff, phải luôn là bội số của khoảng cách MAXALIGN cho nền tảng." == 8 trên x64]. – GreenReaper

+0

Trong trường hợp cụ thể này, việc sử dụng không gian hàng có thể là 23 + 1 (tiêu đề hàng + tiêu đề rỗng cho tối đa 8 cột) + 4 (ba_length) + 4 (ba_column) + 1 + 16 (hex_representation) + 3 (căn chỉnh đệm cho h_length) + 4 (h_length) + 4 (h_column) = 60 + 4 (hàng đệm). Đó là cách bạn nhận được 1 + 3 + 4 = 8 byte nhiều hơn bằng cách sử dụng uuid. Tóm lại: nếu bạn quan tâm đến không gian, bạn phải quan tâm đến bố cục hàng của bạn. Thông thường, đặt các trường lớn trước tiên là gần tối ưu, mặc dù nếu nó lớn hơn 8 byte bạn có thể xem xét lại. – GreenReaper