我如何令人信服地反对复制数据库列?


47

我已经开始在一个新组织中工作,我在数据库中看到的一种模式是复制字段,以使业务分析师更容易编写查询。我们正在使用Django及其ORM。

在一种情况下,我们保留一个MedicalRecordNumber对象,该对象带有在特定上下文中标识患者的唯一字符串。我们有登记其追踪病人和有关联的对象MedicalRecordNumbers,但不是使用外键关系,他们复制的字符串,使他们能够避免写一个连接(不是由于性能原因)。这种模式在整个数据库中很常见。

对我来说,干净的数据模型的重要性只是为了让我能好好考虑一下。不必要的复杂性浪费了我有限的认知处理时间。这是一个系统的问题。编写连接不舒服是一个可纠正的技能问题。我不一定要提倡返回并更改模式,但我希望能够令人信服地阐明此类重复问题。


2
“不习惯编写连接”是什么意思?他们如何解释呢?
scriptin

9
这些人为您工作吗?你是他们的主管吗?您可以在这里找到大多数理由:en.wikipedia.org/wiki/Database_normalization。是的,他们需要更好地使用联接。
罗伯特·哈维

1
您是否查阅了有关为什么需要标准化的文献?
内森·塔吉

17
不会添加在内部进行联接的视图使编写查询一样容易吗?您可以建议使用它们作为替代。
CodesInChaos

1
您是否与同龄人和年长者(礼貌地)进行了交流?他们的理由是什么,他们在考虑什么?有许多可能的理由说明为什么这可能是一个好主意(即使您说“性能不是原因”,但您必须凭什么证据来支持这一点?)。在指责他们过于懒惰和/或僵化之前,您是否考虑过(并询问)他们按原样进行设计的原因?也许读比写多得多(分析密集型数据库)?变更追踪?历史数据?问大家-有人可能知道真正的原因。
a安2015年

Answers:


128

您的运营数据库应高度规范化,以减少异常情况

您的分析数据库(仓库)应高度非规范化,以简化分析。

如果没有单独的分析数据库,则应制作一些高度非规范化的[物化]视图。

如果您告诉您的高级业务分析师/经理进行大量联接以进行简单分析,那么您可能会被解雇。

敏捷数据仓库设计是一本好书

在这里查看我的快速n'n脏数据仓库提示


9
这是正确的方法。
Nit

6
+1这恰恰是View的目的:允许在规范化的数据库上进行非规范化的视图。
Nzall 2015年

4
绝对正确,但是我认为应该更多地强调“减少异常”,因为这是该问题的主要答案。您会在数据复制/非规范化中看到的最常见(唯一?)异常是,列将以某种方式同时填充有矛盾的数据,从而使您无法知道真实数据应该是什么,并且没有确定出问题的方法。可以通过大量跟踪更改来减轻后者的负担,但这不会便宜也不容易快速找到问题所在。更具成本效益,可以完全避免问题。
jpmc26 2015年

2
另一个需要考虑的角度是,即使假设开发人员能够保持数据正确(可疑),也将极大地消耗其资源,以确保在需要维护一致性时更新每个重复字段。
Nate CK

1
@Panzercrisis事务“隐式”的唯一方法是在查询末尾运行自动提交。生产数据库通常不会出现这种情况。在应用程序中,事务应自动启动,并且提交应与查询分开进行。这是对应用程序的一笔前期投资,但是它简化了涉及添加数据库调用的代码更改,并减少了开发人员必须考虑的事情(提高了开发速度,减少了开发错误)。这种设计也非常适合连接池之类的事情。
jpmc26 2015年

57

我了解,为什么有人希望避免为每个选择编写联接。

但是你可以创建一次与加入并使用它,而不是你的非标准化表的视图。

因此,您将归一化的优势与轻松选择的便利相结合。


12
视图是您的朋友。大量使用它们。为了提高性能,如果您的RDBMS支持,甚至可以使用实例化视图
VH-NZZ 2015年

13

已经被广泛支持的答案涵盖了“如何避免重复”(使用视图),但没有给出原因。他们基本上表明,重复列是使编写查询变得更容易的问题的错误解决方案。但是,问题“为什么不仅仅为它的重复而复制任何随机列?” 仍然站立。

