目录:
一.目标:简化数据库架构
架构层面,保证表的独立性,引用完整性,能兼顾性能是最好的。总的意思就是外键约束少不了的。
二. 反模式:无视约束[错误的使用场景]
省略外键约束,能让数据库简单,灵活,执行起来更加高效。表关系就要靠逻辑代码来维护了。
2.1.用代码来维护外键约束的弊端
- 没有完美的代码,这样会潜在带来表之间引用不完整的问题。(丢数据,数据错误的情况)
- 如果出现错误数据,没有办法及时有效的处理,就算用写的错误检测脚本也没有办法近实时的处理。
- 由于没有外键的约束,表数据不是自动连贯,如果用户直接操作数据库,就很容易带来错误的引用。
- 因为有外键约束,做删除操作的时候,就必须将外键关联的子记录都删除掉,麻烦的很。
三.如何识别以及合理使用反模式
3.1.如何来识别反模式?
- “怎么写一个查询语句来检查一个值是否没有同时在两张表同时存在?”
通常这样的需求数据引用不完整,出现了孤立的行。就是为了查找那些孤立的行。 - “有没有一种简单的方法来判断在一张表中的数据是否也在第二张表中存在?”
为了确定父记录是否存在。外键会自动完成这些,并且外键会使用这父表的索引尽可能的高效完成 - “外键?外键是会影响数据库效率吗?”
性能总是用来裁剪设计的一个好理由。但总是会引入更多的问题。甚至包括性能问题。
3.1.如何合理使用反模式?
- 不支持外键约束的数据库(MyISAM存储引擎):没办法,用别的方法来维护吧。(监控脚本,程序代码控制)
- 太灵活的外键约束:需要参照第6.7章给出答案。(TODO)
四.解决方案:声明约束
外键是必须要的,在入口就封死。防止逻辑出错。
4.1.解决修改删除的问题
CREATE TABLE Bugs (
-- . . .
reported_by BIGINT UNSIGNED NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'NEW',
FOREIGN KEY (reported_by) REFERENCES Accounts(account_id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (status) REFERENCES BugStatus(status)
ON UPDATE CASCADE
ON DELETE SET DEFAULT
);
4.1.外键真的开销过度吗?
外键其实开销要更小。
原因:
- (1)不需要在更新或删除记录前执行Select检查;
- (2)在同步修改时不需要再锁住整张表;
- (3)不再需要执行定期监控脚本来修正不可避免的孤立数据。
外键使用方便,提高性能。还能在任何简或复杂形势的数据变更下始终维持引用完整性。