使用PostgreSQL hstore for i18n

czfnxgou  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(136)

我只是在为一个需要本地化支持的新项目建模PostgreSQL数据库。我想知道 hstore 是否可能是本地化某些数据字段的好方法。
举例来说:让我们用一个包含字段post_titlepost_content的博客帖子的简化表。使用键-值类型 hstore,可以向这些字段添加几个翻译,并将语言代码标识为键:

id | post_title (hstore)   | post_content (hstore)
---|-----------------------|------------------------------
 1 | "en" => "Hello World",| "en" => "Content in english",
   | "de" => "Hallo Welt"  | "de" => "Inhalt auf deutsch"
---|-----------------------|------------------------------
 2 | ...                   | ...

字符串
有没有人在这方面有经验?它似乎是非常灵活和易于使用,但也许我错过了一些显着的缺点在这里?

zed5wv10

zed5wv101#

我在一个项目中也使用了这种方法,我相信这是一个很好的决定,因为我可以很容易地向我的项目中添加一种新的语言,而不需要编写代码或更新数据库模式
我也可以很容易地添加回退到这样的查询:

select coalesce(nullif(post_title -> :lang, ''), post_title -> 'en') from posts

字符串
另外,还有很多强大的sql函数供您使用。

rjjhvcjd

rjjhvcjd2#

是的,这是一个非常好的方法,可以非常有效地使用索引进行搜索。不久前,我研究了如何为产品数据库创建一个易于搜索的多语言数据模型。最后得到了这样的schema:
x1c 0d1x的数据
缺点是必须为每种支持的语言创建索引

CREATE EXTENSION IF NOT EXISTS pg_trgm;

CREATE INDEX product_details_name_idx ON Product
USING GIN (lower(details_name_value) gin_trgm_ops);

CREATE INDEX product_translated_name_idx ON Product
USING GIN (lower(details_name_translationbylanguage -> 'pl') gin_trgm_ops);

字符串
但结果是你得到了一个非常有效的执行计划:

explain select
    product0_.id as id1_0_,
    product0_.details_code as details_2_0_,
    product0_.details_description_translationByLanguage as details_3_0_,
    product0_.details_description_value as details_4_0_,
    product0_.details_name_translationByLanguage as details_5_0_,
    product0_.details_name_value as details_6_0_,
    product0_.details_price as details_7_0_
from Product product0_
where lower(product0_.details_name_value) like ('%'||lower('aaa')||'%')
or lower(product0_.details_name_translationByLanguage -> 'pl') like ('%'||lower('aaa')||'%')

  Bitmap Heap Scan on product product0_  (cost=175.84..5669.84 rows=15680 width=173)
  Recheck Cond: ((lower((details_name_value)::text) ~~ '%aaa%'::text) OR (lower((details_name_translationbylanguage -> 'pl'::text)) ~~ '%aaa%'::text))
  ->  BitmapOr  (cost=175.84..175.84 rows=16000 width=0)
        ->  Bitmap Index Scan on product_details_name_idx  (cost=0.00..84.00 rows=8000 width=0)
              Index Cond: (lower((details_name_value)::text) ~~ '%aaa%'::text)
        ->  Bitmap Index Scan on product_translated_name_idx  (cost=0.00..84.00 rows=8000 width=0)
              Index Cond: (lower((details_name_translationbylanguage -> 'pl'::text)) ~~ '%aaa%'::text)


它甚至可以很容易地与Java JPA/Hibernate中的ORM集成。
您可以查看我关于该主题的完整文章,其中包含以下代码示例:https://walczak.it/blog/performant-internationalization-in-postgresql-hibernate-jpa-hstore-column-with-translations

相关问题