首页 > 数据库 >MySQL初学之旅(4)表的设计

MySQL初学之旅(4)表的设计

时间:2024-11-22 17:13:44浏览次数:3  
标签:范式 score 之旅 主键 初学 student MySQL 学生 id


目录

1.前言

2.正文

2.1第一范式

2.2第二范式

2.3第三范式

2.4表的设计方法

3.小结


1.前言

哈喽大家好吖,今天继续给大家分享MySQL的学习——表的设计,这一部分没有太多语法的讲解,有许多设计思路以及规则的讲解与剖析,那么话不多说让我们开始吧。

2.正文

表的设计的核心就是三大范式,在了解核心三大范式之前,让我们先知道范式是什么:

范式(Normal Form)是一套理论规范,用于组织数据库中的数据,旨在减少数据冗余并确保数据的一致性和完整性。范式通过一系列规则指导数据库设计,以避免常见的设计问题(如重复数据、插入异常、更新异常等)。

范式的目标:

  • 减少数据冗余: 避免重复存储相同信息。
  • 消除插入、删除、更新异常: 确保数据的逻辑一致性。
  • 提高数据完整性: 避免由于设计问题导致的错误数据。
  • 便于扩展和维护: 数据库结构清晰,便于修改和扩展。

下文每一条细讲的时候会逐个说明违反哪个原则会出现那种后果

2.1第一范式

先上定义:

  • 原子性: 表中的每一列都只能包含单一值,而不能包含集合、列表或其他复杂结构。
  • 表结构规范化: 每一列的数据类型必须一致。

让我们放到实例中讲解,我们本文均以学生为背景来讲解,假设我们现在要为建一个学生表,那么它包含的信息就应该有:

  • 姓名,id,年龄,学校等信息

当我们在建表的时候就会发现:

