当前位置: 首页 > news >正文

硅基计划5.0 MySQL 贰 SQL约束三大范式

1758766224377


文章目录

    • 1. 数据库约束
      • 1. 列不为空值——not null
      • 2. 列的默认值——default
      • 3. 指定列的值不能重复——unique
      • 4. 主键约束——primary key
      • 5. 外键约束——foreign key
      • 6. 自定义约束——check
    • 2、三大范式
      • 1. 第一范式
      • 2. 第二范式
      • 3. 第三范式
      • 4. 总结


1. 数据库约束

我们在创建数据库后,在里面创建表,我们可以针对表的特定行特点列指出特定的格式要求

我们就沿用上一篇文章中的数据库来做演示

1. 列不为空值——not null

insert into tmp_information values(null,'张三');

image-20250930143638611

2. 列的默认值——default

create table tmp_information(id int default 0,name varchar(10));insert into tmp_information(name) values('张三');select * from tmp_information;

image-20250930144650120

3. 指定列的值不能重复——unique

create table tmp_information(id int unique,name varchar(20));insert into tmp_information values(1,'张三');insert into tmp_information values(1,'李四');insert into tmp_information values(null,'王五');

image-20250930144935896
但是对于Null值是允许重复的
image-20250930145128218

4. 主键约束——primary key

这个相当于unique+not null的结合体

create table tmp_information(id int primary key,name varchar(10));insert into tmp_information values(null,'张三');insert into tmp_information values(null,'李四');insert into tmp_information values(1,'王五');insert into tmp_information values(1,'赵六');select * from tmp_information;

image-20250930145632228
可以看到结果的表中并没有Null的值而且也没有重复值

当然,我们也可以使用自增主键,说白了就是当值重复后,自动分配合适的主键

create table tmp_information(id int primary key auto_increment,name varchar(10));insert into tmp_information values(10,'张三');insert into tmp_information values(null,'李四');insert into tmp_information values(100,'王五');insert into tmp_information values(null,'赵六');

image-20250930150042420

可以看到自增主键会根据插入的数据自动分配合理的主键
当我们创建id = 10后,插入新的数据会分配到11
但一旦当我们插入id = 100后,再插入新的数据则会往后分配了
因此如果使用自增主键可能会造成空间浪费,但也没关系

5. 外键约束——foreign key

这个约束主要是对于两张表之间的某种联系,比如我这里有两张表,一张表是学生信息表,一张是班级信息表
那么这两个表之间,我们可以通过班级id去确认其具体班级
image-20251012155524643
但是你是否有发现赵六的班级是四班,可是我班级信息表中不存在四班啊,因此我们可以认为赵六四班这条数据是一个无效数据
虽然还是可以正常插入,但是不符合实际要求啊,那么怎么让数据库知道这是一条无效数据呢
这就是我们要讲的外键约束
那么,接下来,我们来实现代码

use home;create table class(class_id int primary key auto_increment,class_name varchar(3));insert into class values(1,'一班'),(2,'二班'),(3,'三班');create table student(name varchar(10),class_id int,age int,foreign key(class_id) references class(class_id));insert into student values('张三',1,18),('李四',2,19),('王五',3,20);insert into student values('赵六',4,19);

image-20251012160643564
可以看到报错信息提示我们插入的4班并未在班级表中存在,即外键约束

同理,我们想修改各个学生的班级信息,那么我们修改的班级必须在班级信息表中存在才可以
同理,如果在学生信息表中删除的班级是在班级信息表中已经存在的,也不可以
image-20251012161115834

因此,说白了就是两个表之间存在相互约束关系


接下来看这一种情况
image-20251012161404818
之前我在写班级信息表的时候,对于班级id那一列,我是使用了主键的,但是这一次我没有使用主键,当我使用外键约束创建学生信息表的时候,对于班级id那一列,报错了

为什么会报错,这是因为我们数据在进行全列查询的时候,加入数据表的数据非常之庞大,逐行遍历是非常耗时耗资源的,因此我们在查询的时候通常会用到索引
而这个索引,就是我们使用主键的时候创建的
我们没有使用主键约束某个特定列,就会导致我们在查询的时候非常不便
因此MYSQL要求使用外键约束的前提必须是约束来源的那个表的约束列必须使用主键
其实不一定是primary key才可以,unqiue约束也可以


接下来再看一种极端情况
就接着我们刚刚那两张表,如果发生这样的情况:三班因为人数过少被撤销了
这个时候你难道想把是三班的同学的信息删去吗?但是因为你使用了外键约束,导致我们无法删除
这时候我们就可以这样,我们在班级后面再添加一列,表示班级状态,可以使用布尔值或者是0与1方式表示
一旦这个班级撤销了,我们在其后面的列标记,这样当其他人查看的时候,就会提示这个班级被撤销了
虽然提示是被撤销,但实际上还是在硬盘上,只是换了一种显示方式而已
image-20251012162531358

6. 自定义约束——check

这个约束在实际开发中非常常用,能过大大提高自定义的空间
比如我想让一张价格表中商品价格不能超过100元或者是商品类型只能是饮料和零食

