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

时间:2012-07-24 11:18:03

标签: php mysql json localization internationalization

更新:我遇到过几年后我做过的这个问题:现在我知道这是一个非常糟糕的方法。请不要使用它。您可以随时为i18n使用其他表(例如productsproducts_lang),每个语言环境都有单独的条目:更好的索引,更适合搜索等。


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

我已经阅读了答案,说明“i18n通常不属于数据库”,我认为这是一种有点狭隘的方法。 那些名为productd的产品,或者在我的实例中,存储在db?中的菜单结构和内容呢?

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

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

我认为另一种解决方案是使用JSON。所以我的数据库中的菜单条目看起来像:

idmenu label
------ -------------------------------------------
5      {"en":"Homepage", "it":"pagina principale"}

您如何看待这种方法?

4 个答案:

答案 0 :(得分:2)

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

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

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          
)

我会创建:

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)
)

我会这样查询:

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

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

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

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

与其他人指出的一样,JSON的想法存在一个问题,即查询它是不可能的,这反过来意味着无法仅提取您在特定时间需要的翻译。

答案 1 :(得分:1)

这不是扩展名。您失去了使用关系数据库的所有优点。与您的一样,您可以使用serialize()来获得更好的解码和存储数据的性能,即使在文件中也是如此。没有特别使用具有这种结构的SQL。

我认为使用所有语言的列都没问题。这在CMS的编程中更容易。关系数据库不仅用于存储数据。它是为了合理地处理数据(例如使用强大的内置机制)和控制数据的结构和完整性。

答案 2 :(得分:0)

首先想到:这显然会在sql WHERE label ='Homepage'中制作精确搜索 第二:用户在搜索时可以看到不需要的结果(例如,当他的查询在其他语言字符串中找到时)

答案 3 :(得分:0)

我建议在数据库中保留一种主要语言,并使用额外的子系统来维护翻译。这是Drupal等Web应用程序的标准方法。最有可能在您的软件/应用程序的域中,每个主要语言字符串都会有一个翻译,因此您不必担心上下文或含糊不清。 (事实上​​,为了获得最佳用户体验,您应该努力为独特功能提供独特的标签)。

如果您想要自己的表格,可以使用以下内容:

create table translations (
  id          int          not null primary key
, source      varchar(255) not null // the text in the primary language
, lang        varchar(5)   not null // the language of the translation
, translation varchar(255) not null // the text of the translation
) 

您可能需要超过2个字符的语言,因为您可能需要en_US,en_UK等。