当前位置:网站首页>MySQL 外键影响
MySQL 外键影响
2022-06-24 12:33:00 【Kevin崔】
数据库范式是一个比较抽象的概念,对于关系型数据库来说,有效的解决关系数据库中避免数据冗余,减少数据库的存储空间,并且减轻维护数据完整性的成本。
数据库范式也是关系型数据库核心的设计模式之一,也是从事数据库开发人员必备知识。其中外键适用于3NF第三范式,在数据库中的作用是保持数据一致性,完整性。主要目的是使两张表形成关联,控制存储在外键表中的数据。 外键在一定程度上说明的业务逻辑,会使设计周到具体全面。
特别是,MySQL已主键驱动数据,经验告诉我们,外键其实不适合。实际环境中很少使用外键,一般都是程序实现关联关系。
外键理解
在MySQL外键的关联中,包含多种action关联,如语法中体现:
[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注意:
目前外键使用范围 InnoDB和NDB存储引擎都会使用FOREIGN_KEY,还有受到lower_case_table_names大小写敏感系统变量。
父子表必须使用相同的存储引擎,并且不能将它们定义为临时表。
创建外键约束需要父表上的REFERENCES权限。外键和引用键中的对应列必须具有类似的数据类型。固定精度类型(如INTEGER、DECIMAL)的大小和符号必须相同。字符串类型的长度不必相同。对于非二进制(字符)字符串列,字符集和排序规则必须相同。
在外键引用表中,必须有一个索引,其中外键列以相同顺序列在第一列。以便外键检查可以快速,不需要全表扫描。
NDB要求在作为外键引用的任何列上都有一个显式的唯一键(或主键)。InnoDB不是。
不支持外键列上的索引前缀,BLOB和TEXT列不能包含在外键中。
InnoDB目前不支持分区的表的外键
外键约束不能引用虚拟生成的列。
外键的行为
从语法上包含三个Action 直接引用,update ,delete 对应操作:
CASCADE:删除或更新父表中的行,并自动删除或更新子表中匹配的行。
SET NULL:从父表中删除或更新行,并将子表中的外键列或列设置为NULL.
RESTRICT:拒绝父表的删除或更新操作。
NO ACTION:来自标准SQL的关键字。在MySQL中,相当于RESTRICT。如果在被引用的表中有一个相关的外键值,MySQL服务器拒绝对父表进行删除或更新操作。一些数据库系统有延期检查,NO ACTION就是延期检查。在MySQL中,外键约束被立即检查,所以NO ACTION与RESTRICT相同
SET DEFAULT:这个动作被MySQL解析器识别,但是InnoDB和NDB都拒绝包含ON DELETE SET DEFAULT或ON UPDATE SET DEFAULT子句的表定义。
备注:对于未指定的ON DELETE或ON UPDATE,默认操作总是NO action
InnoDB使用深度优先搜索算法对对应外键约束的索引记录执行级联操作。
锁机制
MySQL根据需要将元数据锁扩展到外键约束相关的表。对于外键检查,在相关表上使用共享只读锁(lock TABLES READ)。对于级联更新,在操作涉及的相关表上使用一个无共享的写锁(lock TABLES write)。当存在外键约束的时候,每次要去扫描此记录是否合格。所以一段关联字段操作,就容易会出现死锁现象。
#结构
CREATE TABLE categories(
cat_id int not null auto_increment primary key,
cat_name varchar(255) not null
) ENGINE=InnoDB;
CREATE TABLE products(
prd_id int not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
cat_id int not null,
FOREIGN KEY fk_cat(cat_id) REFERENCES categories(cat_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
)ENGINE=InnoDB;
#数据
insert into categories(cat_id,cat_name) values(1,'水果'),(2,'蔬菜');
insert into products(prd_id,prd_name,prd_price,cat_id) values(1,'苹果',9,1),(2,'菠萝',10,1),(3,'白菜',8,2),(4,'可乐',7,3);1)有意思的演示:
父表插入数据未提交,子表更新等待。
父表进行更新未提交,子表插入等待。
| session1 | session2 |
|---|---|
|
|
|
|
#外键最少2张表操作
mysql> show OPEN TABLES where In_use > 0;
+----------+----------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+----------+--------+-------------+
| dbdemo | products | 2 | 0 |
+----------+----------+--------+-------------+
mysql> SHOW ENGINE INNODB STATUS\G
#外键错误
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2022-05-31 17:22:52 140626893833984 Transaction:
TRANSACTION 9011856, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1128, 2 row lock(s), undo log entries 1
MySQL thread id 23, OS thread handle 140626893833984, query id 168 localhost root updating
update categories set cat_id=3 where cat_id=2
Foreign key constraint fails for table `dbdemo`.`products`:
,
CONSTRAINT `products_ibfk_1` FOREIGN KEY (`cat_id`) REFERENCES `categories` (`cat_id`)
Trying to update in parent table, in index PRIMARY tuple:
DATA TUPLE: 4 fields;
0: len 4; hex 80000002; asc ;;
1: len 6; hex 000000898290; asc ;;
2: len 7; hex 01000001970151; asc Q;;
3: len 6; hex e894ace88f9c; asc ;;
But in child table `dbdemo`.`products`, in index fk_cat, there is a record:
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000002; asc ;;
1: len 4; hex 80000003; asc ;;2)DDL操作受外键约束:
mysql > TRUNCATE TABLE products;
Query OK, 0 rows affected (0.03 sec)
mysql > TRUNCATE TABLE categories;
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (`dbdemo`.`products`, CONSTRAINT `products_ibfk_1`)
mysql> DROP TABLE categories;
ERROR 3730 (HY000): Cannot drop table 'categories' referenced by a foreign key constraint 'products_ibfk_1' on table 'products'.
注意:MySQL里外键是即时检查的,对每一行都会运行外键检查。如上述情况 或 用load data 导入数据,在检查外键约束上往往消耗大量时间。有时候,可以灵活处理,忽略外键检查:SET foreign_key_checks=0,默认值是1。
3)子表的里外键值是实际保存的数据,一旦父表外键更新,那子表随着更新。可以理解两张表索引结构变更。其实一个动作触发双倍的索引操作,IO放大。
总结
外键在MySQL提现有两种,一个是如何保证数据库数据的完整性和一致性;二是性能的影响。
不用外键时数据管理简单,操作方便,性能高(导入导出等操作,在insert, update, delete 数据的时候更快)
1.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
2.当删除,更新操作底层需要重新重组索引表,这样导致上锁的时间延长;
3.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;
4.数据库需要维护外键的内部管理;
综合这些因素,不推荐在关系型数据库使用外键,除了把控不好,在MySQL这样轻量级数据库上,影响范围比较大,建议全靠代码逻辑去保证。
边栏推荐
- How to check the situation that the national standard platform easygbs equipment video cannot be accessed by grabbing packets?
- 我在深圳,到哪里开户比较好?现在网上开户安全么?
- 巧妙构思-铁死亡调节因子分型预后发6+
- pipeline groovy
- Insurance app aging service evaluation analysis 2022 issue 06
- How is the e-commerce red envelope realized? For interview (typical high concurrency)
- National standard platform easygbs administrator assigns roles to sub users and troubleshooting of invalid channels
- Tencent cloud and the ICT Institute launched the preparation of the "cloud native open source white paper" to deeply interpret cloud native
- Introduction to C language circular statements (foe, while, do... While)
- Easynvr user login is modified to share the modification process of ip+ user name restriction
猜你喜欢

