1、为什么要设计数据库
当数据库比较复杂时,我们需要设计数据库。
糟糕的数据库设计:
-
数据冗余,浪费空间
-
数据库插入和删除都会麻烦、异常(屏蔽使用物理外键)
-
程序的性能差
良好的数据库设计:
-
节省内存空间
-
保证数据库的完整性
-
方便我们开发系统
软件开发中,关于数据库的设计:
-
分析需求:分析业务的需要处理的数据库的需求
-
概要设计:设计关系图E-R图
设计数据库的步骤:(个人博客)
-
收集信息,分析需求
-
用户表(用户的登录注销,用户的个人信息,写博客,创建分类)
-
分类表(文章分类,谁创建的)
-
文章表(文章的信息)
-
友链表(友链信息)
-
自定义表(系统信息,某个关键的字(例如标题不可能单独去建一张表),或者一些主字段) key:value
-
-
标识实体(把需求落地到每个字段)
-
标识实体之间的关系
-
写博客 user -->bolg
-
创建分类user -->category
-
关注user -->user
-
友链:links
-
2、 三大范式
为什么需要数据规范化
-
信息重复
-
更新异常
-
插入异常
-
删除异常
三大范式:
1.第一范式 - 1NF
遵循原子性,表中字段的数据,不可以再拆分
先看一个不符合第一范式的表结构,如下:
员工编码 | 姓名 | 年龄 |
---|---|---|
001 | 销售部小张 | 28 |
002 | 运营部小黄 | 25 |
003 | 技术部小高 | 22 |
在这一个表中的,姓名 字段下的数据是可以再进行拆分的,因此它不符合第一范式,那怎么样才符合第一范式呢?如下:
员工编码 | 部门 | 姓名 | 年龄 |
---|---|---|---|
001 | 销售部 | 小张 | 28 |
002 | 运营部 | 小黄 | 25 |
003 | 技术部 | 小高 | 22 |
2.第二范式 - 2NF
在满足第一范式的情况下,遵循唯一性,消除部分依赖。即,表中任意一个主键或任意一组联合主键,可以确定除该主键外的所有的非主键值。
再通俗点讲就是,一个表只能描述一件事情。
我们用一个经典案例进行解析。
学号 | 姓名 | 年龄 | 课程名称 | 成绩 | 学分 |
---|---|---|---|---|---|
001 | 小张 | 28 | 语文 | 90 | 3 |
001 | 小张 | 28 | 数学 | 90 | 2 |
002 | 小黄 | 25 | 语文 | 90 | 3 |
002 | 小黄 | 25 | 语文 | 90 | 3 |
003 | 小高 | 22 | 数学 | 90 | 2 |
我们先分析一下表结构。
-
假设学号是表中的唯一主键,那由学号就可以确定姓名和年龄了,但是却不能确定课程名称和成绩。
-
假设课程名称是表中的唯一主键,那由课程名称就可以确定学分了,但是却不能确定姓名、年龄和成绩。
-
虽然通过学号和课程名称的联合主键,可以确定除联合主键外的所有的非主键值,但是基于上述两个假设,也不符合第二范式的要求。
那我们应该如何调整表结构,让它能复合第二范式的要求呢?
我们可以基于上述的三种主键的可能,拆分成 3 张表,保证一张表只描述一件事情。
学生表 - 学号做主键
学号 | 姓名 | 年龄 |
---|---|---|
001 | 小张 | 28 |
002 | 小黄 | 25 |
003 | 小高 | 22 |
课程表 - 课程名称做主键
课程名称 | 学分 |
---|---|
语文 | 3 |
数学 | 2 |
成绩表 - 学号和课程名称做联合主键
学号 | 课程名称 | 成绩 |
---|---|---|
001 | 语文 | 90 |
001 | 数学 | 90 |
002 | 语文 | 90 |
002 | 语文 | 90 |
003 | 数学 | 90 |
3.第三范式 - 3NF
在满足第二范式的情况下,消除传递依赖。即,在任一主键都可以确定所有非主键字段值的情况下,不能存在某非主键字段 A 可以获取 某非主键字段 B。
仍然用一个经典例子来解析
学号 | 姓名 | 班级 | 班主任 |
---|---|---|---|
001 | 小黄 | 一年级(1)班 | 高老师 |
这个表中,学号是主键,它可以唯一确定姓名、班级、班主任,符合了第二范式,但是在非主键字段中,我们也可以通过班级推导出该班级的班主任,所以它是不符合第三范式的。
那怎么设计表结构,才是符合第三范式的呢?
学生表
学号 | 姓名 | 班级 |
---|---|---|
001 | 小黄 | 一年级(1)班 |
班级表
班级 | 班主任 |
---|---|
一年级(1)班 | 高老师 |
通过把班级与班主任的映射关系另外做成一张映射表,我们就成功地消除了表中的传递依赖了。
总结(背):
第一范式 - 1NF:遵循原子性,表中字段的数据,不可以再拆分。
第二范式 - 2NF:每张表只做一件事。前提:满足第一范式 。
第三范式 - 3NF:确保数据表中每一列数据都和主键直接相关,而不能是间接相关。前提:满足第一范式 和第二范式。
规范性和性能的问题:
关联查询的表不能超过三张表
-
考虑商业化的需求和目标(成本和用户体验)数据库的性能更加重要
-
在规范性能的问题时,需要适当考虑规范性
-
故意给一些表增加一些冗余的字段(从多表查询变为单表查询)
-
故意增加一些计算列(从大数据量降低为小数据量的查询:索引)