答案是“因为墨菲定律”。墨菲定律指出:

如果出了什么问题,那就可以了。

在这种情况下,假定重复列的每个行字段的内容与原始列的每个对应行字段的内容相同。可能出问题的是,某些行字段的内容可能与原始内容不同,从而造成了严重破坏。您可能会认为您已采取所有可能的预防措施以确保它们不会有所不同,但是墨菲定律指出,由于它们可以有所不同,因此它们也会有所不同。和破坏随之而来。

作为这种情况发生的一个示例,只需考虑以下事实:重复的列不会被魔术填充;有人必须实际编写每当在原始表中创建行时就在其中存储值的代码,而有人必须编写每当修改原始表时就不断更新它们的代码。撇开这样一个事实,即这会给将数据输入数据库的代码增加不必要的负担(并且从定义上讲,它比仅查询数据库的任何代码都更为重要),在某些情况下某个地方的某人可能会忘记进行此重复。然后,值将不同。或者他们可能记得执行重复操作,但不是在事务内进行,因此在某些罕见的故障情况下,可以将其省略。但是我真的不需要浪费时间写这些例子,如果会出错,它将。


12

从权衡而不是好/坏的角度考虑它会更有成效。他们在权衡归一化(尤其是一致性)的优势以换取查询可用性方面的优势。

在一种极端情况下,如果数据严重不一致,数据库将变得无用。在另一种极端情况下,如果对于每天需要查询数据库以获取他们可以依靠的结果的人来说太困难了,那么数据库将毫无用处。

您如何做才能降低风险和成本?

  • 构建一致性检查器工具并定期运行。
  • 通过一致地更新复制数据的软件来路由写访问。
  • 添加视图或构建自动执行联接的查询工具,以便业务人员可以根据信息而不是数据库内部进行思考。

6

我认为,对业务分析师进行数据标准化的最有力依据是,它可以促进数据完整性。如果您的关键数据仅存储在一个地方(一张表中的一列),那么由于错误的更新而损坏数据的可能性就很小。我认为他们可能会关心数据完整性的重要性,因此这可能是说服他们更新与数据库交互方式的好方法。

一种稍微更困难的查询方法可能比潜在的数据损坏更可取。


6
他的员工将争辩说,他们足够优秀,可以确保正确更新所有数据(如果对联接不满意,这是我的前提条件)。也许更好的说法是,如果避免标准化,则会失去RDBMS提供的ACID的大部分好处。
罗伯特·哈维

4
可能吧,但这全都是风险问题。他们是否愿意接受由于使查询更容易而损坏数据库的风险?
Oleksi 2015年

1
在这里扮演魔鬼的拥护者,一个明显的反驳是,如果有人无论如何都要破坏更新和破坏数据,那么无论是否进行规范化都是一个问题-至少,数据库中有一些冗余使其更有可能有人会注意到该损坏,甚至以后可以修复它。(当然,临时非正规化几乎不是最可靠的错误检测方案,但是通过冗余进行错误检查的原理是合理的:这就是复式簿记的工作原理。)
Ilmari Karonen 2015年

或者,换句话说,数据完整性不仅仅是关系完整性。使用完全规范化的数据库,即使有人弄乱了更新,您仍然可以保持完美的关系完整性,但这不会使错误更新的数据减少任何浪费。
Ilmari Karonen 2015年

0

补充以上其他人的建议。这是一个数据治理问题。您需要与相关的利益相关者合作:数据架构师和数据管理员来制定数据原理,策略和命名约定。

要有耐心,有条理地工作。改变不会在一夜之间发生。


0

放弃。

老实说,您可以花费数月的时间讨论标准化,一致性和与因懒惰而导致的疯狂bug战斗,然后退出。

或者,您可以只节省时间,而沮丧并立即退出。

好的程序员是非常懒惰的人。他们了解客户和管理需求。但最重要的,他们明白,解决问题的好,用精心设计的,并且执行情况良好的解决方案节省了他们的个人巨大的数额,努力,而且最重要的痛苦和压力。

因此,在一个了解并重视良好工程的地方工作会更好。

祝好运。


事后思考:也许他们需要的是BI / OLAP工具... http://en.wikipedia.org/wiki/Online_analytical_processing

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.