CREATE table student(
id BIGINT,
name varchar(50),
school 

school这个变量里没有适合它的数据类型,学校可以包括学校的名字,学校的地址,学校的电话等,即学校这个这个字段可以进行拆分,那么这就违反了建表的第一范式。遇到这种情况我们会选择额外建立一张学校表来处理。

还有一种情况不符合,即在创建表时,该字段会被填入俩个及以上数据时,这样也违反了第一范式,一般遇到这种情况,我们可以将一行数据变成俩行,分开存储。

2.2第二范式

定义:

  • 前提条件: 表必须满足第一范式(1NF)。
  • 要求: 所有非主键字段必须完全依赖于主键,不能对主键产生部分依赖。

区分一下什么叫完全依赖,什么叫部分依赖:

  • 部分依赖: 如果一个非主键字段只依赖于主键的一部分,而不是整个主键,就称为部分依赖。
  • 完全依赖: 如果一个非主键字段依赖于主键的全部字段,则称为完全依赖。

看着定义又是完全又是部分,那么到底是什么意思呢,举个例子大家就懂咯:
假设我们现在创建一个有关学生选修课的表:

CREATE table student(
id BIGINT,
name varchar(50),
subject VARCHAR(50),--学科
credit BIGINT,--学分
score BIGINT--成绩
);

我们乍看这张表没有问题,包含信息还比较完整,但当我们仔细观察,发现学分这一列只会跟随学科的变化而变化,不会随着学生的变化而变化。那么也就说明当我们在插入足够多的数据的时候,可以想象,有一列完全一样的学科对应着一列完全相同的学分,这样就造成了数据的冗余,这也是违背了第二范式即所有非主键字段必须完全依赖于主键。

所以我们在解决这个问题采用分开建表的方式,分别可以建立三张表:

  • 一个为学生基础信息表。
  • 另一个为课程学分表。
  • 还有一个单独储存成绩的表,因为成绩既和学生有关,又和学科有关,所以放在哪个表中都不合适,所以单独建表。

我们再来专门分析一下如果违反了第二范式会导致什么后果:

  • 数据冗余: 每次记录学生学分名都会重复存储。
  • 更新异常: 修改一个学生的姓名或课程信息时,需要更新多条记录,如果中间更新中断,我们无法确定哪一部分数据已更新,哪一部分数据未更新,会造成数据不一致。
  • 插入异常: 如果课程尚未被选,则无法记录课程信息。既如果新加一个课程,但并没有考试成绩,会导致此时部分空没有意义。
  • 删除异常: 删除某学生的选课记录后,课程信息也会丢失。既某些课程的学分信息被一并删去,且直到下一次再插入数据时均没有该信息,信息会短暂丢失。

以上都是违背了第二范式导致设计不合理的后果,应该严格去遵守这个原则。

2.3第三范式

定义:

  • 前提条件: 表必须满足第二范式(2NF)。
  • 要求: 非主键字段必须直接依赖于主键,而不能通过其他非主键字段间接依赖于主键(即,消除传递依赖)。

我们再来明确一下什么是传递依赖:

  • 如果一个非主键字段依赖于另一个非主键字段,而这个非主键字段又依赖于主键,那么就存在传递依赖。

继续举例子详细讲解,假设我们现在这样创建一个表:

学生ID学生姓名专业ID专业名称专业院长
1张三101计算机王教授
2李四102数学李教授

主键:

  • 主键是学生ID

问题:

  • 专业名称专业院长依赖于专业ID,而专业ID又依赖于主键学生ID
  • 这意味着专业名称专业院长并非直接依赖主键,而是通过专业ID间接依赖于主键,存在传递依赖。

处理方法就是将其拆成俩张表:

学生表:

学生ID学生姓名专业ID
1张三101
2李四102

专业表:

专业ID专业名称专业院长
101计算机王教授
102数学李教授

这样就可以避免问题。

2.4表的设计方法

我们了解完何为三大范式后,我们就要明白建表的流程了:

  1. 先从需求中得到类,类对应数据库中的实体。
  2. 实体在数据库中表现为一张一张的表。
  3. 类的属性对应表中多个字段。
  4. 确定类与类之间的关系。

确定类与类之间的关系很重要,类之间的关系有以下几种:

  1. 一对一的关系,例如一个学生对应一个学校
  2. 一对多的关系,一个班级包含许多个学生
  3. 多对多的关系,例如一个学生可以选修许多学科,某个学科也可以被许多学生选择。

讲完了三大范式与设计方法,接下来来一段实操应用一下:

背景:创建数张表,用于存储课程信息,学生信息,以及学生成绩信息。

代码:

create table student_message(
st_id bigint PRIMARY KEY auto_increment,
name varchar(20) not NULL
);

CREATE table subject(
su_id BIGINT PRIMARY KEY auto_increment,
name varchar(20) not null
);

CREATE table score(
score_id BIGINT PRIMARY KEY auto_increment,
student_id BIGINT,
subject_id BIGINT,
grade bigint,
foreign key (student_id) REFERENCES student_message (st_id),
foreign key (subject_id) REFERENCES subject (su_id)
);

查询这三张表的语句:

select * from score;
select * from student_message;
select * from subject;

我们尝试插入一些数据看看效果如何:

INSERT into student_message values(1,'alice');
INSERT into student_message values(2,'tom');
INSERT into student_message values(3,'jerry');

insert into subject (su_id,name) values(1,'math'),(2,'english'),(3,'chinese');

insert into score values (1,1,1,90);
insert into score values (2,2,2,80);
insert into score values (4,2,3,95);

再次查询,结果如下:

分析一下结果:

其中多对多 关系,通过中间表(score 表)实现:

  • 学生(student_message) 与 科目(subject) 之间是多对多关系。
    • 一个学生可以选修多门科目。
    • 一门科目可以被多个学生选修。
  • score 表 是关系的桥梁,记录了某个学生在某门科目上的成绩。

3.小结

今天的分享到这里就结束了,喜欢的小伙伴点点赞点点关注,你的支持就是对我最大的鼓励,大家加油!

标签:范式,score,之旅,主键,初学,student,MySQL,学生,id
From: https://blog.csdn.net/2301_81073317/article/details/143860888

相关文章

  • python+pymysql(16)
    python操作mysql一、python操作数据库1、下载pymysql库,方法一:pip3installpymysql或pipinstallpymysql方法二:在pycharm中setting下载pymysql===============================2、打开虚拟机上的数据库===============================3、pymysql连接(1)连接......
  • 初学STM32记录
    一、硬件准备1.物品采购(1)STM32F103C6T6最小系统板(2)STLink仿真器(一般会随机赠送几条母对母杜邦线,若没有请购买)(3)一台计算机2.线路连接(1)将STM32系统板的VCC3V3、SWDIO、SWDCLK、GND这几个端口通过杜邦线连接到仿真器对应端口。(2)调试时将仿真器USB接口插入......
  • Ubuntu 22.04 安装docker及部署mysql
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、查看Ubuntu内核版本二、安装docker前的环境准备1.更新系统软件包列表2.安装必要的依赖包添加Docker官方的GPG密钥添加Docker官方的软件源Ubuntu22.04Ubuntu20.04Ubuntu18.04再次更新......
  • python批量修改mysql中某个字段的长度
    突然被告知DB中某个关键字段长度要增大,涉及到N张表,改起来超麻烦,想着用代码改,比较少写这种增删表或者改变表结构的代码,记录下。importpymysqldefmodifyFieldVarcharLen(config,new_column_length):connection=pymysql.connect(**config)try:withconn......
  • 【MySQL主从复制】揭秘高效数据库架构,轻松应对大数据挑战!
    MySQL主从复制概述MySQL主从复制是一种数据复制技术,用于将一个MySQL数据库服务器(主库)的数据实时复制到一个或多个MySQL数据库服务器(从库)。这种机制常用于实现读写分离、负载均衡和数据备份等目的。主从复制的基本步骤配置主库:在主库上启用二进制日志,并创建一个具有复......
  • Python 初学者的学习指南:从入门到实践 ---亲身经历版本!!!
    前言Python因其简单易学、功能强大而成为初学者编程的首选语言。无论你是零基础的小白,还是想拓展技能的开发者,Python都能为你提供无限可能。本篇博客将为Python初学者提供一套学习方法和学习路线,帮助你在短时间内掌握Python编程的核心知识,并学以致用。学习方法明......
  • mysql一次性写入大量数据的时候报错
     修改mysql配置参数解释1、innodb_buffer_pool_size=8G作用: 这是InnoDB存储引擎用于缓存表和索引数据的内存区域大小。 数据库主要从内存中读取数据而非磁盘,因此该值越大,系统性能越好(特别是对于大数据量的场景)。初始值: MySQL5.7及以下:通常为128MB。 ......
  • 免费送源码:Java+django+MySQL django 教师培训反馈系统 计算机毕业设计原创定制
           目   录摘  要IAbstractII第1章  前  言31.1 研究背景31.2 研究现状31.3 系统开发目标3第2章  系统开发环境62.1HTTP协议62.2HTML网页技术62.3B/S结构62.4django脚本语言72.5MySQL数据库72.6Apache简介8第......
  • win10同时安装Mysql5和mysql8
    1.下载安装包,解压。 2.添加环境变量,导入各自的bin到系统变量Path中。    3.进入mysql5的安装目录,新建my.ini文件,粘贴信息,注意更改安装目录路径。1[mysql]2#设置mysql客户端默认字符集3default-character-set=utf84[mysqld]5#设置3305端口6po......
  • 炸裂,MySQL9.0创新版发布!功能又进化了!
    炸裂,MySQL9.0创新版发布!功能又进化了!原创 MySQL 作者:wddwr7307914 时间:2024-07-0210:44:58  976  0作者:IT邦德中国DBA联盟(ACDU)成员,10余年DBA工作经验,Oracle、PostgreSQLACECSDN博客专家及B站知名UP主,全网粉丝10万+擅长主流Oracle、MySQL、PG、高斯及Greenp......