Piotr Kononow是一位业务分析师、软件架构师和项目经理,他拥有15年以上编程经验和背景(SQL,java,C++…)。他的专长是数据仓库/ BI和商业应用,这是他的一篇文章:
最近我和几位DBA和架构师争论,他们对一些数据库没有外键感到震惊,并声称这是一种设计缺陷,是不应该发生的。如果发生必须马上改正。我想与他们争辩。我的经验告诉我,很多数据库(大多数我曾经使用的)不包含外键时并不总是一件坏事。在这篇文章中,我想把重点放在为什么的原因上。
为什么这是一个问题?
1. 潜在的数据完整性问题,
缺少外键明显问题是数据库不能强制进行引用完整性检查,如果在高一层没有正确处理,则可能会导致数据不一致(子行没有相应父行)。
2. 表格关系不清晰
数据库中缺少外键的另一个不太明显的负面影响是,不了解该模式的人很难找到正确的表并找出表关系。这可能会导致严重的数据库查询和报告问题。
为什么数据库可以没有外键?
让我们来看看数据库可以没有外键的原因。首先一个简短的免责声明(因为文章引发了一些关于LinkedIn群体的争议):
下面的理由绝不鼓励不要在数据库中使用外键约束。这仅仅是我在各种渠道(主要是互联网论坛)都能找到的许多开发人员、架构师为什么不使用它们的理由。我个人(和许多其他经验丰富的数据库专家)建议在任何可能的地方使用它们(不会导致更多的问题)。
1. 性能
在表上拥有活动的外键可以提高数据质量,但会影响插入、更新和删除操作的性能。在这些任务之前,数据库需要检查它是否违反数据完整性。这就是为什么一些架构师和DBA完全放弃外键的原因。数据仓库和分析数据库尤其如此,这些数据仓库和分析数据库不以交易方式(一次一行)处理数据,而是批量处理数据。性能是数据仓库和商业智能的一切。
2. 传统数据
许多数据库在设计时需要存储来自旧数据库和遗留数据,这些数据可能对数据质量和完整性没有那么严格。为了能够容纳旧的脏数据,架构师可以选择a)清理和转换遗留数据(昂贵的练习),或者b)放弃在数据库级别上强制执行参照完整性。一些打包的ERP和CRM应用程序也使用这种方法。
3. 全表重新加载
一些数据库,如数据仓库,分段或接口数据库,需要经常从外部重新加载数据。这会导致重新加载时数据不一致(在父表为空的情况下,子表可能已满载)。这可以通过在重新加载时禁用外键来绕过。然而,这引入了额外的逻辑和复杂性以及另一个失败点。如上所述,对性能有负面影响。通常,成本大于收益,开发人员不用担心外键。
4. 更高层次的框架
一些应用程序使用编程框架,在物理数据库之上创建另一个逻辑层。开发人员不使用插入或更新语句来修改数据,而使用API或者框架在后台执行所有操作。ORM(对象关系映射)框架或Ruby on Rails框架就是这种情况。这些工具负责参照完整性,并与RDBMS一起创建更高级别的数据库引擎。这些框架可以自己创建数据库表,而不总是创建外键。使用这些工具的开发人员很少会干扰自动生成的模式,并且不需要外键。
5. 跨数据库关系
这可能不是数据库没有外键的正确理由,一些数据库跨越更多的物理数据库甚至引擎,并且在技术上可能不能创建跨越数据库的它不能在同一台服务器上的两个数据库上创建key。SQL Server就是一个很好的例子 - 它不能在同一台服务器上的两个数据库上创建key。而且这种架构在大型系统中很常见。
6. 数据库平台不可知论者
类似于前一个,一些应用程序被设计为数据库平台(DBMS)不可知的,并能够在Oracle,SQL Server,DB / 2或Sybase等各种数据库上工作。这是我读过的有关PeopleSoft(目前由Oracle拥有)的内容。设计人员不想绑定到任何特定的平台,并将所有逻辑推送到应用程序层,尽可能清楚地离开数据库层。
7. 对更改开放
我与Oracle一直保持紧密联系,我听说过另一个关于其应用程序的故事,这是Oracle自己的产品 - Oracle电子商务套件 - 就是它被设计成尽可能定制。Oracle提供了坚实的基础,使实施团队具有弹性,可以尽可能多地决定设计。至少这是他们所说的。也许这个原因和以前一样,或者是下一个原因:
8. 懒惰的架构师
在创建数据库时,如果要存储数据,则需要创建一些表和列。这是最低限度。但是,您不必创建保持数据一致性的结构,如主键,唯一键,外键或约束。这需要一些努力,但是却没有带来直接的好处。一些架构师和数据库管理员只是忽略了这一部分。
9. 保持模型的秘密
也许这是一个很遥远的问题,但也许有时候是因为人们不希望别人知道太多太容易。一般来说,人们希望被需要和不可替代。一个完美的自我解释的设计可能会使他们过时。但这只是我的理论。