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

【MySQL】(7) 数据库设计

一、范式

1、范式的简介

        范式就是数据库设计的规范,满足的范式越多,数据库冗余越小。范式一共有六种,但在实际开发中满足:第一、第二、第三范式即可,因为满足过多的范式,细分的表越多,查询时需要连接的表越多,导致查询效率降低,数据库设计的难度也加大。实际上根据业务需求也会反范式化,让经常一起查询的数据冗余存储在同一个表中。

2、第一范式

2.1、定义

        数据表的列不可再分,即能用 MySQL 中的基本数据类型定义。满足第一范式是关系型数据库的基本要求

2.2、反例

2.3、修改

3、第二范式

3.1、定义

        在第一范式的基础上,不存在非关键字段候选键部分函数依赖。候选键就是可以唯一标识数据行的列(可以选作主键)或多个列(可以选做复合主键,里面的所有列都是候选键)。部分函数依赖某些非关键字段只依赖部分候选键,与其它候选键无关系)存在于有复合主键的表中。

3.2、反例

记录学生在某门考试中的分数。

        该表中,成绩通过学号+课程名确定,主键可以设计为 (学号,课程名) 复合主键,可能不满足第二范式。学生信息:学生姓名、年龄、性别只依赖学号学分只依赖课程名确定,即存在部分函数依赖,不满足第二范式。

3.3、修改

        解决部分函数依赖,给学生、课程实体分别单独建立表,学生、课程之间存在的关系(学生课程成绩)也单独用表进行描述:

3.4、不满足第二范式可能存在的问题

  • 产生大量数据冗余,如案例中的学生信息、课程学分:

  • 更新异常,如给MySQL修改学分,就要修改表中的所有MySQL记录:

  • 插入异常:学分、成绩与学生有关系,意味着只有学生获得成绩后才能添加课程的学分信息。但这不符合常理,一门课在考试前就是存在的。
  • 删除异常:把所有毕业生的成绩删除,若全部学生毕业,课程的信息也跟着被清空了。

4、第三范式

4.1、定义

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

4.2、反例

        记录学生信息,包含学生所在的学院信息:

        该表中 id 是主键,学号、姓名、年龄、性别与 id 强相关,学院电话、地址与学院强相关,该表中存在两个强相关关系。且这两个强相关关系间存在传递依赖,即可通过 id 找到学生信息,学生信息又包含学院信息。

4.3、修改

        把学院信息从学生表中拆分出来,再将学生表与学院表建立关系

二、设计过程

  • 从业务中抽象出概念类(需求分析),即定义实体(数据库设计),如教务系统中:

  • 定义实体之间的关系,画 E-R 图,便于设计人员与非专业人士沟通。
  • 根据 E-R 图编写 SQL 语句,定义属性的数据类型、约束,创建数据库。

三、实体-关系图

1、三种基本成分

        实体(方框)、属性(椭圆)、关系(菱形)。

2、一对一关系

        分别创建实体对应的表,再在其中一个表中加关联字段(另一个表的主键或唯一键)。如账号表-用户表:

3、一对多关系

        分别创建实体对应的表,再在多方表(从表)中加入对一方表(主表)得关联字段(不能在多方表加,因为加了就是不同班级有一个学生数组,mysql中没有这种数据类型,且不满足第一范式要求)。如一个班级有多个学生:

4、多对多关系

        分别创建实体对应的表,再创建一个关系表,建立两个实体表的联系。如一个学生有多门课成绩,一门课有多个学生考试:

四、编写 SQL 语句

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
);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),account_id bigint  # 在用户实体中添加对账户实体的关联
);

2、一对多,班级 -- 学生

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,  # 在多方表建立对一方表的关联foreign key (class_id) references class(id)
);

3、多对多,学生、课程、成绩

# 课程表
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 里右击创建好的数据库,点击逆向数据库到模型,可根据数据库逆向生成 E-R 图,但是收费。我们使用官方的 Workbench:Database >> Reverse Engineer >> next >> 选需要逆向生成的数据库:

        选择需要生成的表:

        根据外键关联只自动生成了一对多的关系,我们需要手动建立其它关系:

http://www.xdnf.cn/news/1334.html

相关文章:

  • 【集合】底层原理实现及各集合之间的区别
  • 数据库操作
  • 遥感生物多样性产品
  • 【LLM】Ollama:容器化并加载本地 GGUF 模型
  • Agent系统工程实践:Langchain-Chatchat框架定制与优化
  • 计算机视觉算法实现——垃圾分类系统
  • 理解RAG第六部分:有效的检索优化
  • C++异步操作 - future async package_task promise
  • Java学习手册:RESTful API 设计原则
  • AI日报 - 2025年4月23日
  • css3新特性第六章(2D变换)
  • 使用Python+OpenCV将多级嵌套文件夹下的视频文件抽帧为JPG图片
  • 创建表结构
  • 树莓派超全系列教程文档--(39)树莓派config.txt旧版选项
  • 线程同步——线程安全
  • jQuery — 总结
  • 逻辑思维与软件开发:从选定方向到风险管理的全流程
  • BeeWorks:低成本的国产化企业内网即时通讯
  • 使用Multipart Form-Data一次请求获取多张图片
  • Linux网络IP协议
  • 【ROS2】ROS2 插件开发流程(基于 pluginlib)
  • 2023蓝帽杯初赛内存取证-4
  • 数据结构-树
  • 美乐迪电玩客户端打包与资源替换实战教程
  • Shader属性讲解+Cg语言讲解
  • pda数据采集器,是如何采集数据的?
  • Docker底层原理浅析 | namespace+cgroups+文件系统
  • windows搭建xwiki17服务器
  • C++——多态、抽象类和接口
  • 鸿道操作系统Type 1虚拟化:破局AI机器人与智能汽车的“安全”与“算力”双刃剑