添加信息,xml列还是新表?

时间:2013-02-12 15:04:19

标签: sql database-design

我们希望扩展我们的数据库以创建多语言支持,但我们不确定如何执行此操作。 我们的数据库如下所示:

ID - 名称 - 描述 - (许多不相关的列)

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

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

技巧和优点是,当我删除行时,我也会删除翻译。

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

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

1 个答案:

答案 0 :(得分:3)

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

enter image description here

这个模型有一些不错的属性:

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

您会注意到上面的模型使用identifying relationships并且生成的PK:{LANGUAGE_ID,TABLEx_ID}可用于clustering(因此属于同一语言的翻译在物理上存储关闭在数据库中一起)。只要你有少数主要(或“热门”)语言,这应该没问题 - 缓存是在数据库页面级别完成的,因此避免将“热”和“冷”数据混合在一起页面避免缓存“冷”数据(并使缓存“更小”)。

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


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