MySQL —— 表的设计

表的设计

在设计表之前,我们需要从需求中获得实体(实体就是一张张表),实体的属性就是表中的字段(列),然后确定实体与实体之间的关系,最后使用 SQL 语句去创建具体的表

在设计表的时候我们会遵守一些规则,这些规则叫做三大范式(范式是描述数据关系的模型),下面我们来了解一下三大范式。

第一范式

第一范式是关系型数据库的一个基本要求,如果不满足第一范式就不是关系型数据库。

第一范式要求表里的字段不能继续拆分

举个例子:
我们定义一个学生表,但是你只是给了一个字段——学生,可是这个学生范围很广泛,有学生的姓名,性别,年龄,班级,学号等等,说明学生这个字段是可以拆分的,所以你最开始定义的表是不符合第一范式的。

如果一张表里的所有的字段都无法拆分那就满足第一方式,还是学生表为例子:现在创建了学号,姓名,性别,年龄这四个字段组成学生表那就符合第一范式,因为每一个字段都是不可分的。

在定义表的时候,对照数据中的数据类型,将每一个字段都可以用一个数据类型表示,那么当前这个表就天然满足第一范式

第二范式

第二范式在满足第一范式的基础上,存在于复合主键的情况下,不存在非关键字段对任意候选键的部分函数依赖

简单来说,对于由两个或者多个关键字段(即复合主键)决定一条记录的情况的时候,如果一行数据中非主键的字段与复合主键的部分字段存在关系,就说明存在部分函数依赖,不满足第二范式

现在举个例子:
假设我有一张学生成绩表,表里有一下这些字段:
在这里插入图片描述

这张表设计是存在问题的,首先我们可以假设将学号设置为主键,然后通过学号我们是可以确定这个学生的姓名性别年龄以及班级的,但是再往后看,我们会发现通过课程名称我们应该是可以找到课程的学分,这时候这个课程的成绩到底是由什么决定的,那应该就是学生和课程共同决定的(学生参加这个课程的考试之后就会有成绩),那这时候我们就可以将学号和课程名称定义为复合主键,在这张表中姓名和课程学分就是非关键字段,但是却与候选键发生了函数依赖(也就是存在关系),那么就会违反第二范式。

以上面的学生成绩表为例:
将表进行拆分,学生表(学生学号,姓名,性别,年龄与班级),课程表(课程编号、名称,课程学分),还有一张课程成绩表(学号,课程编号,成绩)。

如果一张表没有复合主键,那么这张表一定满足第二范式。

如果不满足第二范式有什么后果?

  1. 造成数据冗余:就像上面的表,本来我需要查看的是学生考了多少分,但是你还告诉我学生的性别,年龄,班级甚至课程学分我都不想知道,这就是数据冗余,并且很浪费空间,应该让每一张表都有自己特定的数据进行保存,而不是全部塞进去
  2. 更新可能会出现异常:假设你要修改课程对应的学分,那你是不是要把每一个都有这个课程的数据行都要进行修改,不仅费时费力,万一数据库服务器突然坏了一秒钟,你之前更新的数据还不一定会保存下来。
  3. 插入异常,如果你要新增一门新课程,那你怎么往这张表插入数据,设计表的时候有些列不能为空的,那你是不是还要伪造哪些空数据,或者你等到有人考了这门成绩出来以后再加入数据库中(黄瓜菜都凉了)。
  4. 删除异常:假设所有参加 JavaEE 课程的同学都毕业了,但是JavaEE 的新学生还没这么快考试,那你如果删除这些毕业的人的数据的时候,也就连JavaEE 的课程信息也删除了。

如何避免第二范式:
在设计复合主键的时候,一定要考虑清楚其他字段会不会与复合存在部分函数联系。

第三范式

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

以下面的学生表为例:
在这里插入图片描述

这张表主键定义为学号,但是我们可以 从学号得知学院名称 再得知学院的地址和电话,由于学院名称是非关键字段,所以存在了传递关系。

那该如何设计这张学生表?
设计成两张表,一个学院表(学院编号,学院名称,学院电话,学院地址)
一张学生表(学号,姓名,学院编号)设计成主外键键关系即可。

表的关系

一对一

举个例子:一个中国公民只有一个身份证

如何设计表:
创建两张表,分别记录中国公民的个人信息(姓名,电话,现居地址),身份证信息(身份证号,姓名,年龄,性别)
然后我们可以再公民表中设计一个外键(身份证号)。

