Tôi chưa bao giờ chơi với hstore, nhưng tôi làm điều gì đó tương tự khi tôi cần một cột EAV, ví dụ:
create index on product_eav (eav_value) where (eav_type = 'int');
Hạn chế khi làm như vậy là bạn cần phải rõ ràng trong truy vấn của mình để sử dụng nó, tức là truy vấn này sẽ không sử dụng chỉ mục trên:
select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size;
Nhưng cái này sẽ:
select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size
and type = 'int';
Trong ví dụ của bạn, nó có thể giống như sau:
create index on product ((data->'size')::int) where (data->'size' is not null);
Điều này sẽ tránh thêm tham chiếu vào chỉ mục khi không có mục nhập kích thước. Tùy thuộc vào phiên bản PG mà bạn đang sử dụng, truy vấn có thể cần được sửa đổi như vậy:
select product_id
from products
where data->'size' is not null
and data->'size' = :size;
Một sự khác biệt lớn khác giữa chỉ mục thông thường và chỉ mục một phần là chỉ mục sau không thể thực thi một ràng buộc duy nhất trong định nghĩa bảng. Điều này sẽ thành công:
create unique index foo_bar_key on foo (bar) where (cond);
Những điều sau sẽ không:
alter table foo add constraint foo_bar_key unique (bar) where (cond);
Nhưng điều này sẽ:
alter table foo add constraint foo_bar_excl exclude (bar with =) where (cond);