1

我们想扩展我们的数据库以创建多语言支持,但我们不确定如何做到这一点。我们的数据库如下所示:

ID——名称——描述——(很多不相关的列)

选项 1 是在表中添加一个 xml 列,在该列中我们可以存储我们需要的信息,如下所示:

<translation>
    <language value=’en’&gt;
        <Name value=’’&gt;
        <Description value=’’&gt;
    </language>
    <language value=’fr’&gt;
        <Name value=’’&gt;
        <Description value=’’&gt;
    </language>
</translation>

诀窍和优点是当我删除行时,我也删除了翻译。

选项2是添加一个额外的表,创建一个表来存储信息很容易,但是在获取信息时需要内部连接,并且在删除原始行时需要更努力地删除行。

在这种情况下,首选方案是什么?或者还有其他好的解决方案吗?

4

1 回答 1

3

我建议使用“关系”方法,即单独的翻译表。考虑这样做:

在此处输入图像描述

这个模型有一些很好的属性:

  • 对于每个多语言表,创建一个单独的翻译表。这样,您可以使用适合该特定表的字段,并且翻译不会“错误连接”到错误的表。
  • 与 XML 不同,LANGUAGE 表和相关联的 FOREIGN KEY 的存在确保了不存在语言的翻译不能存在。
  • 与 XML 不同, ON DELETE CASCADE引用操作将确保在删除语言时不会留下“孤立”翻译。
  • 虽然 XML 在更简单的情况下可能更快,但我怀疑 JOIN 在语言数量增加时更具可扩展性。1无论如何,测量差异并自行决定它是否足够显着。
  • NAME 和DESCRIPTION 等单独的字段可能更容易索引。对于 XML,您可能需要一个对 XML 有特殊支持的 DBMS,或者可能需要某种全文索引。
  • NAME 和DESCRIPTION 等字段可能只是常规的VARCHAR。OTOH,将它们放在一起可能会产生对于常规 VARCHAR 而言太大的 XML,从而迫使您使用 CLOB/BLOB,这可能有其自身的性能问题。
  • 如果您的 DBMS 支持集群(见下文),则整个转换表可以存储在单个 B-Tree 中。XML 有很多冗余数据(开始和结束标记),可能使它比 B-Tree 更大且对缓存不太友好(即使我们计算所有相关的开销)。

您会注意到,上面的模型使用识别关系和生成的 PK: {LANGUAGE_ID, TABLEx_ID} 可用于聚类(因此属于同一语言的翻译在物理上紧密地存储在数据库中)。只要您的主要(或“热”)语言很少,这应该没问题 - 缓存是在数据库页面级别完成的,因此避免在同一页面中混合“热”和“冷”数据可以避免缓存“冷”数据(并使缓存“更小”)。

OTOH,如果您经常需要查询多种语言,请考虑将聚类键顺序翻转为:{TABLEx_ID, LANGUAGE_ID},以便同一行的所有翻译在物理上紧密地存储在数据库中。一旦您检索到一个翻译,同一行的其他翻译可能已经被缓存。或者,如果您想在单个查询中提取多个翻译,您可以使用更少的 I/O 来完成。


1我们可以只加入所需语言的翻译。对于 XML,您必须先加载(并解析)整个 XML,然后再决定只使用与所需语言相关的一小部分。每当您添加新语言(以及与 XML 相关的翻译)时,即使您很少使用新语言,它也会减慢现有行的处理速度。

于 2013-02-12T17:23:02.340 回答