1

我们有一个数据库表,我将其称为 TIMES。它传统上看起来像这样:

ID    Blah1 Blah2 Blah3  Description
1     a     b     c      Day
2     d     e     f      Night

(我添加了 Blah 列主要是为了表明表中存在更多列,但与我们尝试进行的升级没有直接关系。)

我们想为从 db 获得的结果添加一些语言支持。所以我的建议是:

a) 走懒惰的路,只为语言添加一个新列,给我们

ID    Blah1 Blah2 Blah3  Description  Language
1     a     b     c      Day          English
2     d     e     f      Night        English
1     a     b     c      Tag          German
2     d     e     f      Nacht        German

或者,最好是 b) 进行一些规范化并创建一个仅包含相关值的新表:

ID      Description  Language
1       Day          English
2       Night        English
1       Tag          German
2       Nacht        German

我们的数据库人员说,好吧,我们可以只使用原始表并将所有内容都包含在 xml 中……这样我们就可以节省行数。

ID        Blah1 Blah2 Blah3  Language
1         a     b     c      <TimeDescriptions>
                                 <TimeDescription language='English'>
                                     Day
                                 </TimeDesciption>
                                 <TimeDescription language='German'>
                                     Tag
                                 </TimeDesciption>
                             </TimeDescriptions>        
2         d     e     f      <TimeDescriptions>
                                 <TimeDescription language='English'>
                                     Night
                                 </TimeDesciption>
                                 <TimeDescription language='German'>
                                     Nacht
                                 </TimeDesciption>
                             </TimeDescriptions> 

“节省行数”?我不是一个真正的数据库人,但这对我来说听起来很奇怪。当然,它会节省一些行......但是当行本身更长时,这是一个整体的胜利吗?(很有可能)除此之外,它似乎打破了我习惯的规范化规则。我也知道可以在 SQL 中使用 XML 并对其进行搜索(尽管我没有这样做,并且对细节非常模糊),但我只是看不到这样做的胜利。

当我问起这件事时,他开始变得棘手,所以我退缩了,但我仍然想知道我是否遗漏了什么。显然很多细节都丢失了,但我不是在寻找详细的分析......我只是想知道这是否合理。

编辑:啊。你会认为我在这里待的时间足够长,已经学会了正确的格式,但我把最后一点搞砸了……我会尝试修复它,但欢迎进行其他编辑。

4

1 回答 1

2

当然,它会节省一些行......但是当行本身更长时,这是一个整体的胜利吗?

可能。但这意味着页面中的行数更少,这通常意味着更多的磁盘访问和更多的磁盘 I/O。这些行现在看起来还不错,但是如果您支持十几种语言,那么仅针对 XML 数据,您可能会看到每行 1Kb。我粗略计算的经验法则是每页使用 8Kb(有时可以调整,具体取决于您的 dbms),因此每页只有 8 行。

此外,这意味着使用 like 子句查询行WHERE Description = 'Day'要困难得多。(不过,这在您的应用程序中可能无关紧要。)此外,使用现有结构,如果需要,您可以在“语言”上对表进行分区。

向原始表添加新列似乎会引入多值依赖关系,这将违反 4NF。(Language->>Description) 但是如果你可以将它建模为一个复合属性,你就可以消除这种依赖关系。

复合属性:复合属性是具有内部结构的属性,dbms a) 完全忽略或 b) 提供函数和运算符,以便用户可以操作片段。最常见的示例是“日期”类型的列。日期具有内部结构——年、月、日。它们具有内部多值依赖关系。但是 dbms 提供了函数和运算符,以便在您需要时获取它们。

您的 dbms 可能会使用Compoundcompositeuser-definedtypecolumnattribute等词的某种组合来描述此功能。

如果您的 dbms 支持用户定义的类型,您可能能够为特定于语言环境的单词创建一个类型,并在表中使用它。

但无论如何,这不应该是一个意见问题。您应该能够在一个下午或一天内测试带有代理键的 5NF 方法、不带代理键的 5NF、带有复合类型或用户定义类型的 5NF 以及 XML。然后再花一个下午确保您的索引和查询做得很好,这样性能差异不仅仅是由于错误、匆忙或无知造成的。

最后,权衡最佳表现者与维护成本。(并用这些新获得的技能更新你的简历。)

于 2013-01-14T12:19:04.870 回答