Opencv learning notes - regions of interest (ROI) and image blending

链接器 --- Linker
[mysql_16] variables, process control and cursors
Deep parsing and implementation of redis pub/sub publish subscribe mode message queue

FreeRTOS overview and experience
![[live review] battle code pioneer phase 7: how third-party application developers contribute to open source](/img/fa/e52bd8a1a404a759ef6ba88e8da0f0.png)
[live review] battle code pioneer phase 7: how third-party application developers contribute to open source
Database migration tool flyway vs liquibase (II)

ArrayList # sublist these four holes, you get caught accidentally

GLOG from getting started to getting started

ArrayList#subList这四个坑,一不小心就中招
随机推荐
Kubernetes best practice: graceful termination
打新债可以申请多少 开户是安全的吗
怎样购买打新债 开户是安全的吗
Opencv learning notes - loading and saving images
Install Kali on the U disk and persist it
Identification of new prognostic DNA methylation features in uveal melanoma by 11+ based on methylation group and transcriptome analysis~
ArrayList#subList这四个坑,一不小心就中招
Automatic reconstruction of pod after modifying resource object
Fbnet/fbnetv2/fbnetv3: Facebook's lightweight network exploration in NAS | lightweight network
Opencv learning notes -- Separation of color channels and multi-channel mixing
Tencent security monthly report - zero trust development trend forum, digital Expo Technology Award, Mercedes Benz security research results
[tke] GPU node NVIDIA Tesla driver reinstallation
How to configure the national standard platform easygbs neutral version?
Based on am335x development board arm cortex-a8 -- acontis EtherCAT master station development case
Simple and flexible permission design?
广发证券靠谱吗?开证券账户安全吗?
Continuous testing | making testing more free: practicing automated execution of use cases in coding
The operation and maintenance boss laughed at me. Don't you know that?
嵌入式必学!硬件资源接口详解——基于ARM AM335X开发板 (下)
Detailed explanation of the execution order of the expression and loop body in the for loop



