MySQL 的3个小知识点,你知道吗?
最近看了几个MySQL的小知识点,积累了一下,分享出来,给大家尝尝鲜。
01
MySQL 外键约束关键字
如果你经常使用MySQL的外键约束,可能对外键约束的关键字并不陌生。
常见的外键约束关键字有:cascade、restrict、no action和set default和set null,其中,
cascade:表示级联,父表的动作会级联到主表中;
restrict:表示严格模式,它是MySQL特有的关键字,表示父表的上不能直接删除或者更新有外键关联的记录;
no action:表示严格模式,标准SQL关键字,在MySQL中,它和restrict的意思相同;
set default:父表上的记录删除后,关联的子表记录会设置成默认值;
set null:父表上的记录删除后,关联的子表记录会设置成null值。
从上面的描述不难发现,no action和restrict既然意思相同,为什么不统一成一种?
从字面意思来看,no action似乎代表主表数据删除之后,子表上不发生任何动作;而restrict看起来是严格禁止主表删除数据的,但是实际上,二者在MySQL中,意思是一样的。所以MySQL保留了restrict的关键字,更加直观、有效。
看一个例子吧:
1、首先创建一个parent父表,并插入数据
代码语言:javascript复制mysql> show create table parentG
*************************** 1. row ***************************
Table: parent
Create Table: CREATE TABLE `parent` (
`id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> select * from parent;
----
| id |
----
| 1 |
| 2 |
| 3 |
----
2、创建一个child的子表,并插入数据
代码语言:javascript复制mysql> show create table childG
*************************** 1. row ***************************
Table: child
Create Table: CREATE TABLE `child` (
`id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
KEY `par_ind` (`parent_id`),
CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)
REFERENCES `parent` (`id`) ON DELETE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> select *from child;
------ -----------
| id | parent_id |
------ -----------
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
------ -----------
3 rows in set (0.01 sec)
3、parent父表上删除id=1的记录。
代码语言:javascript复制mysql> delete from parent where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row:
a foreign key constraint fails (`test`.`child`,
CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)
REFERENCES `parent` (`id`) ON DELETE NO ACTION)
以上例子,说明no action跟restrict的含义是一样的。
02
table语法,你知道吗?
在MySQL中,查询一个表的所有数据,通常使用"select * from table_name"语法来查询, 在MySQL 8.0中,可以使用更加简单的语法:table table_name来对表数据进行查看。
如下:
代码语言:javascript复制MySQL 8.0.30
mysql> table child;
------ -----------
| id | parent_id |
------ -----------
| 2 | 2 |
| 3 | 3 |
------ -----------
2 rows in set (0.00 sec)
mysql> select * from child;
------ -----------
| id | parent_id |
------ -----------
| 2 | 2 |
| 3 | 3 |
------ -----------
2 rows in set (0.00 sec)
table 语法还可以跟limit、order by等关键字。
table语法和select * from table的语法,有2个重要区别:
1、table语法仅支持所有的列都显示,不支持过滤列。
2、table语法不支持where条件。
可以使用help 'table'命令去查看帮助,更多细节,请大家自己探索。
03
explain语法也能卡主MySQL?
看如下的SQL:
代码语言:javascript复制mysql> explain select * from ( select sleep(10)) t;
---- ------------- ------------ ------------ -------- --------------- ------ --------- ------ ------ ---------- ----------------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---- ------------- ------------ ------------ -------- --------------- ------ --------- ------ ------ ---------- ----------------
| 1 | PRIMARY | <derived2> | NULL | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 2 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
---- ------------- ------------ ------------ -------- --------------- ------ --------- ------ ------ ---------- ----------------
2 rows in set, 1 warning (10.01 sec)
通常的概念中,explain语法是查看执行计划的,不应该卡主MySQL才对.
然而,在上述例子中,当explain中包含一个sleep的子查询的时候,explain会先执行子查询,然后再输出结果,因此有一定可能阻塞住MySQL。
# DBA #