相关疑难解决方法(0)

为什么在数据库中而不是在代码中应用约束?

为什么在数据库中应用约束?放在代码里不是更灵活吗?

我正在阅读一本关于实现数据库的初学者书籍,所以我作为初学者来问这个问题。假设我设计了一个数据库,包括这个实体模型:

 entity type    |   sub-types
----------------+--------------------------------------------
   Person       |   Employee, Student,       ...
   Student      |   Graduate, Undergraduate, ...
   Employee     |   Teacher,  Administrator, ...
Run Code Online (Sandbox Code Playgroud)

当前限制:

  1. 系统上的注册人员只能是学生或员工。
  2. 人实体需要社会编号的唯一性,我们假设每个人都只有一个唯一的(也就是一个足够好的主键)。(见#1)

后来我们决定去掉数字 1:如果有一天学院决定TeacherEmployee子类型)也可以Student,在空闲时间参加课程,改变数据库设计要困难得多,可能有数千、数百万、数十亿,数以万计的条目,而不仅仅是更改代码中的逻辑:只是不允许一个人同时注册为学生和员工的部分。

(这是非常不可能的,但我现在想不出其他任何事情。 显然这是可能的)。

为什么我们在数据库设计而不是代码中关心业务规则?

#1:7 年后的一个笔记,一个真实的例子:
我见过一个政府,因为一个错误,发放的 SSN 被复制了:多人,同一个 SSN。那些设计原始数据库的人肯定犯了没有在数据库中应用这种唯一性约束的错误。(后来原始应用程序中的一个错误?多个应用程序使用共享数据库并且不同意在哪里放置、检查和强制执行约束?...)。
这个错误将继续存在于系统中之后开发的所有系统都依赖于原始系统的数据库,未来很多年。阅读这里的答案,我学会了在数据库中明智地(而不是盲目地)应用所有约束,尽可能多地应用它们,以尽可能好地表示那里的真实物理世界。

database-design

24
推荐指数
12
解决办法
8090
查看次数

我如何证明删除外键的行为不会破坏现有数据?

TL;DR:证明在实践中,alter table table_name drop foreign key constraint_name语句的执行不会破坏现有数据。重要的考虑是语句本身的执行;考虑无关紧要的事后数据更改。(打个比方:打开马厩门是有害的行为,而不是马螺栓。)

我和我的老板对于是否在 MySQL/InnoDB 数据库中使用外键有不同的看法。我赞成使用它们来强制执行 RI 并利用ON DELETE CASCADEON UPDATE RESTRICT/ SET NULL,而他反对(相信他可以在应用程序级别强制执行 RI)。

他的论点主要是:

  1. Drupal 不使用它们,没有它们也能正常工作,那我们为什么要这样做呢?
  2. 当您需要更改数据和/或结构时,它们太不灵活了。
  3. 他已将它们从现有表中删除以进行更改,这导致数据损坏仅在数周或数月后才在高流量/高活动站点上引起注意,因此他宁愿不使用它们。

我的论点主要是:

  1. 并非 Drupal 5-7(MyISAM、SQLite 3)支持的所有数据库/数据库引擎默认都强制执行FK,因此 Drupal 仅将它们保留为文档,而这在 D8 中可能有所不同。
  2. 是的,它们可能很难处理,但也许问题在于开发人员的规划/设计不当,而不是 FK。
  3. 当然,在 DBMS 级别不使用 FK 强制执行 RI 比其他方式更有可能导致数据损坏。(例如,当现有内容引用必须具有特定状态的用户时,D6 的用户引用模块不限制更改用户状态)。
  4. 让代码做/尝试 DBMS 已经做的事情是在浪费时间和资源。他如何保证他的代码与 DBMS 一样好(或比 DBMS 更好)?

从本质上讲,如果我能证明删除外键本身的行为(无论后续数据插入/更新如何)不会破坏现有数据,他就会认同我的想法。我看不出有什么方法可以证明它们的有用性/优势,因为我不确定如何令人满意地观察/记录drop foreign key执行后立即产生的效果,而不是将执行前的数据与执行后的数据进行比较。

那么,我如何通过证明以后删除/更改外键的行为不会破坏现有数据,而使用它们不会导致任何问题来说服我的老板我们应该使用外键?我如何最好地设置实际使用测试?

注意:我不太想证明我使用 FK 是正确的(从自负的角度来看),但是在 DBMS 级别使用它们比在应用程序代码中使用它们更有益于数据和应用程序代码等级。

mysql innodb foreign-key database-design referential-integrity

5
推荐指数
2
解决办法
1828
查看次数

为什么要在我的关系数据库中实现外键?

今天早些时候,我与我的专业同行就我们公司数据库中的外键话题引发了一场相当意外的辩论。简而言之,一位比我年长的软件工程师说他不喜欢我对我们的一个存储库所做的提交,因为我在两个表之间实现了外键关系。他的论点是他不喜欢外键,因为它们限制了可以插入数据库的数据,他认为这会使数据库更难使用。(注意:他的论点一般反对外键,而不仅仅是我在我们的应用程序中提出的轶事外键约束。他认为外键约束是现代关系数据库系统中的一个设计缺陷。)

此时,我完全措手不及,我们的老板暂时选择站在高级开发人员一边,要求我从我正在处理的错误修复的实现中删除外键。我正在修复的错误实际上源于使我们的 ORM 感到困惑的关系不一致(这本身还有一些不足之处,但这是一个不同的故事),虽然我试图向我的团队解释这一点,但每个人都站在高级dev & 我被告知要回到绘图板并重新实现我的数据库修复,而不依赖于外键约束。换句话说,我被要求在没有 RDBMS(posgres,如果重要的话)的内置关系管理工具的情况下进行关系管理。

我重申这不是修复错误的正确方法,此时我的老板告诉我讨论占用了太多时间,如果我想辩论正式 FK 约束的优点,我需要以后再做……我打算这样做,但我也觉得我的任务是争论为什么水是湿的。

当我进入这场辩论时,我想用尽可能多的事实来支持外键的使用。我知道实施合理的 FK 约束:

  1. 作为防止关系不一致的自动护栏(即,防止“垃圾数据”(这是我目前正在使用的系统的一个明显问题)),
  2. 向正在检查数据库模式的人阐明两个相关表之间的高级关系上下文,以及
  3. 可以提高数据库查询操作的性能

......但我想知道在这个主题上是否还有其他我可能遗漏的要点,我应该用这些要点来应对这场辩论。我应该确保向我的老板和同事提出哪些其他好处?(或者真的有范式转变远离 FK 约束,当它发生时我一直把头埋在石头下?)

postgresql foreign-key relational-theory

5
推荐指数
1
解决办法
174
查看次数