5

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


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

我已经阅读了“i18n 通常不是数据库的一部分”的答案,我认为这是一种狭隘的方法。产品名称怎么样,或者像我的例子一样,存储在数据库中的菜单结构和内容呢?

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

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

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

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

您如何看待这种方法?

4

4 回答 4

3

“一种解决方案是为要翻译的字符串使用参考 (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          
)

我会创建:

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 想法的问题是几乎不可能查询它,这反过来意味着无法仅提取特定时间所需的翻译。

于 2012-07-24T11:32:27.880 回答
1

这不是扩展。您失去了使用关系数据库的所有优势。通过像您这样的方式,您serialize()甚至可以在文件中使用更好的解码和存储数据性能。将 SQL 与此类结构一起使用并没有什么特别之处。

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

于 2012-07-24T11:25:24.383 回答
0

第一个想法:这显然会破坏 sql WHERE label='Homepage' 第二个中的精确搜索:用户在搜索时将能够看到不需要的结果(例如,当他的查询在其他语言字符串中找到时)

于 2012-07-24T11:20:29.477 回答
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 等。

于 2012-07-25T08:23:51.407 回答