虽然这个问题可能是similar https://stackoverflow.com/questions/929410/what-are-best-practices-for-multi-language-database-design to https://stackoverflow.com/questions/316780/schema-for-a-multilanguage-database many https://stackoverflow.com/questions/1980214/how-to-support-multi-languages-approach-in-database-schema/ others https://stackoverflow.com/questions/9960241/i18n-using-database,我想就 i18n 的最佳方法(特别是 FuelPHP)征求意见/建议。
所以,这是我到目前为止所得到的:
数据库模式#1:
models (id, name_pt, name_es, name_en, description_pt, description_es, description_en)
样本数据#1:
(1, 'Modelo', 'Modelo', 'Model', 'Descrição do modelo', 'Descripción del modelo', 'Model description')
Pros:
- 直接又简单
- 每个型号一张表
- 无需使用 JOIN
- 使用魔术方法来简化数据访问:
public function & __get($property)
{
if (array_key_exists($property, array('name', 'description')))
{
$property = $property.'_'.Session::get('lang_code');
}
return parent::__get($property);
}
这样,我就可以拨打电话:
$model->name;
$model->description;
代替:
$model->{'name_'.Session::get('lang_code')};
$model->{'description_'.Session::get('lang_code')};
Cons:
- 有很多语言/翻译字段可能会变得混乱。
- 添加新语言意味着向表中添加新字段
- 这个魔术方法只有在我们已经有一个 ORM 实例/对象时才有效。通过以下方式获取 ORM 实例查询生成器 http://fuelphp.com/dev-docs/packages/orm/relations/intro.html按翻译字段排序,它仍然需要如下代码:
Model_Model::query()
->order_by('name_'.Session::get('lang_code'))
->get();
数据库模式#2:
languages (id, code, name)
models (id)
i18n_models (id, model_id, language_id, name, description)
样本数据#2:
-- languages
(1, 'pt', 'Português')
(2, 'es', 'Español')
(3, 'en', 'English')
-- models
(1)
-- i18n_models
(1, 1, 1, 'Modelo', 'Descrição do modelo')
(2, 1, 2, 'Modelo', 'Descripción del modelo')
(3, 1, 3, 'Model', 'Model description')
Pros:
- 更好的数据组织
- 添加新语言轻而易举
- 与第一种方法一样,我们也可以使用set() http://fuelphp.com/dev-docs/packages/orm/crud.html填充 $_custom_data 数组的方法:
$i18n = Model_I18n_Model::query()
->where('model_id', $model->id)
->where('language_id', Session::get('lang_code'))
->get_one();
$model->set(array(
'name' => $i18n->name,
'description' => $i18n->description
));
Cons:
- 复杂性增加
- 必须使用 JOIN 或第二个查询
- 每个型号都需要一个额外的表
数据库模式#3:
在其他问题上,我看到人们建议对所有翻译使用中央 i18n 表,为模型的每个翻译使用一行。
Pros:
- i18n 在模型之间共享的单个表
- 添加新语言应该像以前的方法一样容易
Cons:
- 获取数据时复杂性会增加,需要为模型的每个翻译文本进行 JOIN
- 我们可以尝试使用EAV集装箱 http://fuelphp.com/dev-docs/packages/orm/eav.html使用这种方法,虽然使用键/值进行映射,但在这种情况下,我们还必须使用 language_id 来获取正确的翻译。
就我个人而言,我更喜欢第二种方法。您还看到哪些其他优点/缺点?有人在 FuelPHP 上以不同的方式实现了 i18n 吗?分享你的想法:)