Day03-mysql基础篇之关系模型

本文详细介绍了关系模型中的关键概念,包括主键的唯一标识作用及常见问题,联合主键的使用,外键的一对多、多对多和一对一关系,以及索引的创建和效率。强调了主键和外键在数据关联中的重要性,以及索引对查询性能的提升,同时讨论了不同场景下选择使用或不使用索引的考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们上上一篇简单介绍了关系模型是一个存储着数据的二维表,那么这篇文章就介绍介绍关系模型中表与表之间的关系是如何来进行维护的。

首先要明确三个概念,主键,索引,外键。

主键

是指关系表中记录的唯一标识,什么叫唯一标识,就是这个表中任意的两条记录是不能重复的,不能重复是指不完全重复,不是一点都不能重复。从上面的概念我们可以看出主键的作用就是为了区分不同的记录。

ps:补充一下什么是记录

 这个表中的每一行代表一条记录,一条记录是有多个字段组成的。这个表有两条记录。

对于主键的要求:我们要明确一点,就是绝对不能出现重复,不能使用任何和业务相关的字段作为主键。例如:如果我们使用name字段作为主键的话,那么数据表中就无法添加和小明一样名字的一条记录,这样就非常的不合理,难道全世界只有你才能叫小明吗?

最最常见的就是把主键的字段名设置为id,主键的生成策略int变量的自增,UUID字符串。但是他们都存在问题,第一种自增的情况会出现,当数据发生迁移的时候,很容易就出现主键的冲突问题。第二种解决了第一种的情况,但是这种方式生成的主键是无序的,无法知道表中数据的插入顺序问题,需要使用其他的字段来进行排序,一般采用时间戳。但是在分布式系统中也存在问题,并发量太大的时候,时间戳的排序就不精准了,怎么解释呢,就是我们往数据表中添加一个字段,这个字段展示的插入数据的时间。如果我们在同一时间内往数据表中添加很多条记录,那么可能一秒内添加了几千条,几万条,我们怎么知道谁先添加上去呢?结合抢购案例就能简单的理解这种情况。

联合主键

联合主键的意思就是使用多个字段标识同一条记录,就是把两个或者更多的字段设置为主键。

对于联合主键,可以出现一列中有重复的数据,但是不能两列都重复。看图:

 一般我们不会使用联合主键,因为它导致了关系表的复杂度的上升,本来就烦,使用这个更烦。

主键不允许为空。特别标注。默认使用bigint和GUID类型。

外键

外键这个概念应该怎么理解呢,我觉得要结合两个表之间的关联关系来理解,下面我们根据一个案例来进行理解。

一对多

例如现在有两张表,一张学生表,一张班级表,一个班级拥有多个学生,但是这种关系怎么表示?我们可以在学生表中增加一列,暂且称它为class_id字段,让他对应班级表中的主键,这样我们就可以通过class_id这一列直接定位出学生表这一条记录对应班级表的哪一条记录。

通过在学生表中定义class_id字段,可以把学生表中的数据和班级表的中数据关联起来,这种列我们通常称为之外键。但是外键并不是通过列名来实现的,而是通过定义外键约束来实现的。

定义外键约束的sql语句如下:

alter table students
add constraint fk_class_id
foreign key (class_id)
references classes(id);

student表示我们要向哪个表添加外键,fk_class_id表示这个外键的名称是什么,class_id表示我们指定的是我们要添加的那个表中的哪个字段,classes(id)表示我们要关联到哪个表的哪个字段。

 通过navicat能够很清楚的看到我们为哪个字段设置了外键,外键的名称是什么。

 通过定义外键,可以保证我们插入数据的时候不会插入无效的数据,比如id为99的班级如果不存在,那么学生表中就不能插入class_id为99的数据。虽然这种方式挺好的,但是我们通常都不使用这种方法来设置外键约束,因为大部分的互联网应用程序为了速度,放弃了设置外键约束,而是仅仅依靠程序自身来保证逻辑的正确性,(就是我们正常的逻辑就是不会添加不存在的数据,或者设置条件,默认不让你进行添加,只给你展示存在的数据。)。

删除外键也是通过alter table来实现的,还记得这个操作表中字段的语句是什么语句吗?

alter table students
drop foreign key fk_class_id

此处注意删除的是外键的约束,并没有删除students表中的字段,没有对表结构进行改变。

多对多

 我们实现多对多关系通常是把这个关系转换成两个一对多的关系,即通过一个中间表,关联两个一对多关系。例如

 一对一

一对一表示一个表中的记录对应到另一个表中的唯一的记录,这样理解,我们把一个表中的某个字段拆分出去单独成为一张表,那么就可以得到一对一的关系。我们通常把这个关系应用于把一张大表中经常查询的字段分出来单独成为一张表,这样就提高了我们的查询速度哦。

索引

在关系型数据库中,如果存在成千万或者上亿的记录,在查找记录的时候想要缩短查询时间,就需要使用到索引。索引就是对数据库中某一列或者多列进行一个预排序。在查询的时候不必扫描整个表,直接定位到符合条件的记录。这样的话就大大加快了我们的查询速度。

例如需要频繁对student表中的name字段进行查询,我们可以为name这一列创建一个索引。

# 为某一列设置索引
alter table students
add index idx_name (name);
# 为多列设置索引
alter table students
add index idx_name_score (name,score)
# 删除索引
alter table students
drop index idx_name;

 那么索引的查询效率取决于什么呢?索引的效率取决于需要被索引的列是否是散列的,比如性别gender这一列,只有两个值,那加不加索引查询速度都不会受到太大影响。

索引的优点是提高了查询效率,缺点是插入、删除、更新记录的时候比较慢,需要同时修改索引。

需要了解的是对于主键来说,关系型数据库会自动创建主键索引,使用主键索引的效率是最高的。因为主键的特性就是绝对唯一性。

唯一索引

就是说我们的表中出现了看上去唯一的列,像身份证号这样的列,我们就可以给这种列添加一个唯一索引。

alter table students 
add UNIQUE index idx_name (name) 

需要明白的是,不管创不创建索引,对于用户和应用程序来说,使用关系型数据库没有任何区别。因为当我们在数据库中查询的时候,如果有相应的索引可以使用,那么数据库管理系统就会自动使用索引来进行查询,如果没有索引,那么查询也会正常的执行,只是速度相对来说会慢一点。索引一般我们在使用数据库的时候慢慢优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值