序言:
对于一个外键列,如果没有显示地对这个列加索引,InnoDB存储引擎自动对其加一个索引,因为这个可以避免表锁

外键和锁:

在插入一个外键的时候,会需要先对父表进行读取。对父表的select操作不会使用一致性非锁定读。而是使用一致性锁定读来确保数据插入的正确性;
session A

  1. mysql> show create table child \G
  2. *************************** 1. row ***************************
  3. Table: child
  4. Create Table: CREATE TABLE `child` (
  5. `id` int(11) DEFAULT NULL,
  6. `parent_id` int(11) DEFAULT NULL,
  7. KEY `parent_id` (`parent_id`),
  8. CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8
  10. 1 row in set (0.00 sec)
  11. mysql> begin;
  12. Query OK, 0 rows affected (0.00 sec)
  13. mysql> delete from parent where id=3;
  14. Query OK, 1 row affected (0.00 sec)

session B

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into child values (3,3);/*此时inset操作会挂起,直到session A commit后*/

此时在session B中的插入外键操作,会先去查看父表中的值,这个时候因为id=3的记录正在Session A 中被delete(被赋予了一把X 锁),所以此时session B 中的insert 操作会挂起。