-
2021-09-14 22:28:15
外键带来的好处
数据一直性检查由数据库保证
外键带来的不便
1、测试成本高,麻烦
每次增删改时都要考虑到外键约束,在调试接口的时候很麻烦,且测试人员(很多黑盒测试人员玩不转)会要求开发提供测试数据。
调试麻烦、可能会浪费开发人员时间2、并发阻塞
产生并发问题:外键约束会启用行级锁,主表写入时会阻塞
如:表A有个字段a是外键,a是表B的主键。对表A增删改时会对锁住表B的的一行数据。此时表B这行数据不可插入。3、数据不可控
级联删除:删除主数据时,(主数据的id为其他表的外键)关联表数据也会删除
导致数据不可控(我明明只删除了表A一条数据,结果少了一大片数据…)
触发器也是同理,不建议使用(且维护起来比较懵逼)。4、数据高度耦合
数据库层面 数据强耦合,如果产生数据迁移(特别是跨数据库类型的,如:mysql -> mongoDB),数据校验部分又需要在代码里补上。
那么不如一开始就在代码里体现,这样也好交接些(代码是些给接坑的同事看的)5、影响数据库性能
有外键时,会先根据外键进行数据检查。
如:新增、删除操作时,数据库会先去检查外键对应的数据是否存在。最后说下
我部门的一位架构大佬就喜欢使用外键,原因是:
1:外键保证数据一致性
2:系统一般不会存在迁移(mysql -> oracle、pg)ps:但是私有化部署、清除测试数据、迁移到其他类型数据库时是真的恶心…
更多相关内容 -
数据库外键的设置与使用
2020-12-14 22:36:02一·首先是外键的作用与设置 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 b表中... -
数据库外键,用还是不用?
2020-12-14 20:59:01对于主/外键/索引来说,在一些开发团队中被认为是处理数据库关系的利器,也被某些开发团队认为是处理某些具体业务的魔鬼,您的观点呢?在实际应用中您会采取哪种方式? 大家共同观点: 主键和索引是不可... -
数据库外键理论及MySQL外键实现规定
2021-12-17 10:35:301. 关系数据库外键概念理论(大学时学习的概念) 教材是:王珊,萨师煊老师的数据库系统概论——第五版,这里直接丢截图了。 有三类完整性约束,分别是:实体完整性、参照完整性以及用户定义的完整性。 其中实体...文章目录
1. 关系数据库外键概念理论(大学时学习的概念)
教材是:王珊,萨师煊老师的数据库系统概论——第五版,这里直接丢截图了。
- 有三类完整性约束,分别是:实体完整性、参照完整性以及用户定义的完整性。
- 其中实体完整性和参照完整性是关系模型必须满足的完整性约束条件,被称作是关系的两个不变性,应该由关系系统自动支持(例如MySQL要负责这部分约束的检查)
- 用户定义的完整性是应用领域需要遵循的约束条件,体现了具体领域中的语义约束
- 不做强制检查,最多让人感觉不符合现实或者有点蠢,和程序员不怎么相关😛😛😛
- 比如:成绩只能是0-100,年龄只能是0-150以内,生日只能是1.1-12.31,类似这种语义约束。
1.1 实体完整性
主要用来描述,数据库中每行数据都应该是可区分的(有某个属性是唯一的!)
1.2 ✅ 参照完整性
- 参照完整性用来描述实体和实体间的联系(可以认为就是图数据库中的关系/边,relationship)
- 可以参考:图数据库初探——4. mysql数据导入neo4j(desktop界面导入)中💫
2.3 关系数据库转为图数据库的规则
部分。
- 可以看到,数据库理论中
- 假如
F
属性是一个表R
的属性,但是不是主码;属性K
是表S
的主码。(表R
和表S
不一定是不同的表)。如果F
和K
对应,则称F
是表R
的外码,并称表R
是参照关系(参照表),表S
是被参照关系。 - 可以去看看
1.5 MySQL数据库操作示例
- 这里的参照完整性规则,意思就是:如果选课表中的课程id,参照了课程表中的课程id,
- 那么选课表中的课程id的取值,要么为空,要么就等于 课程表中的课程id中某个值。
也是:Mysql错误1452 - Cannot add or update a child row: a foreign key constraint fails怎么办?中这个回答的理论依据。
1.3 用户定义完整性
1.4 ✅ 参照完整性的SQL实现
还是王珊,萨师煊老师的教材,是后面的例子,截图贴上来
主要还是关于参照完整性(外键)这部分的内容可以看到,对于学生版Student(Sno)、课程表Course(Cno)和学生选课表SC(Sno,Cno)来说,按照上面的规定,
则,Sno是表SC的外码,SC表是参照关系,被参照表是Student;Cno也是表SC外码,SC表是参照关系,被参照表是Course。1.5 ✅ MySQL数据库操作示例
如果是用Navicat设计mysql数据库,那么可视化应该是这样:
例如,有两个表,分别是poem(诗表)和poet_to_poem(诗人和诗对应表)
poem(诗表)数据
poet_to_poem(诗人和诗对应表)数据
poem(诗表)非空和主键约束
poet_to_poem(诗人和诗对应表)非空和主键约束很明显,
poet_to_poem
表中的poem_id
是引用自poem
表,所以可以设置一个外键(对poet_to_poem表设置)。
所以外键是设置在引用了其他表字段的表上!设置完之后,ER图显示就是这样,主键是钥匙,外键是个锁扣的形状
1.6 ✅ neo4j中的关系和mysql的外键
之前在:图数据库初探——4. mysql数据导入neo4j(desktop界面导入)中,由于外键设置错误,所以导入的时候,只导入了节点,没有识别出关系。设置正确后,就可以正确识别关系了,如下:
C:\shaiic_work\neo4j_data\relate-data\dbmss\dbms-54e8721d-3337-412a-8b54-d6ccd03b564e\bin\neo4j-admin.bat @C:\Users\HUANGS~1\AppData\Local\Temp\csv-001\neo4j-admin-import-params
很奇怪,这个命令运行了两次,第一次报错了
另外,重启桌面版之后,这个新建的数据库在对应的DBMS界面没有显示,但是用命令行去看,是可以看到的。CALL db.schema.visualization()
可以看到,neo4j中的schema导入前mysql的schema是基本一致的(只是关系表,转为了relationship边)
match (p:Poem) return p
一个表的主码就作为节点,其他的属性就作为节点的属性。2 MySQL中实现的规定
根据参考,进行关键部分的摘录
2.1 基本概念
MySQL支持外键,允许跨表的交叉引用(外键可以是表内,也可以是表外,mysql都支持),外键约束可以帮助保持相关数据的一致性。(被参照表的主键字段删了,对应的参照表的外键也会删掉)
外键关系包含拥有列的初始值的父表(例如:学生表),以及引用父表中列的值的子表(例如:学生成绩表引用学生表的student_id)。外键约束定义在子表上
创建表或者修改表时进行外键约束的语法如下(只有这两种时候才可以加外键约束):
[CONSTRAINT [symbol]] FOREIGN KEY [index_name] (col_name, ...) REFERENCES tbl_name (col_name,...) [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
2.2 ✅ 命名规则
- 在外键约束的语法中,如果已经对外键命名,即上面的
[CONSTRAINT [symbol]] FOREIGN KEY
中symbol
这个字段有值了,则直接使用这个值作为外键名称 - 如果CONSTRAINT symbol子句未定义,或CONSTRAINT关键字后未包含符号,
- 对于InnoDB表,会自动生成约束名称,ibfk是InnoDB Foreign Key的缩写
- 例如:使用Navicat工具管理mysql数据库。外键的一种常用命名方式是
表名_fk_序号
,如下,poet表的第一个外键就是:poet_ibfk_1
- 对于NDB表,使用该 FOREIGN KEY index_name值(如果已定义)。否则,会自动生成约束名称。
- 该值(如果已定义)在数据库中必须是唯一的。重复会 导致类似于以下内容的错误:
ERROR 1005 (HY000): Can't create table 'test.fk1' (errno: 121)。 CONSTRAINT symbolsymbol
(外键名称在一个数据库中必须唯一)
这是Mysql错误1452 - Cannot add or update a child row: a foreign key constraint fails怎么办?这个错误下这个答案的依据,只是不太匹配这个报错信息
2.3 ✅ 条件和限制
外键约束遵循以下条件和限制:
-
父表和子表必须使用相同的存储引擎,同时子表和父表不能是临时表。
-
创建外键需要从父表得到 REFERENCES 权限(需要有引用的权限)
-
外键列和它引用的被参照列必须有相似的数据类型(最好是一模一样或者是可以兼容的),比如整数(INTEGER)和小数(DECIMAL)的符号以及固定精度必须一致;如果是字符串类型,则对长度的规定可以不一致,对于非二进制(字符)字符串列,字符集和排序规则必须相同。
- 类似下面这样
- 类似下面这样
-
MySQL支持外键引用同一个表中的另一列(主键),但是列不能对列自身有引用。在这种情况下,子表记录指的是同一个表中的依赖记录。
- 比如,如果学生组,包含学生id属性,小组长/班长id属性,那么后者其实就会引用前者,所以支持同一个表中不同列的引用,但是不支持列对列自身的引用
-
MySQL要求外键和引用的列上都有索引,这样进行外键检查的时候就不需要扫描整个表,可以加快速度。在引用表中,外键引用的那列必须要用索引,如果没有,就会自动创建。
-
对于InnoDB来说,允许外键引用含有索引的列或者列组(好几列),不过,在引用的数据表上,其中引用的第一列上必须有相同的索引。
- 关于索引这部分,其实可以观察一下,在创建外键之后,会自动对外键的列添加索引。(确实是引用表的外键上有索引,被引用的则没有)
- 关于索引这部分,其实可以观察一下,在创建外键之后,会自动对外键的列添加索引。(确实是引用表的外键上有索引,被引用的则没有)
-
外键关系中的表不能更改为使用另一个存储引擎。要更改存储引擎,您必须首先删除所有外键约束。简单来说,还是建立外键关系的两个表,必须使用同一种存储引擎
2.3.1 存储引擎查询
- 关于存储引擎,其实就是这个:
- 也可以使用sql语句查询某个表的存储引擎
# 查询某个数据库中所有表的存储引擎 show table status from 库名; # 查询某个特定表的存储引擎 show table status from 库名 where name='表名';
参考:
- mysql官方文档:13.1.18.5 FOREIGN KEY Constraints
- mysql官方文档:1.7.2.3 FOREIGN KEY Constraint Differences
✅mysql5.7文档中文翻译(显示的是5.7 但是对应章节都不一样,参考对照着看,另外,有点像机翻,哈哈。)
-
MySQL自学笔记——设置外键约束这个应该也是看官方文档翻译的,可以作为参考
其他可能有用的信息
mysql5.1文档的中文翻译
- 1.8.6. MySQL处理约束的方式,网页中的链接有错误,自己往下拉,或者直接搜索
外键
- 15.2.6.4.外键约束
- 23.1.12. INFORMATION_SCHEMA TABLE_CONSTRAINTS表
实践的结果(从程序员的角度来看):
-
myMySQL数据库外键约束怎么写 MySQL数据库使用教程
2021-03-16 03:46:06mysql外键约束的写法:【[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1】。外键约束是表的一个特殊字段,经常与主键约束一起使用。在 CREATE TABLE 语句中,通过 FOREIGN KEY 关键字来指定外键。(推荐学习:...mysql外键约束的写法:【[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1】。外键约束是表的一个特殊字段,经常与主键约束一起使用。
在 CREATE TABLE 语句中,通过 FOREIGN KEY 关键字来指定外键。
(推荐学习:mysql教程)
具体的语法格式如下:
MySQL 外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表)。
定义外键时,需要遵守下列规则:
主表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则主表与从表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。必须为主表定义主键。
主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
在主表的表名后面指定列名或列名的组合。这个列或列的组合必须是主表的主键或候选键。
外键中列的数目必须和主表的主键中列的数目相同。
外键中列的数据类型必须和主表主键中对应列的数据类型相同。
举例:
为了展现表与表之间的外键关系,本例在 test_db 数据库中创建一个部门表 tb_dept1,表结构如下表所示。
创建 tb_dept1 的 SQL 语句和运行结果如下所示。
创建数据表 tb_emp6,并在表 tb_emp6 上创建外键约束,让它的键 deptId 作为外键关联到表 tb_dept1 的主键 id,SQL 语句和运行结果如下所示。
以上语句执行成功之后,在表 tb_emp6 上添加了名称为 fk_emp_dept1 的外键约束,外键名称为 deptId,其依赖于表 tb_dept1 的主键 id。
注意:从表的外键关联的必须是主表的主键,且主键和外键的数据类型必须一致。例如,两者都是 INT 类型,或者都是 CHAR 类型。如果不满足这样的要求,在创建从表时,就会出现“ERROR 1005(HY000): Can't create table”错误。
-
什么是数据库外键?
2021-04-10 21:17:42外键就是一个表中的一个字段引用了另一个表中的主键,引用的表叫做子表,被引用的表叫做主表,外键是一种约束,描述的是表之间的关系。外键
Teacher_id就是student的外键
Teacher是主表,student是子表(从表)
外键就是一个表中的一个字段引用了另一个表中的主键,引用的表叫做子表,被引用的表叫做主表,外键是一种约束,描述的是表之间的关系。
讲师:https://zhidao.baidu.com/usercenter?uid=db874069236f25705e79f91c&role=pgc主键、外键、索引的区别
主键、外键和索引的区别?
定义:
主键:唯一标识一条记录,不能有重复的,不允许为空外键:表的外键是另一表的主键, 外键可以有重复的, 可以是空值
索引:该字段没有重复值,但可以有一个空值
作用:
主键:用来保证数据完整性
外键:用来和其他表建立联系用的
索引:是提高查询排序的速度
个数:
主键:主键只能有一个
外键:一个表可以有多个外键
索引:一个表可以有多个唯一索引
-
数据库外键约束的优点和缺点
2021-09-25 23:35:331,由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。 eg:数据库和应用是一... -
Mysql数据库外键的使用【重点】
2021-12-06 20:42:00Mysql数据库外键用法 -
深度分析数据库外键的使用和原则
2021-04-14 15:01:20外键的作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 b表中存有每个客户的订单 ... -
SQL数据库外键代码
2021-01-18 19:15:29子表(test_student)创建一个外键, alter表TEST_STUDENT 添加约束fk_class_id外键(CLASS_ID) 参考test_class(CLASS_ID); 扩展资料: 1.高可用性: 分布式组织的可扩展性,决策支持的数据仓库功能,与... -
数据库外键示例 - 使用sqlite演示
2020-12-27 23:34:262个表;人员表,订单表; 创建人员表,pid为主键;Sqlite的主键自增长必须为integer,不能为int; 创建订单表;字段: oid,orderno, pid;...订单表中的 pid 列指向人员表中的pid列;...sqlite外键的写法:. -
Mysql 数据库外键设置方式
2021-02-05 03:30:54Mysql数据库5.5以后默认的表类型就是INNOB的,默认支持外键设置,现以学生选课表为例说明外键的设置格式。第一张学生表:create table student(sid int primary key ,sname varchar(45) not null,ssex varchar(2) ... -
一文一点 | 为什么不建议使用数据库外键
2020-08-25 22:43:57你好,这是【一文一点】的第1篇文章,不拘泥于篇幅字数,用一篇文章说清一个知识点。有的SQL规约是这么说的:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。那先复习下是什么... -
qt数据库外键查询
2022-02-04 19:23:29qt数据库外键查询 最近,开发qt数据库方面的信息管理系统,使用到了sqlite数据库,涉及到了外键查询。 查找了几个文章,没有找到合适的解决方案,阅读QSqlRelationalTableModel帮助文档,没有看懂其使用方法。 最后... -
2021-10-17 Django 学习,数据库外键的设置
2021-10-17 10:18:48Django 学习,数据库外键的设置 model.ForeignKey() TypeError: init() missing 1 required positional argument: ‘on_delete’ 建立外键的时候碰到上述报错 class Student(models.Model): s_name = models.... -
为什么需要数据库外键
2019-01-09 15:59:26MySQL数据库使用外键条件:两个表存储引擎必须是InnoDB,MyISAM暂时不支持外键;外键列必须建立索引,MySQL4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显式建立;外键关系的两表的列的... -
数据库外键ForeignKey
2021-03-11 22:33:23外键(foreign key)的使用及其优缺点 要不要使用外键(foreign key )? MYSQL外键的使用以及优缺点 外键是什么 如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键... -
数据库外键 附数据和代码
2018-05-14 23:46:06数据库外键定义: 数据库外键作用: 数据库外键和主键的区别: 数据库外键demo; DROP schema IF EXISTS `demo`; CREATE schema demo; -
查询mysql数据库外键和外键关联的表名
2020-05-17 23:27:57查询数据库外键和外键关联的表名 -
数据库外键使用所造成的影响有哪些?
2020-12-14 11:34:56数据库有外键时,可能导致热更新后不能正常使用,无法运行,只有重启服务才正常,从而达不到热更新目的 3.耦合度 外键的使用物理关联,导致耦合度增加 4.难以分库分表 在大型互联网项目中,如果要做分库,当存在... -
数据库外键和级联操作
2021-04-25 12:25:38外键的作用,以下表为例: --创建学生信息表 create table StInfo( StuNum varchar(20), StuName varchar(20), sex varchar(10), department varchar(30) ); --插入学生数据 insert into StInfo values('001',... -
数据库外键的使用以及优缺点
2018-08-23 13:59:251,由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。 e... -
数据库外键的注意事项
2021-05-24 10:58:52阻止执行 ...主表修改主键值,连带从表相关行的外键值一起修改。两种方法提供给用户选择。无论选取哪种方法,从表里都* 不会有多余行。从另一个角度理解,用拒绝同一事物在从表中的标志与主表不一致来实现 -
数据库外键的使用和原则
2015-11-19 10:47:49外键的作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 b表中存有每个客户的订单 有了... -
数据库外键foreign key
2020-10-11 19:05:24外键foreign key 如果一个实体的某个字段指向另一个实体的主键,就称为外键。被指向的实体,称之为主实体(主表),也叫父实体(父表)。负责指向的实体,称之为从实体(从表),也叫子实体(子表) 对关系... -
sqlite3数据库外键的问题
2022-04-13 10:06:56sqlite3数据库的外键默认是关闭的,使用的时候需要用以下的语句启用: PRAGMA foreign_keys = ON; 但是,问题在于,以后执行删除语句、插入语句或者更新,在需要外键限制的地方,都需要再次打开外键。 我在执行... -
关闭数据库外键约束
2017-08-06 19:54:27当向数据库中插入数据的时候,如果有表之间的关系十分复杂,尤其是是存在各种外键关系,这是需要暂时关闭这种针对外键约束的检查,本文针对以下三种数据库进行了一个总结 -
数据库外键的优势以及缺点
2017-05-23 13:40:48对于主/外键/索引来说,在一些开发团队中被认为是处理数据库关系的利器,也被某些开发团队认为是处理某些具体业务的魔鬼,您的观点呢?在实际应用中您会采取哪种方式? 大家共同观点: 主键和索引是不可少的,不仅... -
查看外键名称查看数据库外键名字
2019-10-29 12:46:35我们要进行删除外键时,需要知道外键的名字,那么如何查看数据库外键呢?有2种方式查看: 1.过查看表的方式查看外键名字; 2.通过mysql自带的系统表查看外键。 更多精彩请访问本文源地址: ... -
mysql数据库外键、主键详解
2021-01-18 18:41:25一、什么是主键、外键:关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如学生表(学号,姓名,性别,班级)其中每个学生的学号是唯一的,...