外键的作用
外键的主要作用是:保持数据的一致性、完整性。
关于外键,我有自己的一些理解,但是不晓得是否正确,举个例子来表达我的看法:假如现在需要建立一个表,一个什么样的表呢?一个班级的学生个人信息表:
所以在设计的时候,就给表1添加一个外键,这个外键就是表2中的学号字段,那么这样表1就是主表,表2就是子表。所以结合2张表就能保持数据的一致性、完整性(估计就是还原成原来的那张大表吧)。
借着这个例子再谈谈外键的一些事项:
1表1可以有一个或者多个外键,也可以没有。(如果表1有多个外键可不可以是这样的情况,表2中的多个字段是表1的外键;或者说表1的多个外键是在多个表中)
以上就是我个人对外键的理解。
----------------------------------------解---答---纠---正-----------------------------------------
什么是外键
+-------+ ref +-------+
| sub | ------> | main |
+-------+ +-------+
从表(sub)的某列引用(ref)主表(main)的某列的值。比如学生表有个学生编号(sid),分数表中的学生列(stu)引用学生表的学 生编号,此时对于分数表的 stu 来说,学生表的 sid 就是外键。从表也叫外键表,主表也叫主键表、外表,列也叫字段。
所以在设计的时候,就给表1添加一个外键,这个外键就是表2中的学号字段,那么这样表1就是主表,表2就是子表。
你的主从关系理解颠倒了。你的图中,表1的确是主表,表2是子表,但不是叫做给表1添加一个外键,而是给表2添加一个外键,表2中的学号 字段就叫外键,它是表1学号字段的主键。你可以这样说:表1的学号字段是表2的外键。
外键用来干什么
你贴的图片已经解释了。为了一张表记录的数据不要太过冗余。这和软件工程的模块化思想差不多类似,只不过在数据库中是对表关系进行解耦,尽量让表 记录的数据单一化。就如你贴的图片中,把成绩和学生信息放在一张表中就太冗余了,成绩完全可以以学生的id作为区分标识。
为什么说外键能保持数据的一致性、完整性
你想想,你的图中的第一章表分割成了表1和表2,表2的学号引用了表1的学号字段作为外键,如果不建立外键,只是和表1一样单纯性 地设立一个学号字段,那么和建立外键有什么区别呢?
比如表1中张三的学号为20140900001,那么我在表2中插数据的时候在学号字段插20140900001来记录张三的成绩不也是做到了表 的解耦了吗?
这里存在的问题是,在不设置外键的情况下,表2的学号字段和表1的学号字段是没有关联的。只是你自己认为他们有关系而已,数据库并 不认为它俩有关系。也就是说,你在表2的学号字段插了一个值(比如20140999999),但是这个值在表1中并没有,这个时候,数据库还是允 许你插入的,它并不会对插入的数据做关系检查。然而在设置外键的情况下,你插入表2学号字段的值必须要求在表1的学号字段能找到。 同时,如果你要删除表1的某个学号字段,必须保证表2中没有引用该字段值的列,否则就没法删除。这就是所谓的保持数据的一致性和完整性。你想,如 果表2还引用表1的某个学号,你却把表1中的这个学号删了,表2就不知道这个学号对应的学生是哪个学生。数据的一致性还包括数据类型的一致性(这 个见下面就知道了)。
外键的使用规则
从表的字段必须与外键类型相同(如上,分数表 stu 的类型必须和学生表 sid 的类型相同,比如都是 int(10) 类型)外键必须是主表的唯一键(如上,学生表 sid 是主键,而主键是唯一的,所以可以作为分数表 stu 的外键)有关联的字段(如上,分数表之所以使用学生表的 sid 是因为两者有关联,分数表记录的是学生的分数,而学生可以用 sid 来唯 一标识)避免使用复合键(也就是说从表可以同时引用多个外表的字段作为一个外键,一般不推荐这种做法)
你的问题
如果表1有多个外键可不可以是这样的情况,表2中的多个字段是表1的外键;或者说表1的多个外键是在多个表中。
都可以。因为表1的外键不一定是表2的主键,也可以是唯一键(UNIQUE)。比如表2有个主键 A,有个唯一键 B,表1两个字段 A‘ 和 B’ 分别引用表2的 A 和 B,这就是多对多的关系了。再或者表2主键 A,表3主键 B,表1的两个字段 A‘ 和 B‘ 分别引用表2的 A 和表3 的 B。
外键不一定需要作为从表的主键,外键也不一定是外表的主键,外表的唯一键就可以作 为从表的外键。
再给一张图以帮助理解
平常需要使用外键吗?
数据库的诸多设计,帐号,权限,约束,触发器,都是为 C/S 结构设计的,是以 C 端不可信做为假设前提的。B/S 模式安全边界前移到 web 服务层,应用与数据库之间是可信的,应用自行完成这些功能更加灵活。所以能不用就不用
1. 互联网行业应用不推荐使用外键: 用户量大,并发度高,为此数据库服务器很容易成为性能瓶颈,尤其受IO能力限制,且不能轻易地水平扩展;若是把数据一致性的控制放到事务中,也即让应用服务器承担此部分的压力,而引用服务器一般都是可以做到轻松地水平的伸缩;
2.数据库服务器的性能不是问题,所以不用过多考虑性能的问题;另外,使用外键可以降低开发成本,借助数据库产品自身的触发器可以实现表与关联表之间的数据一致性和更新;最后一点,使用外键的方式,还可以做到开发人员和数据库设计人员的分工,可以为程序员承担更多的工作量;
为何说外键有性能问题:
1.数据库需要维护外键的内部管理;
2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;