数据库外键ForeignKey
本文参考
外键是什么
如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。
比如有学生表(学号,姓名,性别,班级编号)和班级表(班级编号,班级名字),班级对应学生是一对多的关系,学生对应班级是多以一的关系。这种关系中,班级编号是两张表的公共关键字,又是班级表的主键,学生表的外键,所以呢,班级表是主表,学生表是从表
外键的作用:数据库通过外键来保证数据的完整性一致性
在用户进行insert,update,delete等操作时,数据库会先通过外键检测(做关系检查),才会允许操作。具体的!!!外键检测规则!!!如下:
- insert:主表不存在的主键,子表也是不能插入相应的外键的
- update:从表记录不存在时,主表才可以更新。更新从表,主表不变
- delete:从表记录不存在时,主表才可以删除。删除从表,主表不变
- 我们也自定义外键的级联操作规则,Hibernate通过关联关系映射就有这方面的设计,以后细讲,Hibernate关联关系映射并不好用。
举个例子:存在学生表(学号,姓名,性别,班级编号)和班级表(班级编号,班级名字),学生表引用了班级表的班级编号作为外键。在不设置外键的情况下。学生表的班级编号字段和班级表的班级编号字段是没有关联的。仅仅是你自己觉得他们有关系而已。数据库并不觉得它俩有关系。也就是说,你在学生表的班级编号字段插了一个值(比方20140999999),可是这个值在班级表中并没有,这个时候,数据库还是允许你插入的,它并不会对插入的数据做关系检查。然而在设置外键的情况下。你插入学生表班级编号字段的值必需要求在班级表的班级编号字段能找到。 同时。假设你要删除班级表的某个班级编号字段。必须保证学生表中没有引用该字段值的列,否则就没法删除。这就是所谓的保持数据的一致性和完整性。从表的字段必须与外键类型同样,这也保证了数据的一致性。
建外键几个原则
- 为关联字段创建外键。
- 所有的键都必须唯一。
- 避免使用复合键。
- 外键总是关联唯一的键字段。
外键的优点--保证数据的完整性一致性
- 业务逻辑清楚明了:外键在一定程度上可以说明业务逻辑
- ER可读性:有主外键的数据库设计可以增加ER图的可读性,这点在数据库设计时非常重要。
- 保证数据完整性一致性:外键是数据库级的一个完整性约束,通过建立外键,由数据库自身保证数据一致性,完整性,更可靠。
- 安全:使用应用程序来维护数据完整性是严重降低数据库安全性的一种做法。???
- 避免数据冗余:不适用外键,会导致数据冗余,在级联最底层的表可能会重复好几层的数据。会导致最底层的表数据量翻倍,IO瓶颈是数据库性能瓶颈之一。
- 使用外键可以保证数据的完整性和一致性
外键的缺点--对海量数据,性能低
- 降低性能:不用外键时,数据!!!管理简单,操作方便,性能高,在insert,update,delete数据的时候更快!!!。在海量数据库中不要用外键。比如一个程序每天要insert数百万条记录,当存在外键约束时,每次insert都要扫描此记录是不是合适,有没有违反外键约束,有的时候还不止一个外键,这样的扫描是成级数增长的。没有外键,3小时完成的入库,在有外键约束的情况下,要28小时。
- 增加开发维护难度:除了性能方便的问题,开发测试部署实施以及维护的时候都会带来不少问题。
- 可被替代:可以用触发器或应用程序保证数据的完整性
- 总之,外键可以维护数据库完整性,但是数据完整性几乎都是业务的要求,理应由业务部分负责维护,而不是依赖数据库。访问量较大的web应用,以及有一定规模的企业应用,都关注伸缩性和性能问题,各种形式的垂直、水平切分运用越来越多,外键、触发器、存储过程之类的基本属禁区。
- 总之:使用外键性能低,开发维护难!
要不要使用外键
数据库设计是否需要外键,这里有两个问题:一个是如何保证数据库数据的完整性和一致性;二是第一条对性能的影响。
- 在大型系统中(性能要求不高,安全要求高),使用外键;在大型系统中(性能要求高,安全自己控制),不用外键;小系统随便,最好用外键。
- 用外键要适当,不能过分追求
- 不用外键而用程序控制数据一致性和完整性时,应该写一层来保证,然后个个应用通过这个层来访问数据库。
逻辑外键
鉴于以上(物理)外键的优点和缺点,我们既想保证数据的完整性一致性,又想提高应用程序的性能,降低开发维护难度,就可以选择不用物理外键,使用逻辑外键由程序控制数据完整性。
- 使得业务逻辑清楚命令
- 保证数据完整一致性:全由业务应用程序控制数据完整性
- 提高了性能
- 降低了开发维护难度