create table idcard(id bigint primary key comment '身份证号',name varchar(20) not null comment '姓名',gender varchar(1) not null comment '性别',age int not null comment '年龄'
);create table person(id bigint primary key auto_increment comment '编号',name varchar(20) not null comment '姓名',address varchar(100) comment '现居地址',foreign key (id) references idcard(id)
);

一对多(多对一)

举例:一个班级存在很多个学生,这是一对多的关系
同理,很多个学生都在一个班级,这是多对一的关系

如何设计表:
还是一样,先创建不同的实体表,再去建立联系

演示:创建班级表(班级编号,班级人数)
再创建学生表(学生学号,姓名,年龄,所属班级)
最后确定关系,我们可以在学生表添加一个班级外键:

create table class(id bigint primary key comment '班级编号',num int comment '人数'
);create table student (id bigint primary key auto_increment comment '学生学号',name varchar(50) not null comment '姓名',age int comment '年龄',foreign key (id) references class(id)
);

多对多

举个例子:学生与课程的关系,一个学生可以选择很多个课程,一个课程同时也可以包含很多个学生。

如何设计?
首先分别创建好实体表,一张学生表(学生学号,姓名,年龄) 一张课程表(课程编号,课程名称,课程学分)
然后确定关系发现是多对多,那就再创建一张表——关系表(关系表自身的编号,学生学号,课程编号)

create table student (id bigint primary key auto_increment comment '学生学号',name varchar(50) not null comment '姓名',age int comment '年龄'
);create table course(id bigint primary key auto_increment comment '课程编号',name varchar(20) not null comment '课程名称',score decimal(2,1) comment '学分'
);create table student_course (id bigint primary key comment '自身编号',student_id bigint not null comment '学生学号',course_id bigint not null comment '课程编号',foreign key (student_id) references student(id),foreign key (course_id) references course(id)
);

我们还可以在这张关系表中添加一个成绩的字段。

没有关系

对于没有关系的表,我们直接设计即可,不需要考虑其与其他的关系(因为本来就没有关系)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394934.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity Console 窗口输出对齐

起因:做了个工具在console窗口罗列一些信息,基本结构是 [ 文件名 :行号 ],因为文件,行号长度不一,想要做到如下效果。 初步尝试,用以下方法: string format "{0,-10} …

python自动化笔记:配置文件.ini及yml文件

目录 一、.ini配置文件1.1、ini编写格式1.2、读取.ini配置文件的数据1.3、编辑:写入和删除(了解即可) 二、yaml文件2.1、yaml编写语法规则2.2、yaml三种数据结构2.3、yaml文件的读取和写入 一、.ini配置文件 后缀名.ini 用于存储项目全局配置…

[独家原创] CPO-RBF多特征分类预测 优化宽度+中心值+连接权值 (多输入单输出)Matlab代码

[独家原创] CPO-RBF多特征分类预测 优化宽度中心值连接权值 (多输入单输出)Matlab代码 目录 [独家原创] CPO-RBF多特征分类预测 优化宽度中心值连接权值 (多输入单输出)Matlab代码效果一览基本介绍程序设计参考资料 效果一览 基本…

java学习day016

API 1.Number 数字格式化 : # 任意数字,0-9任意单个数字 , 千分位 . 小数点 0 补位 //四位小数 DecimalFormat df new DecimalFormat("###,###.####"); System.out.println(df.format(1234567.312));//1,234,567.312 //四位小数,不够补0 df new Deci…

前缀和处理数组区间之和问题

1.什么是区间和问题 “区间和问题”通常指的是涉及计算或处理数组或数列某个子区间(即一段连续元素)的总和的类型问题。这类问题可能有多种变体和不同的复杂度,但基本思想都是在给定的区间内快速计算总和或处理与区间和相关的操作。 2.例题…

常见的框架漏洞

ThinkPHP 首先我们打开一个环境 然后进行远程命令执行代码 然后进行远程代码执行 ?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]-1 在网页中输出phpinfo getshell ?sindex/think\app/invokefunction&function…

c语言基础知识

ASCII码 字符A~Z的ASCII码值从65~90 • 字符a~z的ASCII码值从97~122 • 对应的⼤⼩写字符(a和A)的ASCII码值的差值是32 • 数字字符0~9的ASCII码值从48~57 • 换⾏ \n 的ASCII值是:10 • 在这些字符中ASCII码值从0~31这32个字符是不可打印字符,⽆法打印在…

sql实战cmseasy

