数据库主键、外键和索引的理解

举报
gentle_zhou 发表于 2023/12/22 23:26:07 2023/12/22
【摘要】 我们可以说主键和外键这两个指标就是各个数据表的粘合剂。至于索引,则对于数据检索有着关键的作用。

数据库是一种用于存储和管理数据的软件系统,它最常见的功能就是实现数据的增删改查。而想要方便的对库立面的数据进行操作,归功于数据库里面的数据都是按照一定结构关系组织起来的,即数据会存储在若干个二维表中,这些表则由行和列组成;行表示数据记录,列表示字段。

如果用户想高效的将这些表组织为一个有效的数据集合,保证数据的完整性和一致性,那么数据库中的表就需要定义一些特殊的列,也就是标题中提到的主键和外键,我们可以说这两个指标就是各个数据表的粘合剂。至于索引,则对于数据检索有着关键的作用。但要注意的是,一旦数据表上了生产环境,那么我们所定义的这些指标就很难进行修改,因此在开发前设计阶段就定义好这些指标就非常关键了。

主键、外键和索引分别是什么?

主键

主键 Primary Key,作为关系型数据库的基石,是一种用于唯一标识表中每一行记录的列或列的组合。这句话的意思就是一个表里只能有一个主键,它可以作为各个表之间的关联依据,保证表内数据的完整性。

值得我们注意的是,主键除了是表里唯一存在的特性之外,它还不能包含空值不能为NULL,通常主键会由数据库自动生成,常见的数据类型包括自增整数(AUTO_INCREMENT);尤其需要注意的是,主键一旦定义,就不应该修改,否则会破坏数据的一致性,因此最好可以设置为和业务无关且无意义的字段,以避免业务变化导致主键变化。

外键

外键 Foreign Key,则是一种用于建立和加强两个表之间联系的列或列的组合。它可以实现表之间的逻辑关系,如一对一、一对多、多对多等,保证各个表之间数据的一致性,防止出现孤立或不匹配的数据,以此提高数据的可读性和可维护性。

外键具备以下特点:它和主键不同,外键可以包含空值可以为NULL,也可以有重复的值,不一定得是唯一的。数据表中可以有多个外键,但必须引用另一个表的主键或唯一键,且他们之间的数据类型及长度必须一致或则至少兼容。

索引

索引 Index,基于数据表单列或则多列,是一种用于提高数据检索效率的数据结构。通过索引,可以快速定位到数据行的位置,减少数据的扫描次数;直接按照索引列的顺序返回数据,降低数据的排序成本;并且通过索引可以加速分组和聚合操作,如GROUP BY、COUNT、SUM等,支持数据的分组和聚合

索引的特点包括:索引是对表中一列或多列的值进行排序的一种方式,类似于书籍的目录或字典的检字表;索引可以是唯一的,也可以是非唯一的,前者要求索引列的值不能重复,后者则允许索引列的值重复;它也可以是由主键自动创建的索引,或则由用户自定义创建。

索引的使用方法其实就是对数据表内数据增删改查的操作,可以分为4大类:使用CREATE INDEX语句创建索引、使用DROP INDEX语句删除索引、使用SHOW INDEX语句查看索引、使用OPTIMIZE INDEX语句优化索引或则重建索引。

唯一索引

唯一索引,作为索引中的一类,它要求索引列的值是唯一的,但允许有空值。

唯一索引的主要作用就是保证数据的唯一性,防止出现重复的数据。唯一索引也可以提高查询速度,因为一旦找到满足条件的记录,就会立即停止搜索。

三者实际运用举例

这里举个经典的例子,假设我们有两张数据表,一张是关于学生的,一张是关于班级的。

在学生这张表里,我们有如下数据:

id student_name class_id
1 Alice 1
2 Bob 2
3 Chanel 3
4 Dove 1

在这张表里,主键是自动生成且无意义的id,外键则是class_id。

而在班级这张表里,我们则有如下数据:

id name
1 小班
2 中班
3 大班

在班级这张表里,主键也是自动生成且无意义的id,外键在这表里就没有存在。

由上面两张图,结合前面一节“主键、外键和索引分别是什么?”的介绍,我们可以得出如下结论:

  • 主键是用于唯一标识表中每一条记录的指标,它不能重复,不能为空,且只能有一个。例如,学生表的id列和班级表的id列都是主键,它们的值都是自动生成的,不会有重复或空值的情况。
  • 外键是用于数据表之间建立联系的指标,它必须引用另一个表的主键或唯一键,它可以重复,可以为空,且可以有多个。例如,学生表的class_id列就是外键,它引用了班级表的id列;它的值可以重复,表示多个学生属于同一个班级,但不能超出班级表中id列的值范围,因为外键和引用的表的主键/唯一键的数据类型及长度必须一致或则至少兼容。
  • 索引是用于提高数据检索效率的数据结构,它对表中的一列或多列的值进行排序,方便快速定位数据。例如,学生表的id列和班级表的id列可以作为主键索引,它们是唯一的,可以帮助用户快速找到对应的记录。当然我们也可以用学生表的student_name列创建一个非主键索引,就可以加速用户按照姓名查询学生的操作。

最后,附上可以创建出如上两张表的一种SQL语句表达方式:

CREATE TABLE students (
  id INT NOT NULL AUTO_INCREMENT, -- 学生表的主键,自增整数类型
  student_name VARCHAR(255) NOT NULL, -- 学生的姓名,字符串类型,不能为空
  class_id INT NOT NULL, -- 学生所属的班级,是学生表的外键,整数类型,不能为空
  PRIMARY KEY (id), -- 定义id为主键
  FOREIGN KEY (class_id) REFERENCES classes (id) -- 定义class_id为外键,引用classes表的id列
);

CREATE TABLE classes (
  id INT NOT NULL AUTO_INCREMENT, -- 班级表的主键,自增整数类型
  name VARCHAR(255) NOT NULL, -- 班级的名称,字符串类型,不能为空
  PRIMARY KEY (id) -- 定义id为主键
);
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。