数据库主键、外键和索引的理解
数据库是一种用于存储和管理数据的软件系统,它最常见的功能就是实现数据的增删改查。而想要方便的对库立面的数据进行操作,归功于数据库里面的数据都是按照一定结构关系组织起来的,即数据会存储在若干个二维表中,这些表则由行和列组成;行表示数据记录,列表示字段。
如果用户想高效的将这些表组织为一个有效的数据集合,保证数据的完整性和一致性,那么数据库中的表就需要定义一些特殊的列,也就是标题中提到的主键和外键,我们可以说这两个指标就是各个数据表的粘合剂。至于索引,则对于数据检索有着关键的作用。但要注意的是,一旦数据表上了生产环境,那么我们所定义的这些指标就很难进行修改,因此在开发前设计阶段就定义好这些指标就非常关键了。
主键、外键和索引分别是什么?
主键
主键 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为主键
);
- 点赞
- 收藏
- 关注作者
评论(0)