MySQL主键、外键和索引

1. 主键

什么是主键?

主键其实是唯一性索引的一种,我们使用Laravel时,通常会在表里加一个自增的id,默认表中的id为主键。

属性:唯一、不为空

2. 外键

什么是外键?

表的外键是另一表的主键, 外键可以有重复的, 可以是空值。多表关联时,我们常用外键与主表建立联系,这样在删除数据时就可以不用从代码上关联删除记录,MySQL会自动删除从表记录。当然这需要在创建表时设计好外键约束。

属性:可重复,可空值

外键约束

父表更新时子表也更新,父表删除时如果子表有匹配的项,删除失败。

1
2
3
4
5
ALTER TABLE xxx ADD CONSTRAINT name FOREIGN KEY(xx) REFERENCES xxx(id)
[ON DELETE reference_option] // 在主表删除时
[ON UPDATE reference_option] // 在主表更新时
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION

参数解释:

  • CASCADE:
    从父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。
  • SET NULL:
    从父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。
  • NO ACTION:
    InnoDB拒绝删除或者更新父表。
  • RESTRICT:
    拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的。

3. 索引

为什么需要索引

索引影响着查询速度。至少要理解索引才能数据库调优。
假如有一张100w条数据的表(很大很大),你需要查找一个账号为123的人:

  • 在没有建立索引的情况下,需要遍历100w行数据,怕不怕
  • 假如建立的账号的索引,只需要查1或多行(某些索引类型可重复)

什么是索引?

MySQL的索引分为单列索引(主键索引,唯索引,普通索引)和组合索引.

单列索引

普通索引

最基本的索引,索引可重复。创建方法:

1
2
3
CREATE INDEX indexName ON `tableName`(`name`);
or
ALTER TABLE tableName ADD INDEX indexName(`name`);

唯一索引

与普通索引不同,索引不可重复,可为空。

创建方法:

1
2
3
CREATE UNIQUE INDEX indexName ON `tableName`(`name`);
or
ALTER TABLE tableName ADD UNIQUE INDEX indexName(`name`);

主键索引

一般设为自增的int型,可为char,但是int优于char。

组合索引

特定情况下,MySQL效率继续提升。

一个表中如果含有多个单列索引不代表是组合索引,组合索引是:多个字段组合成一个索引

1
CREATE INDEX indexName ON `tableName`(`nameA`, `nameB`, `nameC`);

实际效果相当于建立了(nameA, nameB, nameC)、(nameA, nameB)、(nameA)三个索引

为什么没有(nameB,nameC)?
因为MySQL组合索引遵循最左前缀原则, 索引的查询条件要注意:

  • 从最左项查询,即nameA。
  • 如果使用了范围查询,如like,那么此列右边的列无法作为索引查询。

什么时候用索引?

索引可以加快查询速度,但相应的会消耗相应的资源。索引也不是越多越好,在需要频繁插入、删除的表中,MySQL维护更新索引的成本会很大,得不偿失。所以索引适合用在经常需要查询,改动不频繁的表上。

删除索引

1
DROP INDEX indexName ON `tableName`;