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

5
如果我们要开发一个多语言应用程序,我们应该将翻译存储在资源文件还是数据库中?
假设我们选择在数据库中进行。在关系模型中建模多语言实体是否有标准方法?
1. 一个大的翻译表
我们可以将所有翻译存储在一个表中,并使用语言中立键作为属性值。
Person (SSN, FirstName, LastName, Birthday)
Translation (key, langid, translation)
2. 每个实体一个翻译表
Person (SSN, Birthday)
PersonML (SSN, LangId, FirstName, LastName)
我更喜欢这种方法。它真的是一个1:N关系
问题
似乎无法使用多语言列来形成主键
假设每个人都有一个唯一的名字,那么(FirstName, LastName)可以用作主键。

人员(名字姓氏,出生日期)

但是,考虑到多语言的情况,(名字,姓氏)无法唯一确定一个人。
显然我们不能添加LangId来形成主键。

人员(LangId名字姓氏,出生日期)

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

我们是否必须使用语言中立列作为主键?
当没有这样的列时,我们应该使用代理吗?
我被告知盲目使用代理是不可取的,我强烈同意。


更新 1

在这个例子中,我假设名字姓氏需要本地化。

如果每个实体都有像 SSN 这样的属性,第二种方法更合理。
然而,如果它们包含需要本地化的列,则某些有效的主键可能会变为无效。

另一个例子

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

Company (CompanyName, ...)

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

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


更新2

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

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

Company(CompanyNameEnglish,CompanyNameFrench,CompanyNameSpanish,...)

当然,有重复的组,因此它违反了1NF。

改进后:

Company(CompanyNameEnglish,...)

CompanyNameML(CompanyNameEnglishLangId,CompanyName)

问题是,即使用户不需要默认(英文)名称,我们也必须提供一个默认的英文名称。
一些用户可能提供英文名称,而另一些用户可能仅提供法文名称。
这个要求是否太牵强?

4. DBMS本地化支持

PerformanceDBA在他的评论中提到了这个问题。
我会进行更多的研究。


可能是数据库存储值的全球化的重复问题。 - Zohar Peled
从你的例子中完全不清楚你的数据模型中哪些内容需要翻译。相反,它更像是一个“什么是好的主键”的问题。请编辑你的帖子,提供关于你的数据模型和需要本地化的列的具体信息。 - Ondrej Tucny
@ZoharPeled。你是对的。在这种情况下,SSN是更自然的主键 - 这是一个糟糕的例子。 - dzhu
1
(a) 如果你想要一个关系型数据库,就不能“发明代码”,键必须从数据中“组成” (b) 本地化与RM无关,这是实现的问题。使用SQL平台,本地化现在是标准的 (c) 如果你有本地化“问题”,那是因为你没有商业服务器。你为NONsql编写的任何代码都是不可移植的,当你得到一个[i]时,你将不得不替换它 (d) 把所有东西都存储在数据库中 (e) 我不确定你是否真正理解我的答案,你仍然在问如何打破规则。 - PerformanceDBA
1
(e) LangId是Person的属性,不一定是关系键的一部分,它与Person PK是1::1的关系。如果您没有真正的SQL平台,那么您可能需要在每个代码段中处理本地化,然后贯穿始终地携带LangId,当然,您可以将其作为PK的一部分,但这是不正确的。(f) 如果(SSN)或(LastName,FirstName)是唯一的,则加上任何内容也是唯一的。添加是多余的。 - PerformanceDBA
显示剩余8条评论
2个回答

1

"有人告诉我代理键不应该盲目使用,我非常同意。"
我也同意,盲目使用任何东西都不是一个明智的选择。

然而,不是每次使用代理键都是盲目的。请记住,主键并不是确保唯一性的唯一方法。大多数关系型数据库都提供了唯一约束和唯一索引,应该明智地使用它们。事实上,在翻译表中存储多语言数据时,使用代理键可能比使用自然键更好。 阅读这篇文章以获取自然键和代理键策略的良好比较。

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


1
“主键不是确保唯一性的唯一方法”这句话可能让您感到困惑。请问能否澄清这个说法,并且提供一个例子。在关系模型中,要求使用数据来构建键,这当然是提供行唯一性的唯一方法。您可能会将代理键分配为“主键”,但这并不能提供行唯一性,结果就是一个没有完整性的记录存储系统,特别是缺乏关系完整性(与引用完整性不同)。 - PerformanceDBA
2
我不建议使用Ambler或他的建议,因为它充满错误,并且对RM一无所知。没有“代理人或自然”的争论或辩论。他的建议的结果是非关系型的。使用它会降低您答案的可信度。 - PerformanceDBA
1
(a) 阅读没有问题,似乎这句话和我上次读到的一样。(b) 你认为什么并不重要;或者我认为什么也不重要;或者你是否同意我的观点也不重要。重要的是E.F.Codd博士在“关系模型”中写道,必须从数据中制作出一个键。如果你没有它们,你就没有(i)关系键或(ii)关系数据库。(c) 你提供的链接是Scott Ambler撰写的页面。他以传播“为了性能而去规范化”的神话而闻名,持续了几十年,然后转向规范化,用于敏捷开发,并且无法... - PerformanceDBA
1
...表述他的变化。该页面充满了错误、半真半假和歪曲事实的内容。安布勒以其对所提出问题的肤浅理解而闻名。福勒也是如此。(d) 代理键与自然键并不是非此即彼的选择。请阅读代理键维基百科,它是半正确的,而正确的一半证明了它的正确性。(e) 你关于“与数据库一起工作”的陈述,结合你的其他陈述,意味着它们不是关系型数据库。因此,你不会知道你错过了什么,所以你对此的看法是... - PerformanceDBA
1
我已在我的评论中回答了dzhu的问题。代理开一个关于代理的新问题,发布“优点”和缺点,我会回答它。 - PerformanceDBA
显示剩余2条评论

0

你的问题不成立:如果你决定将翻译存储在"资源文件"中,那么这组资源文件就是数据库(或其一部分)。

更相关的问题需要回答,例如:谁是翻译的所有者(即翻译是否是软件包的完整部分,最终用户是否可以自定义它们)?这些问题的答案将决定你的翻译是否可以作为随二进制文件一起发货的资源文件。

我没有给出真正的答案,因为唯一了解决定性因素的人是你。我只是指出了需要回答的更深入的问题,这将使它变得清晰明了。


1
我承认这个问题的无关紧要。关于“那组资源文件就是数据库”的观点很有道理。我也对使用配置文件或将配置存储在数据库中感到困惑。总的来说,文件就是数据库。鉴于关系型数据库提供了访问路径独立性,我更喜欢使用数据库方法。在我正在开发的产品中,有数百个配置文件。与它们一起工作很麻烦。 - dzhu
我知道那种感觉。但是 SQL 实在太过受限,以至于使用“真正”的 DBMS 管理的数据库也往往同样麻烦。 - Erwin Smout
1
@dzhu。明确一点,关系型数据库管理系统并不会提供访问路径独立性或RDB,这是你在通过关系模型学习后实现的,然后你使用RDBMS来实现该方法。SQL并非“残缺不全”。当然,如果你实现了一个非关系型数据库,即记录文件系统,导航当然是残缺不全的,但这不是SQL的问题。此外,有些人只是不知道如何使用它。 - PerformanceDBA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接