IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> sql sever 三范式 -> 正文阅读

[大数据]sql sever 三范式


提示:以下是本篇文章正文内容,下面案例可供参考

数据库范式分为第一范式(1NF),第二范式(2NF),第三范式(3NF)

一、第一范式

是对属性的原子性,要求属性具有原子性,不可再分解
什么是原子性?在化学上讲原子是不可再分的

举个例子:

use test
create table Student--学生表
(
StudId varchar(20) primary key,--学号
StuName varchar(20) not null,--学生姓名
StuContact varchar(50) not null,--联系方式
)
insert into Student(StudId,StuName,StuContact)
values(1,'张三','QQ:12345,Tel:138********')

select * from Student

在这里插入图片描述
如果哪天我想根据QQ来查找人怎么办?你联系方式里可不止QQ一个信息啊,就非常麻烦了。

所以根据第一范式的原子性,我们将代码修改一下——把联系方式拆分成联系电话和联系QQ

create table Student--学生表
(
StudId varchar(20) primary key,--学号
StuName varchar(20) not null,--学生姓名
Tel varchar(50) not null,--联系电话
QQ varchar(20) not null --联系QQ
)

这样子,将来如果需要对联系QQ进行查找人,就很方便了。

二、第二范式

是对记录的唯一性,要求记录有唯一标识,也就是实体的唯一性,即不存在部分依赖。
什么叫作实体的唯一性?
比如我们这里创建的学生表,就有实体的唯一性:

create table Student--学生表
(
StudId varchar(20) primary key,--学号
StuName varchar(20) not null,--学生姓名
Tel varchar(50) not null,--联系电话
QQ varchar(20) not null --联系QQ
)
insert into Student(StudId,StuName,Tel,QQ)
values(1,'张三','Tel:138********','QQ:12345')

select * from Student

在这里插入图片描述
我们查找到的信息,一个StuId可以唯一标识一行,是可以代表一个学生的,
如果到了第二行,又会是另一个学生,这就是唯一性

那什么时候我们实体的唯一性会被打破?
比如下面的代码:

create table StudentCourse
(
StuId varchar(20),--学号
StuName varchar(20) not null,--学生姓名
CourseId varchar(20) not null,--课程号
CourseName varchar(20) not null,--选课名称
CourseScore int not null--考试成绩
)
insert into StudentCourse(StuId,StuName,CourseId,CourseName,CourseScore)
values('1','张三','01','语文',90)

insert into StudentCourse(StuId,StuName,CourseId,CourseName,CourseScore)
values('1','张三','02','数学',87)

insert into StudentCourse(StuId,StuName,CourseId,CourseName,CourseScore)
values('2','李四','03','英语',91)

insert into StudentCourse(StuId,StuName,CourseId,CourseName,CourseScore)
values('3','王五','03','英语',95)

select * from StudentCourse

我们看看:一人选了两门课,和一门课被两个人选了是什么效果
在这里插入图片描述
在第一行出现了“张三”,第二行又出现了“张三”,这并没有保证学生的唯一性
另外,图中三四行的英语,也出来了两次,也是没有保证课程的唯一性。
没有保证唯一性就会出现数据上的冗余。比如张三,你明明可以把他选的语文和数学放一起,你却没有这么做,你让张三这条信息多出现了一次,这就是冗余。

上述设计中有两个事物,一个学生信息,一个课程信息,很显然这两个事物都没有保证实体的唯一性,这里的姓名依赖学号,课程名依赖课程编号,所以不符合二范式。,你不符合第二范式就会出现一系列的问题,
问题1:你英语可能有很多人选吧,这些人中又很有可能选了别的课,你这样一个课一个课,那个人名的信息就很冗余了,一个人对应那么多信息。
问题2:对数据的维护(比如增删查改),比如我现在增加一个学生,因为现在这个表既保存学生信息也保存课程信息,如果我现在有一个学生信息要添加,但是他还没有选课,你怎么加?我现在课程那些又是not null不能为空的,怎么办?

所以我们上面很粗暴的用一张表把信息存储起来很不规范,不符合第二范式,我们来改进一下代码:

create table Course(--课程
	CourseId int primary key identity(1,1),--课程编号
	CourseName varchar(30) not null,--课程名称
	CourseContent text--课程介绍
)

