如何在关系数据库中建模多语言实体

dzh*_*zhu 5 multilingual database-design relational-database

如果我们要开发一个多语言应用程序,我们应该将翻译存储在资源文件还是数据库中?

假设我们选择在数据库中进行。是否有一种标准方法可以在关系模型中对多语言实体进行建模?

1. 一张大翻译表

我们可以将所有翻译存储在一张表中,并使用与语言无关的键作为属性值。

人员(SSN、名字、姓氏、生日)

翻译(关键懒惰、翻译)

2. 每个实体一个翻译表

人物(SSN、生日)

PersonML(SSNLangId、名字、姓氏)

我更喜欢这种方法。确实是1:N的关系

问题

看来多语言列不能用于形成主键
假设每个人都有一个唯一的名字,那么 (FirstName, LastName) 可以用作主键。

人(名字姓氏、生日)

然而,当考虑到多语言时,(FirstName, LastName) 无法识别一个人。
显然我们不能添加 LangId 来形成主键。

人(LangId名字姓氏、生日)

在这种情况下,一个人将存储在多行中,并且非键列将被重复。

我们是否必须使用与语言无关的列作为主键?
当没有这样的列时,我们应该使用代理吗?
有人告诉我不应盲目使用代孕妈妈,我非常同意。


更新1

在示例中,我假设FirstNameLastName需要进行本地化。

如果每个实体总是有一些属性,例如 SSN,则第二种方法更有意义。
但是,如果某些有效主键包含需要本地化的列,则它们可能会变得无效。

另一个例子

每个公司都有一个唯一的名称,因此 CompanyName 可以用作主键。

公司(公司名称,...)

当涉及到本地化时,公司名称不能用作主键。我们必须发明一些代码来代表公司。

这是否意味着本地化不适合关系模型?


更新2

3. 默认语言与其他语言的1:N关系

用户可能会将公司表视为:

公司(公司名称英语、公司名称法语、公司名称西班牙语、...)

当然有重复的组,所以它打破了1NF。

改进:

公司(公司名称英文,...)

公司名称ML(公司名称英语LangId、公司名称)

问题是我们必须提供默认(英文)名称,即使用户不需要。
一些用户可能提供英文名称,其他用户可能仅提供法文名称。
这个要求是不是太做作了?

4. DBMS 本地化支持

PerformanceDBA在他的评论中提到了这一点。
我会对此做更多研究。

Zoh*_*led 1

“有人告诉我,不应盲目使用代孕妈妈,我强烈同意。”
我也同意,盲目使用任何东西都不是明智的选择。

但是,并非每次使用代理键时都是盲目完成的。请记住,主键并不是确保唯一性的唯一方法。大多数(如果不是全部)关系数据库都提供唯一约束和唯一索引,应该明智地使用它。事实上,当在翻译表中存储多语言数据时,使用代理键可能比使用自然键更好。阅读这篇文章,了解自然键策略和代理键策略之间的良好比较。

为了回答您的问题,我将为每个实体提供一个翻译表,仅在主实体表中保留实体非文本数据(例如您的示例中的出生日期和性别),并将文本数据保留在翻译中表,其主键由语言 id 和实体表主键组成。
请注意,在这种情况下,实体表的主键必须是非文本的,并且不依赖于语言。

  • 我不会推荐 Ambler 或他的建议,它充满了错误,并且对 *RM* 无知。不存在“替代或自然”的争论或辩论。他的建议的结果是不相关的。使用它会降低你答案的可信度。 (2认同)