环境搭建 这里我们用phpstady搭建 版本是cmseasy5.5 未授权访问 这里ip的方法获取客户端的ip 这里的意思是当你的server ip等于 客户端ip并且get传参 get(ishtml)1的情况下他会直接return 他就不会检查后面是不是admin,而他这个IP是从X_FORWARDED_FOR获取&…

Spring Boot 3.x Rest API统一异常处理最佳实践

上一篇:Spring Boot 3.x Rest API最佳实践之统一响应结构 在Spring MVC应用中,要对web表示层所抛出的异常进行捕获处理有多种方式,具体的可参考著名国外Spring技术实战网站baeldung上的相关话题。Spring Boot对Spring MVC应用中抛出的异常以…

RNN循环网络层

文章目录 1、简介2、RNN 网络原理3、PyTorch RNN 层的使用3.1、RNN送入单个数据3.2、RNN层送入批量数据 4、RNN三个维度4.1、解释4.2、输入数据的组织4.3、示例4.4、为什么需要这种格式?4.5、小结 🍃作者介绍:双非本科大三网络工程专业在读&a…

苹果手机数据被抹除还能恢复吗?这两个方法强烈推荐

苹果手机数据被抹除还能恢复吗?我们在使用苹果手机时,有时由于误操作、系统故障或升级失败等原因,导致手机照片、备忘录、视频、联系人等数据被意外抹除。 面对这类情况,我们应该怎么办?下面牛小编给大家的分享2个方法…

记录使用FlinkSql进行实时工作流开发

使用FlinkSql进行实时工作流开发 引言Flink SQL实战常用的Connector1. MySQL-CDC 连接器配置2. Kafka 连接器配置3. JDBC 连接器配置4. RabbitMQ 连接器配置5. REST Lookup 连接器配置6. HDFS 连接器配置 FlinkSql数据类型1. 基本数据类型2. 字符串数据类型3. 日期和时间数据类…

论文解读,神经网络全梯度表示《Full-Gradient Representation for Neural Network Visualization》

导语 这篇论文介绍了一种新的工具,称为全梯度,用于解释神经网络的响应。这个全梯度的概念将神经网络的响应分解为两个部分:输入灵敏度和每个神经元的灵敏度分量。 输入灵敏度:输入灵敏度指的是对于神经网络输出的影响程度。它反…

Python试讲

Python试讲 导语Python简介Python及其特点如何使用Python Python与计算计算变量 导语 本次试讲内容如下:Python简介与使用,Python与基本运算 辅助教材为 《趣学Python编程》和《Python编程从入门到实践》 Python简介 Python是目前入门最简单最好学的…

NSSCTF练习记录:[SWPUCTF 2021 新生赛]jicao

题目: 这段PHP代码的意思是: 对index.php文件进行语法高亮显示,插入flag.php文件,变量id的值为POST传递的值,变量json的值为GET传递的json类型的值。当id值为wllmNB且json中含有键为“x”,值为“wllm”的时…

数据结构:栈与队列OJ题

目录 前言 一、用栈实现队列 二、用队列实现栈 三、括号匹配问题 前言 前面讲了栈和队列的基础知识,今天来巩固一下加深理解,这里说明一下,因为现在都是在用C语言写,这些OJ题里都要用到前面实现栈和队列的代码,每道题…

告别数据丢失烦恼,转转数据恢复和另外三款工具助你一臂之力!

不知道大伙儿有没有和我一样,到哪都喜欢拍照片和视频,加上办公上也是七七八八的各种格式的文件实在是多,所以电脑和手机等等设备上经常内存爆满需要清理,难免会出现不小心误删或者格式化、清空等等的情况,用过几款和转…

Journyx项目管理软件 soap_cgi.pyc XXE漏洞复现

0x01 产品简介 Journyx-Journyx成立于1996年,提供自托管项目管理解决方案ProjectXecute。主要功能包括资源跟踪、待办事项列表、任务分配以及与MS Project的集成。要运行ProjectXecute,需要Windows 2003或更高版本、IIS Web服务器和Intel处理器。也可以在Linux、Solaris、AI…

#子传父父传子props和emits #封装的table #vue3

#子传父&父传子props和emits #封装的table #vue3 父组件&#xff1a;emits defineEmits props 子组件&#xff1a; 子组件 <template><el-table v-bind"$attrs" ref"innerTableRef" v-loading"loading" border :data"tabl…

力扣刷题-轮转数组

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 首先&#xff0c;我们现在这里提供的是一种特别简单的思路&#xff0c;我们先来看一下这段代码&#xff1a; void rotate(int* nums, int numsSize, int k) {k%numsSize;int n…