更新:几年后我遇到了这个问题:现在我知道这是一个非常糟糕的方法。请不要使用这个。您始终可以为 i18n 使用额外的表(例如 products
和 products_lang
),每个区域设置都有单独的条目:更好地用于索引,更好地用于搜索等。
我正在尝试在 MySQL/PHP 站点中实现 i18n。
我读过一些回答说“i18n 通常不是数据库的一部分”,我认为这是一种有点狭隘的方法。 命名的产品,或者像我的例子一样,存储在数据库中的菜单结构和内容怎么样?
我想知道您如何看待我的方法,考虑到语言应该是可扩展的,所以我试图避免“每种语言解决方案一栏”。
一种解决方案是对要翻译的字符串使用引用 (id),并且每个可翻译列都有一个包含主键、字符串 ID、语言 ID 和翻译的表。
我想到的另一个解决方案是使用 JSON。所以我的数据库中的菜单条目看起来像:
idmenu label
------ -------------------------------------------
5 {"en":"Homepage", "it":"pagina principale"}
您如何看待这种方法?
最佳答案
“一种解决方案是对要翻译的字符串使用引用 (id),并且每个可翻译的列都有一个包含主键、字符串 ID、语言 ID 和翻译的表。”
我实现过一次,我所做的是采用现有的数据库模式,查找所有具有可翻译文本列的表,并为每个这样的表创建一个单独的表,仅包含那些文本列,以及一个额外的语言 ID 和id 将其绑定(bind)到原始表中的“数据”行。所以如果我有:
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 的想法存在一个问题,即几乎不可能对其进行查询,这反过来意味着无法在特定时间仅提取您需要的翻译。
关于php - MySQL 数据库 I18N,一种 JSON 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11629728/