2

数据库设计的“第三范式”要求您删除功能依赖关系。它旨在消除冗余,从表中删除可以从其他字段计算的任何属性(字段)。例如,当您引用另一个实体时,您只存储它的键。您不存储这些引用实体的属性副本,因为这意味着每次更改引用实体时都必须更新它们。

另一种情况是高度等属性。您想知道一个人的身高,但在您的应用程序中,您可能希望以不同的单位了解它:米、英尺、天文单位。但是您不会存储所有这些值,您应该删除计算字段,因此您只保留其中一个(当然是米),并在需要时“即时”计算转换后的值。

您也不存储年龄之类的东西,而是从出生日期计算它们。在这种情况下,年龄随时间变化的事实也起作用。如果你不这样做,你的数据很快就会不正确,除非你不断地更新它。

现在假设您有一个显示每个用户的星座的社交网络。对于每个用户,我们都会显示他或她的星座,这是根据出生日期和时间以及用户选择的占星术传统(例如西方或中国)计算得出的。计算某人的星座是一项非常专业和复杂的计算,但您仍然可以从占星术库中调用并计算。你会如何设计这个数据库,你会删除这个功能相关的属性,或者你会计算一次用户的符号,或者每次她更新她的出生日期,然后将它存储在数据库中并忘记计算登录的可能性你的系统的其余部分,或者你会强制执行“3NF” 用铁腕统治?如果用户坚持认为她的符号应该与您的算法计算的符号不同,那么您如何看待能够调整用户符号的潜在好处?

现在假设一个新的应用程序。你正在为军队建立一个系统,为新的应征者选择可能的职业。你的系统的一部分是一个巨大的模式识别机器,由 ORNL 开发,它会根据来自你数据库的大量数据告诉你允许应征入伍者从事哪些职业。这种模式识别方法会查看每个人的身高、出生日期、医疗记录、学校成绩单,并且还会查看该人对两份问卷之一的一长串答案。它还考虑了上级军官填写的评估问卷,并同时分析每年的所有应征入伍者,得出一堆参数,例如前馈神经网络。这个神经网络比整个模式识别系统更简单,但它仍然是一个相当复杂的计算,而不仅仅是温度单位的转换。然而,你可以把它看作一个“黑匣子”,当你从数据库中提取他的记录时,它可以告诉你每个应征者的命运。

在陆军日历中的特定日期,进行分析,找到 ANN 参数,现在您可以运行黑匣子并告诉每个应征者他将在接下来的一两年内做什么。这是一件非常重要的事情。您将决定人们的职业,您将派一些人在厨房操作烤箱,而另一些人则负责驾驶坦克。每个人都将登录陆军网络查看他们的职业,并在他们的个人网页中查看结果。

现在,小黑盒就在那里,它根据从数据库中提取的属性输出这个重要的值。属性和参数可能永远不会改变,而应征者命运的计算可能永远是正确的,永远是第一天的相同值。但是你真的会把它留在数据库之外,只是为了遵循“删除计算的属性”规则吗?

这不仅仅是年龄、星座或温度转换的一些计算。模式识别系统确实是计算属性的路径。但是你真的想把它永远保存在你的系统中,一遍又一遍地重新计算这个非常重要的事情吗?还是您认为最好计算一次,然后忘记这个神奇的黑匣子的存在?我的意思是,只要有一天运行所有这些疯狂的模式识别代码,然后挑选结果,并将它们记录在数据库中。当有人登录查看他的分析输出时,让查询只是一个无聊的数据获取过程,而将所有的识别“兴奋”留到下一次。

另一个更明显的情况:您经营着像亚马逊这样的网上商店。您有一种模式识别方法可以向人们推荐书籍,该方法来自数据库中的用户记录。你会在需要当前推荐的时候一直运行这个东西,还是将模式识别框视为与系统其余部分分开的东西,只是将其结果提供给其他程序可以读取的数据库?拥有一个控件不是很好吗,例如,以确保您不会在尴尬的时刻切换建议?...不要太担心计算负担,假设有出色的内存和计算资源。

TL;DR -- 你认为删除计算属性的规则永远不应该被打破,还是你会说可以将非常重要的属性的结果存储在数据库中,这些属性是通过非常复杂和精细的模式识别方法计算出来的?是否存在我们应该假装您实际上无法“按需”执行计算的情况,然后将这些结果记录在那里,无论如何都不会更新?

4

1 回答 1

2

蓄意的、司法的非规范化被“允许”用于缓存昂贵计算的结果。转换单位或计算年龄将是可能不应缓存的廉价操作的示例,但您引用的其他示例看起来很合适。

根据 DBMS,您可以使表标准化,并在它们“顶部”实现缓存:

  • 一些 DBMS 支持物化视图- 就像常规 VIEW 但持久化,因此每次查询时都不需要重新计算。
  • 一些支持计算字段(又名计算列)的 DBMS,也支持持久化它们(一个例子是MS SQL Server 下的PERSISTED关键字)。
于 2013-02-02T21:25:50.250 回答