insert into Course(CourseName,CourseContent) values('HTML','静态网页制作')
insert into Course(CourseName,CourseContent) values('winForm','Windows应用程序开发')


create table Student(--学生表
   StuId int primary key identity,--学生编号
   StuName varchar(50) not null,--学生姓名
   StuSex char(2) not null--学生性别
)
insert into Student(StuName,StuSex) values('张三','男')
insert into Student(StuName,StuSex) values('李四','女')

create Table Exam(
ExamId int primary key identity(1,1),--选课编号
StuId int not null,--学生编号
CourseId int not null,--课程编号
Score int not null--考试分数
)
insert into Exam(StuId,CourseId,Score) values(1,1,90)--学号为1的人,选了课程1考了90分
insert into Exam(StuId,CourseId,Score) values(1,2,80)
insert into Exam(StuId,CourseId,Score) values(2,1,95)
insert into Exam(StuId,CourseId,Score) values(2,2,90)

select * from Course
select * from Student
select * from Exam

按照上面的代码进行建表就不会出现数据的冗余,同样的数据不会出现多次了
并且这种优化方案,对于数据的维护,比如你要修改课程信息,你只要维护Course表即可

在这里插入图片描述
唯一麻烦的就是查询,比如我要找张三考了多少分,现在数据少好像你在 Exam表里面找找也能出来,但是数据多就比较麻烦,所以是建议用连接查询。

select * from Student 
inner join Exam on Student.StuId=Exam.StuId
inner join Course on Course.CourseId=Exam.CourseId

在这里插入图片描述

三、第三范式

在2NF的基础上,任何的非主属性不依赖于其他非主属性 (在第二范式基础上消除传递依赖)

举个例子

create table Student(--学生表
   StuId varchar(10) primary key ,--学生编号
   StuName varchar(50) not null,--学生姓名
   ProfessionName varchar(50),--专业名称
   ProfessionRemark varchar(20)--专业介绍
)
insert into Student(StuId,StuName,ProfessionName,ProfessionRemark)
values('1','张三','计算机科学与技术','牛逼牛逼')
insert into Student(StuId,StuName,ProfessionName,ProfessionRemark) 
values('2','李四','软件工程','也很牛逼')
insert into Student(StuId,StuName,ProfessionName,ProfessionRemark)
values('3','王五','计算机科学与技术','牛逼牛逼')

select * from Student

上面创建的学生表中,学生编号和学生姓名是直接依赖关系的,但是学生编号和专业介绍却是间接依赖的,什么意思?就是你可以通过学生编号找到他的专业名称,也就是学生编号和专业名称直接依赖。
然后通过专业名称确定专业介绍,专业名称和专业介绍直接依赖。
这种z=f(y),y=f(x),即z依赖y,y依赖x。就可以说z间接依赖x
第三范式要求没有这种间接依赖

我们再来看这种不符合第三范式表的缺陷是什么?
在这里插入图片描述
现在是数据少的情况。假设计算机科学与技术有1000名学生,然后专业描述有1000字,你这1000*1000得有多少冗余数据啊(同样专业描述只需要有一个就行了)。

改进方法:和第二范式改进一样——拆表

create table Professional(
  ProfessionalId int primary key identity(1,1),--专业编号
  ProfessionalName varchar(50),--专业名称
  ProfessionalRemark varchar(200)--专业介绍
)

create table Student(--学生表
   StuId varchar(10) primary key ,--学生编号
   StuName varchar(50) not null,--学生姓名
   ProfessionName varchar(50),--专业名称
)

insert into Professional(ProfessionalName,ProfessionalRemark) values('计算机科学与技术','小母牛蒸桑拿')
insert into Professional(ProfessionalName,ProfessionalRemark) values('软件工程','小母牛抽大烟')

insert into Student(StuId,StuName,ProfessionName)
values('1','张三','计算机科学与技术')
insert into Student(StuId,StuName,ProfessionName) 
values('2','李四','软件工程')
insert into Student(StuId,StuName,ProfessionName)
values('3','王五','计算机科学与技术')

select * from Professional
select * from Student

这样看,之前的数据冗余就消失了

在这里插入图片描述

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 19:02:54  更:2022-05-21 19:05:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:19:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码