create table food_shop(name varchar(20),type varchar(5),price decimal(5,2),check(price > 0.00 and price <= 100.00),check(type = '零食' or type = '饮料'));insert into food_shop values('冰红茶','饮料',4.00),('QQ糖','零食',1.00);

image-20251012163231973
image-20251012163252353
你看,在下面两张图片中,不管是种类还是价格,如果不在符合的约束范围内,就无法插入

2、三大范式

我们在设计数据库的时候,要怎么设计才合规范,这就是我们要讲的三大范式

1. 第一范式

定义:每一列要为不可分割的原子数据项
说人说就是每一列能不可再拆分,每一列都是最小的数据单位
比如在学生信息表中的学校信息,如果你只填一个学校,那么我们是不是还是不知道这个学生具体在哪
因此学校那一列具体可以拆分成学院,学院所在校区,学院电话等等

2. 第二范式

定义:在第一范式基础上,当表中定义复合主键时候,不存在非关键字段对任意候选键部分函数依赖

我们先来解释相关概念

  1. 复合主键:我们平常都是指定一个主键。但是在复合主键中,我们是指定多个主键与之对应
    比如在成绩表中我们通过学号+科目确定一位学生某个科目考试成绩
  2. 候选键:刚刚提到复合主键是由多个列指定的,因此其中的某一个列就叫做候选键
    这里提个醒,对于复合主键,只有把几个列合在一起了我们才叫做这个表的主键,单拎出来一列我们就叫做候选键
  3. 非关键字段:主键以外的列
  4. 函数依赖:通过整个主键确定一条数据,就比如我们刚刚的学号+科目确定一位学生某个科目考试成绩
  5. 部分函数依赖:意思是我们不用通过整个主键去确定一条数据,而是主键的任意一部分去确定
    比如还是在成绩那一列,我们成绩表中包含姓名,那么我确定一位学生姓名,我是不是只需要通过学号确定就好,跟科目没关系啊,这就是部分函数依赖

这么说难免干巴,我直接拿一张表来演示
image-20251012165915941

那么如何去解决这个问题呢,很简单,我们一般都是每个表指定一个主键
好,那么我们可以把一个表拆分成几个表去表示
我直接把拆分结果给大家看
image-20251012170557470

3. 第三范式

定义:在第二范式基础上,不存在非关键字段的传递依赖

我们先来说说什么是传递依赖,比如这张表
image-20251012171114966
很明显,这张表是不合格的,除了在不当场景使用符合主键外,还存在传递依赖,怎么个传递法?
通过学号-->确定这名学生所在的学院,再通过学院-->确定所在校区和学院电话
你看,这三者之间,除了学院和学号是主键,学院校区和学院电话都是普通列
这就形成了非关键字段的传递依赖
因此,和我们刚刚那个表一样,拆分,让每一个表只能有一个主键,并且是一对一关系,不能形成传递依赖

4. 总结

我们在构造数据表的时候,要保证每一列不可拆分,并且一个标只能有一个主键,并且不能形成非关键字段的传递依赖
因此我们的每一张表只能有一个核心内容(主键),其他列都是围绕着这个核心内容展开的


非常抱歉这段时间没有更新
以后会更努力地写更多文章,一起加油!!!

END
http://www.dtcms.com/a/473413.html

相关文章:

  • 设计模式——工厂模式
  • 变色龙哈希与隐私保护
  • 栈和队列:“单端吞吐”VS”双端通行“(第十讲)
  • ros2系统在ubuntu18.04环境下的环境搭建
  • 个人网站展示dw网站制作
  • 鸿蒙NEXT系列之精析NDK UI API(节点增删和属性设置)
  • 10个免费货源网站郑州网络科技公司有哪些
  • Spring 源码学习(十三)—— RequestMappingHandlerAdapter
  • 虚幻引擎虚拟制片入门教程 之 3D渲染基础知识:模型、材质、贴图、UV等
  • excel导出使用arthas动态追踪方法调用耗时后性能优化的过程
  • 【数据结构】强化训练:从基础到入门到进阶(2)
  • python异步编程 -什么是python的异步编程, 与多线程和多进程的区别
  • Linux系统--进程间通信--共享内存相关指令
  • 网站开发的实践报告石家庄市工程勘察设计咨询业协会
  • TensorFlow深度学习实战——图分类
  • SAP MM采购信息记录维护接口分享
  • 网站搭建装修风格大全2021新款简约
  • Mysql初阶第八讲:Mysql表的内外连接
  • SpringCloud 入门 - Gateway 网关与 OpenFeign 服务调用
  • uniapp 选择城市(城市列表选择)
  • AR小白入门指南:从零开始开发增强现实应用
  • 02_k8s资源清单
  • 2025年渗透测试面试题总结-109(题目+回答)
  • uniapp配置自动导入uni生命周期等方法
  • flink的Standalone-HA模式安装
  • Flink时态表关联:实现数据“时间旅行”的终极方案
  • 做哪类英文网站赚钱wordpress 页面 列表
  • nginx + spring cloud + redis + mysql + ELFK 部署
  • 【黑马点评 - 实战篇01】Redis项目实战(Windows安装Redis6.2.6 + 发送验证码 + 短信验证码登录注册 + 拦截器链 - 登录校验)
  • 汕头市通信建设管理局网站二网站手