本教程说:
对于反规范化的支持者来说,这样的想法如下:当您朝着更高的正常形式前进时,规范化会创建更多的表,但是更多的表意味着在检索数据时会有更多的连接,这反过来会减缓查询的速度。因此,为了提高某些查询的性能,可以覆盖数据完整性的优点,并将数据结构返回到较低的范式。
为什么在使用非正态化时不可能实现数据完整性?我的意思是,DBMS不会确保在更新数据时,所有冗余的数据副本都会自动更新吗?
例如,在Oracle中,反规范化是使用物化视图实现的,当原始表被修改时,物化视图中的数据将被自动修改(您也可以选择不自动修改数据)。而且,即使您不使用物化视图(例如,DBMS不支持它)并手动实现去规范化,您仍然可以自己编写触发器来保持数据的一致性(因此,使用去正化并不一定意味着不可能实现数据完整性)。
发布于 2019-01-28 12:27:04
数据完整性在规范化和非规范化数据库中都是可能的。这两种情况的不同之处在于应用程序向数据库写入不良数据的不同方式的数量。
让我们以一个简单的坏数据为例。在数据库中,它说id 123的雇员姓"Brown“。但在现实世界中,123员工的姓氏是"Browne“。不管你怎么看,这都是糟糕的数据。但让我们再深入一点。
在一个数据库中,一个规范化的数据库中,姓氏准确地存储在一个位置,在Employees表中。不是对就是错。而且,如果是错误的,则由知道正确答案的人来修复数据库中的数据。这是数据管理的一部分,虽然对我们中从事自动化工作的人来说不是一个非常令人兴奋的部分。
在另一个非规范化数据库中,employee 123的姓氏存储在两个表中,即Employees表和Contact表。联系人表是关于电话号码和地址的。在规范化数据库中,没有联系人表。相反,这是一种看法。现在,有更多的可能性。姓氏可能在两个地方都是正确的,或者在两个地方都可能是错误的。但还有另一种失败模式。它可能在一个地方是对的,但在另一个地方可能是错误的。现在的数据库不仅错了,而且自相矛盾。这在规范化数据库中是不可能的,因为姓氏只存储一次。
这就是所谓的有害冗余的一个例子。第二范式到第五范式是关于消除有害冗余的情况,通过强制规则使一个事实被存储在一个地方。这并不能保证数据的完整性,但至少可以避免数据的不一致性。您仍然需要管理数据才能正常运行,但是现在DBMS正在帮助您正确地管理数据。
表演完全是另一回事。在某些类型的通信中,其中一个数据库的性能可能优于另一个数据库。甚至有可能其中一个数据库更适合更新,而另一个则更适合查询。但出色的表现和错误的答案在某些情况下可能是灾难性的,而在其他情况下则是可以接受的。
在我给出的示例中,错误数据的检测非常简单,即使有些繁琐。在现实世界中,有些例子是错误的数据检测几乎是不可能的,除非您从DBMS那里得到所有的帮助。正常化可以在这方面有所帮助。
那么,为什么不确保所有的应用程序代码都做正确的事情呢?首先,随着任务范围的扩大,应用程序代码的数量急剧增加。第二,数据错误可能是通过使用交互式SQL (可能是通过DBA )出现的。编写防御性应用程序代码是一件好事,但出于某种原因,它可能无法完成。
抱歉,时间太长了,但我得告诉你到底怎么回事。数据管理是一场永无止境的战斗。寻找和清理错误的数据只是这场战斗的一部分。这是一项肮脏的工作,但总得有人去做。一个好的DBMS,再加上规范化可以帮助您。
发布于 2019-01-28 11:28:04
在关系系统中声明性数据完整性有几个方面。
一个方面是可空性。假设有一个具有null列的规范化表。该表位于外部联接中的右侧,其中有不匹配的行。现在,对于某些行中的非空列,非规范化结果必须显示为null。
宣布的独特性可能会受到影响。规范化表可能具有唯一的约束。如果该表位于一对多或多对多连接的“多”侧,则无法保证连接唯一性。
这对外键有一个流动影响。正如文档所说
引用的列必须是主键或唯一索引。
如果取消规范化意味着引用的列(S)不是唯一的,则无法定义外键。
正如您所评论的,没有什么可以阻止您将所有这些签入到触发器或应用程序的其他层。然而,这将是一种维护开销。声明引用完整性的喜悦认为,一条简单的语句可以确保所有数据都是可靠的,无论其来源还是历史。
https://dba.stackexchange.com/questions/228166
复制相似问题