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

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

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

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

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 并对其进行搜索(尽管我还没有这样做,并且对细节非常模糊),但我只是看不到这样做的好处。

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

编辑:啊。您可能会认为我在这里已经足够长的时间学会了正确格式化,但我不知何故弄乱了最后一点……我会尝试修复它,但欢迎进行其他编辑。

请您参考如下方法:

Sure, it will save some rows...but is that a win overall, when the rows themselves are much longer?

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

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

向原始表中添加新列似乎 引入了多值依赖关系,这将违反 4NF。 (语言->>描述)但是如果您可以将其建模为复合属性,则可以消除这种依赖性。

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

您的 dbms 可能会使用复合、复合、用户定义、类型、 列和属性来描述此功能。

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

但无论如何,这不应该是见仁见智的事情。您应该能够在一个下午或一天内测试具有代理键的 5NF 方法、没有代理键的 5NF、具有复合或用户定义类型的 5NF 以及 XML。然后再花一个下午的时间确保索引和查询工作顺利进行,这样性能差异就不仅仅是由于错误、匆忙或无知造成的。

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


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!