MySQL —— 表的设计

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

表的设计

在设计表之前,我们需要从需求中获得实体(实体就是一张张表),实体的属性就是表中的字段(列),然后确定实体与实体之间的关系,最后使用 SQL 语句去创建具体的表
在设计表的时间我们会服从一些规则,这些规则叫做三大范式(范式是描述数据关系的模型),下面我们来了解一下三大范式。
第一范式

   第一范式是关系型数据库的一个基本要求,如果不满意第一范式就不是关系型数据库。
    第一范式要求表里的字段不能继承拆分
  举个例子:
我们界说一个学生表,但是你只是给了一个字段——学生,可是这个学生范围很广泛,有学生的姓名,性别,年事,班级,学号等等,说明学生这个字段是可以拆分的,以是你最开始界说的表是不符合第一范式的。
如果一张表里的全部的字段都无法拆分那就满意第一方式,还是学生表为例子:现在创建了学号,姓名,性别,年事这四个字段构成学生表那就符合第一范式,由于每一个字段都是不可分的。
在界说表的时间,对照数据中的数据类型,将每一个字段都可以用一个数据类型表示,那么当前这个表就天然满意第一范式
第二范式

   第二范式在满意第一范式的基础上,存在于复合主键的情况下,不存在非关键字段对任意候选键的部门函数依赖
    简单来说,对于由两个或者多个关键字段(即复合主键)决定一条记录的情况的时间,如果一行数据中非主键的字段与复合主键的部门字段存在关系,就说明存在部门函数依赖,不满意第二范式
  现在举个例子:
假设我有一张学生结果表,表里有一下这些字段:

这张表设计是存在问题的,起首我们可以假设将学号设置为主键,然后通过学号我们是可以确定这个学生的姓名性别年事以及班级的,但是再今后看,我们会发现通过课程名称我们应该是可以找到课程的学分,这时间这个课程的结果到底是由什么决定的,那应该就是学生和课程共同决定的(学生参加这个课程的测验之后就会有结果),那这时间我们就可以将学号和课程名称界说为复合主键,在这张表中姓名和课程学分就是非关键字段,但是却与候选键发生了函数依赖(也就是存在关系),那么就会违反第二范式。
以上面的学生结果表为例:
将表举行拆分,学生表(学生学号,姓名,性别,年事与班级),课程表(课程编号、名称,课程学分),尚有一张课程结果表(学号,课程编号,结果)。
   如果一张表没有复合主键,那么这张表一定满意第二范式。
  如果不满意第二范式有什么结果?

  • 造成数据冗余:就像上面的表,本来我需要检察的是学生考了多少分,但是你还告诉我学生的性别,年事,班级乃至课程学分我都不想知道,这就是数据冗余,并且很浪费空间,应该让每一张表都有本身特定的数据举行生存,而不是全部塞进去
  • 更新大概会出现非常:假设你要修改课程对应的学分,那你是不是要把每一个都有这个课程的数据行都要举行修改,不但费时费力,万一数据库服务器忽然坏了一秒钟,你之前更新的数据还不一定会生存下来。
  • 插入非常,如果你要新增一门新课程,那你怎么往这张表插入数据,设计表的时间有些列不能为空的,那你是不是还要伪造哪些空数据,或者你等到有人考了这门结果出来以后再加入数据库中(黄瓜菜都凉了)。
  • 删除非常:假设全部参加 JavaEE 课程的同学都毕业了,但是JavaEE 的新学生还没这么快测验,那你如果删除这些毕业的人的数据的时间,也就连JavaEE 的课程信息也删除了。
   怎样制止第二范式:
在设计复合主键的时间,一定要思量清晰其他字段会不会与复合存在部门函数联系。
  第三范式

   第三范式在第二范式的基础上,不存在非关键字段对任一候选键存在转达依赖。
  以下面的学生表为例:

这张表主键界说为学号,但是我们可以 从学号得知学院名称 再得知学院的地址和电话,由于学院名称是非关键字段,以是存在了转达关系。
那该怎样设计这张学生表?
设计成两张表,一个学院表(学院编号,学院名称,学院电话,学院地址)
一张学生表(学号,姓名,学院编号)设计成主外键键关系即可。
表的关系

一对一

举个例子:一个中国公民只有一个身份证
怎样设计表:
创建两张表,分别记录中国公民的个人信息(姓名,电话,现居地址),身份证信息(身份证号,姓名,年事,性别)
然后我们可以再公民表中设计一个外键(身份证号)。
  1. create table idcard(
  2.         id bigint primary key comment '身份证号',
  3.         name varchar(20) not null comment '姓名',
  4.         gender varchar(1) not null comment '性别',
  5.         age int not null comment '年龄'
  6. );
  7. create table person(
  8.         id bigint primary key auto_increment comment '编号',
  9.         name varchar(20) not null comment '姓名',
  10.         address varchar(100) comment '现居地址',
  11.         foreign key (id) references idcard(id)
  12. );
复制代码
一对多(多对一)

举例:一个班级存在许多个学生,这是一对多的关系
同理,许多个学生都在一个班级,这是多对一的关系
怎样设计表:
还是一样,先创建不同的实体表,再去建立联系
演示:创建班级表(班级编号,班级人数)
再创建学生表(学生学号,姓名,年事,所属班级)
最后确定关系,我们可以在学生表添加一个班级外键:
  1. create table class(
  2.         id bigint primary key comment '班级编号',
  3.         num int comment '人数'
  4. );
  5. create table student (
  6.         id bigint primary key auto_increment comment '学生学号',
  7.         name varchar(50) not null comment '姓名',
  8.         age int comment '年龄',
  9.         foreign key (id) references class(id)
  10. );
复制代码
多对多

举个例子:学生与课程的关系,一个学生可以选择许多个课程,一个课程同时也可以包含许多个学生。
怎样设计?
起首分别创建好实体表,一张学生表(学生学号,姓名,年事) 一张课程表(课程编号,课程名称,课程学分)
然后确定关系发现是多对多,那就再创建一张表——关系表(关系表自身的编号,学生学号,课程编号)
  1. create table student (
  2.         id bigint primary key auto_increment comment '学生学号',
  3.         name varchar(50) not null comment '姓名',
  4.         age int comment '年龄'
  5. );
  6. create table course(
  7.         id bigint primary key auto_increment comment '课程编号',
  8.         name varchar(20) not null comment '课程名称',
  9.         score decimal(2,1) comment '学分'
  10. );
  11. create table student_course (
  12.         id bigint primary key comment '自身编号',
  13.         student_id bigint not null comment '学生学号',
  14.         course_id bigint not null comment '课程编号',
  15.         foreign key (student_id) references student(id),
  16.         foreign key (course_id) references course(id)
  17. );
复制代码
我们还可以在这张关系表中添加一个结果的字段。
没有关系

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表