MySQL学习笔记——数据库约束与数据库设计-表设计

目录

[5 数据库约束](#5 数据库约束)

[5.1 约束类型](#5.1 约束类型)

[5.2 NOT NULL 非空约束](#5.2 NOT NULL 非空约束)

[5.3 UNIQUE 唯一约束](#5.3 UNIQUE 唯一约束)

[5.4 PRIMARY KEY 主键约束](#5.4 PRIMARY KEY 主键约束)

[5.5 FOREIGN KEY 外键约束](#5.5 FOREIGN KEY 外键约束)

[5.6 DEFALUT 默认值约束](#5.6 DEFALUT 默认值约束)

[5.7 CHECK 约束](#5.7 CHECK 约束)

[6 数据库设计------表设计](#6 数据库设计——表设计)

[6.1 范式](#6.1 范式)

[6.2 第一范式](#6.2 第一范式)

[6.3 第二范式](#6.3 第二范式)

[6.4 第三范式](#6.4 第三范式)

[6.5 设计过程](#6.5 设计过程)

[6.6 E-R图](#6.6 E-R图)

[6.6.1 一对一(1:1)](#6.6.1 一对一(1:1))

[6.6.2 一对多(1:N)](#6.6.2 一对多(1:N))

[6.6.3 多对多(M:N)](#6.6.3 多对多(M:N))

5 数据库约束

数据库约束是指对数据库中的数据所施加的规则或条件,用于确保数据的准确性和可靠性。这些约束可以使基于数据类型、值范围、唯一性、非空等规则,以确保数据的正确性和相容性。

5.1 约束类型

类型 说明
NOT NULL 非空约束 指定非空约束的列不能存储 NULL 值
DEFAULT 默认约束 当没有给列赋值时使用的默认值
UNIQUE 唯⼀约束 指定唯⼀约束的列每行数据必须有唯⼀的值
PRIMARY KEY 主键约束 NOT NULL 和 UNIQUE的结合,可以指定⼀个列或多个列,有助于防⽌数据 重复和提高数据的查询性能
FOREIGN KEY 外键约束 外键约束是⼀种关系约束,用于定义两个表之间的关联关系,可以确保数据 的完整性和⼀致性
CHECK 约束 用于限制列或数据在数据库表中的值,确保数据的准确性和可靠性

5.2 NOT NULL 非空约束

定义表示某列不允许为NULL时,可以为列添加非空约束。

  • 比如创建⼀个学⽣表,学⽣名为NULL时,这条记录是不完整的

5.3 UNIQUE 唯一约束

指定了唯一约束的列,该列的值在所有记录中不能重复,比如身份证号和学号。

5.4 PRIMARY KEY 主键约束

主键约束唯⼀标识数据库表中的每条记录。

主键必须包含唯⼀的值,且不能包含 NULL 值。

每个表只能有⼀个主键,可以由单个列或多个列组成。

通常为每张表都指定⼀个主键,主键列建议使用BIGINT类型

一个主键可以包含多个列

表中不能有多个主键

sql 复制代码
drop table student;
# 重构学生表
create table student(
    id bigint PRIMARY KEY auto_increment,
    name varchar(20) primary key
);
ERROR 1068 (42000): Multiple primary key defined # 报错

复合主键:有多个列共同组成的主键,主键冲突是否已多个列的组成进行判定

sql 复制代码
# 复合主键:有多个列共同组成的主键,主键冲突是否已多个列的组成进行判定
drop table student;
# 重构学生表
create table student(
    id bigint,
    name varchar(20),
    PRIMARY KEY (id, name)
);
# 插入数据
insert into student(id, name) values (1, '张三');
# 重复插入主键冲突,此时主键值由id和name两个列共同决定
insert into student(id, name) values (1, '张三');
# 报错:1062 - Duplicate entry '1-张三' for key 'student.PRIMARY'
# 修改id 值插入成功
insert into student(id, name) values (2, '张三');
select * from student;

5.5 FOREIGN KEY 外键约束

外键用于定义主表和从表之间的关系

外健约束定义在从表的列上,主表关联的列必须是主键或唯一约束

当定义外键后,要求从表中的外键列数据必须在主表的主键或唯一列存在或为null

  • 创建班级表(主表),并初始化数据
sql 复制代码
# 创建班级表(主表),并初始化数据
drop table if exists class;
# 建表
create table class (
    id bigint primary key auto_increment,
    name varchar(20) not null
);
# 初始化数据
insert into class (name) values ('java01'), ('java02'), ('java03'), ('C++01'), 
('C++02');
​
select * from class;
​
-- --------------------------------------
# 重构学生表(从表),加入外键约束
# 语法
​
drop table if exists student;
# 重构表
create table student(
    id bigint PRIMARY KEY auto_increment, 
    name varchar(20) not null,
    age int DEFAULT 18,
    class_id bigint,
    foreign key (id) REFERENCES class(id) # 创建外键约束
);
​
# 查看表结构,可以Key列的值为MUL表示外键约束的列
desc student;
​
# 正常插入数据
# 班级编号在主表中存在
insert into student(name, class_id) values ('张三', 1), ('李四', 2);
​
select * from student;

5.6 DEFALUT 默认值约束

DEFALUT约束用于向列中插入默认值,如果没有为列设置值,那么会将默认值设置到该列

5.7 CHECK 约束

可以应用于⼀个或多个列,用于限制列中可接受的数据值,从而确保数据的完整性和准确性。

sql 复制代码
drop table if exists student;
# 加⼊CHECK约束
create table student(
    id bigint PRIMARY KEY auto_increment, # 设置⾃增主键
    name varchar(20) not null,
    age int DEFAULT 18,
    gender char(1),
    check (age >= 16),
    check (gender = '男' or gender = '⼥')
);
# 正常插⼊数据
insert into student(name, age, gender) values ('张三', 17, '男'), ('李
四', 19, '⼥');
select * from student;

6 数据库设计------表设计

6.1 范式

  • 数据库的范式是一组规则。在设计关系数据库时,遵从不同的规则要求,设计出合理的关系行数据库库,这些不同的规范要求称为不同的范式。

  • 关系型数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德 范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式),越高的范式数据库冗余越小。然而,普遍认为范式越高虽然对数据关系有更好的约束性,但也可能导致数据库IO更繁忙,因此 在实际应用中,数据库设计通常只需满足第三范式即可。

  • 数据库IO更繁忙------指原本从一个表中可以查出来的数据,这时需要从多个表中查。

6.2 第一范式

定义:

  • 数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,对象等非原子数据。

  • 在关系型数据库的设计中国,满足第一范式是对关系模式的基本要求。不满足第一范式的数据库不能被称为关系型数据库。

示例:

6.3 第二范式

定义:

  • 在满足第一范式的基础上,不存在非关键字段(非主键字段)对任意候选键(可以理解为主键,唯一键,用来标识数据行)的部分函数依赖。存于表中定义了复合主键(主键包含多个列)的情况下。

  • 候选键:可以唯一标识一行数据的列或者列的组合,可以从候选键中选一个或多个当做表的主键。

示例:

  • 需求:学生可以选修课程,课程有对应的学分,学生考试后每门课程会产生相应的成绩

反例:

不满足第二范式可能出现以下问题:

  • 数据冗余
  • 更新异常

  • 插入异常

  • 删除异常

正例:

6.4 第三范式

定义:

  • 在满足第二范式的基础上,不存在吧非关键字段,对任意候选键的传递依赖。

示例:

  • 要求学生表中记录学生所属的学院,在满足第⼆范式的基础上对学生表做出修改------该需求实际上设计两个实体,一个是学生,一个是学院。

反例:

正例:

6.5 设计过程

  • 从现实业务中抽象得到概念类

    概念类是从现实世界中抽象出来的,在需求分析阶段就需要确定下来

    • 类对应了数据库设计中的实体,实体对应了数据库中的表
    • 类中的属性对应实体中的属性,实体的属性对应了表中的列
  • 确定实体与实体之间的关系,并画出E-R画,⽅便项⽬参与⼈员理解与沟通
  • 根据E-R图完成SQL语句的编号并创建数据库

6.6 E-R图

E-R图包含以下三种基本组成: 实体:指数据对象,用规矩框表示,比如用户、学生、班级等。

属性:实体的特性,用椭圆形或圆角矩形表示,入学生的姓名、年龄。

关系:实体间的联系,⽤菱形框表示,并标明关系的类型,并⽤直线将相关实体与关系连接起来。

6.6.1 一对一(1:1)
6.6.2 一对多(1:N)
  • ⼀个学⽣实体包含的属性有:真实姓名,学号,年龄,性别,入学时间

  • ⼀个班级实体包含的属性有:班级名,学生⼈数

  • ⼀个班级中有多个学生,所以班级实体与学生实体是⼀对多的关系,反过来说学生实体与班级实体 是多对⼀着么,用E-R图表示如下:

6.6.3 多对多(M:N)
  • ⼀个学⽣实体包含的属性有:真实姓名,学号,年龄,性别,入学时间

  • ⼀个课程实体包含的属性有:课程名

  • ⼀个学生可以选修改多门课程,一门课程也可以被多名学生选修改,所以学生与课程之间是多对多 关系,用E-R图表示如下:

  • 对于多对多关系,可以使用中间表进行记录,比如⼀个学生参加了某⼀门课程的考试得到了相应的 成绩,用E-R图表示如下:

练习:

sql 复制代码
# 设计表
-- ------------ 用户与账户的一对一关系 -----------
# 在用户实体中添加对账户实体的关联
drop table if exists users;
create table users(
  id bigint primary key auto_increment,
  name varchar(20) not null,
  nickname varchar(20),
  phone_num varchar(11),
  email varchar(50),
  genter tinyint(1),
  account_id bigint
);
​
drop table if exists account;
create table account(
  id bigint primary key auto_increment,
  username varchar(20) not null,
  password varchar(32) not null
);
​
# 在账户实体中添加对用户实体的关联
drop table if exists users;
create table users (
  id bigint primary key auto_increment,
  name varchar(20) not null, 
  nickname varchar(20),
  phone_num varchar(11), 
  email varchar(50),
  gender tinyint(1)
);
​
drop table if exists account;
create table account (
  id bigint primary key auto_increment,
  username varchar(20) not null,
  password varchar(32) not null,
  users_id bigint
);
​
-- ------------ 学生与班级的一对多关系 --------------
# 班级表
drop table if exists class;
create table class (
  id bigint primary key auto_increment,
  name varchar(20)
);
# 学生表
drop table if exists student;
create table student (
  id bigint primary key auto_increment,
  name varchar(20) not null, 
  sno varchar(10) not null,
  age int default 18,
  gender tinyint(1), 
  enroll_date date,
  class_id bigint
);
​
-- ------------- 学生、课程与成绩的多对多关系 ------------------
# 学生表
drop table if exists student;
create table student (
  id bigint primary key auto_increment,
  name varchar(20) not null, 
  sno varchar(10) not null,
  age int default 18,
  gender tinyint(1), 
  enroll_date date,
  class_id bigint,
  foreign key (class_id) references class(id)
);
# 课程表
drop table if exists course;
create table course (
  id bigint primary key auto_increment,
  name varchar(20)
);
# 分数表
drop table if exists score;
create table score (
  id bigint primary key auto_increment,
  score float,
  student_id bigint,
  course_id bigint,
  foreign key (student_id) references student(id),
  foreign key (course_id) references course(id)
);
相关推荐
Navicat中国19 小时前
利用 PostgreSQL 的强大力量:Supabase 简介
数据库·postgresql·navicat·supabase
天外来鹿20 小时前
Map/Set/WeakMap/WeakSet学习笔记
前端·javascript·笔记·学习
峥嵘life20 小时前
Android16 【GTS】 GtsDevicePolicyTestCases 测试存在Failed项
android·linux·学习
菩提小狗20 小时前
第23天:安全开发-PHP应用&后台模块&Session&Cookie&Toke_笔记|小迪安全2023-2024|web安全|渗透测试|
笔记·安全·php
yqzyy20 小时前
Redis 设置密码无效问题解决
数据库·redis·缓存
HuDie34020 小时前
黑马多模态AIGC课程笔记
笔记·aigc
leixj02520 小时前
SVN学习笔记
笔记·学习·svn
huangliang070320 小时前
oracle使用模版创建分区表
数据库·oracle
江不清丶20 小时前
Kafka消息积压排查与治理:从应急处理到长期优化
数据库·kafka·linq
毕设源码_廖学姐21 小时前
计算机毕业设计springboot古诗词学习App 基于SpringBoot的中华经典诗文数字化研习平台 SpringBoot框架下的传统诗词文化移动学习系统
spring boot·学习·课程设计