MySQL 数据库 I18N,一种 JSON 方法?

Cra*_*nio 5 php mysql json localization internationalization

更新:几年后我遇到了这个问题:现在我知道这是一个非常糟糕的方法。请不要使用这个。您始终可以为 i18n 使用其他表(例如productsproducts_lang),为每个区域设置单独的条目:更适合索引,更适合搜索等。


我正在尝试在 MySQL/PHP 站点中实现 i18n。

我读过一些回答说“i18n 通常不是数据库的一部分”,我认为这是一种有点狭隘的方法。产品名称,或者,就像我的例子一样,存储在数据库中的菜单结构和内容怎么样?

我想知道您如何看待我的方法,考虑到语言应该是可扩展的,所以我试图避免“每种语言解决方案一栏”。

一种解决方案是对要翻译的字符串使用引用 (id),并且对于每个可翻译列都有一个包含主键、字符串 id、语言 id 和翻译的表。

我认为的另一个解决方案是使用 JSON。因此,我的数据库中的菜单条目如下所示:

idmenu label
------ -------------------------------------------
5      {"en":"Homepage", "it":"pagina principale"}
Run Code Online (Sandbox Code Playgroud)

您如何看待这种方法?

Rol*_*man 4

“一种解决方案是对要翻译的字符串使用引用 (id),并且对于每个可翻译列都有一个包含主键、字符串 id、语言 id 和翻译的表。”

我实现了一次,我所做的是采用现有的数据库模式,查找具有可翻译文本列的所有表,对于每个这样的表,我创建了一个仅包含这些文本列的单独表,以及一个附加的语言 id 和 id 来绑定它到原始表中的“数据”行。所以如果我有:

create table product (
  id          int          not null primary key
, sku         varchar(12)  not null
, price       decimal(8,2) not null
, name        varchar(64)  not null
, description text          
)
Run Code Online (Sandbox Code Playgroud)

我会创建:

create table product_text (
  product_id  int          not null
, language_id int          not null
, name        varchar(64)  not null
, description text
, primary key (product_id, language_id)
, foreign key (product_id) references product(id)
, foreign key (language_id) references language(id)
)
Run Code Online (Sandbox Code Playgroud)

我会这样查询:

SELECT    product.id
,         COALESCE(product_text.name, product.name) name
,         COALESCE(product_text.description, product.description) description
FROM      product
LEFT JOIN product_text
ON        product.id = product_text.product_id 
AND       10         = product_text.language_id
Run Code Online (Sandbox Code Playgroud)

(10 恰好是您现在感兴趣的语言 ID。)

正如您所看到的,原始表保留了文本列 - 这些作为默认值,以防当前语言没有可用的翻译。

因此,无需为每个文本列创建单独的表,只需为所有文本列创建一个表(每个原始表)

正如其他人指出的那样,JSON 想法存在一个问题,即几乎不可能对其进行查询,这反过来又意味着无法仅提取特定时间所需的翻译。