如何在PostgreSQL中索引多语言实体

问题描述

在这里,我正在创建表product_feature_text,它与表product具有1:N的关系。由于应用程序必须支持多种用户语言,因此添加lang_code列以将英语文本与其他语言文本进行分段。

由于我想按每种语言按字母顺序显示产品功能,因此我创建了四个带有特定collate的部分索引。预期所有产品功能在所有四种语言中都具有title,例如,将有25%的行带有lang_code = 'ES'

这是对真实案例的过度简化,但足以描述情况。

create table product_feature_text (
  id          bigint generated by default as identity primary key,-- reference to the parent product
  product_id  bigint not null,-- language dependent columns
  lang_code   char(2),title       varchar,foreign key (product_id) references product (id)
);

create index on product_feature_text (title collate "en-US") where lang_code = 'EN';
create index on product_feature_text (title collate "es-ES") where lang_code = 'ES';
create index on product_feature_text (title collate "fr_FR") where lang_code = 'FR';
create index on product_feature_text (title collate "de_DE") where lang_code = 'DE';

这是案例的最佳索引方法吗?

评论的附录:典型的查询

select text
from product_feature
where product_id = 1024
   and lang_code = 'FR'
order by title collate "fr_FR"

product_id可以是任何东西。

解决方法

这取决于索引的预期用途。

如果您想将它们用于

SELECT ... FROM product_feature_text
WHERE lang_code = 'EN' AND ...
ORDER BY title COLLATE "en-US";

您的索引可能会有用。

此外,如果您的查询看起来像

WHERE product_feature_text > 'bhd'  COLLATE ...

可能会有所帮助。

但是,对于我可以设想的大多数情况,一个排序规则无关紧要的索引会更好。

对于附录中的查询,完美的索引应该是:

CREATE INDEX ON product_feature (product_id,title COLLATE "fr_FR")
   WHERE lang_code = FR';