1. 数据库的设计


实现关系


  1. 一对多(多对一)
    实现方式 : ​​​在多的一方建立外键, 指向一的一方的主键​
  2. 多对多
    实现方式 : ​​​多对多关系实现需要借助第三张中间表. 中间表至少包含两个字段, 这两个字段作为第三张表的外键, 分别指向两张表的主键​
  3. 一对一
    实现方式 : ​​​一对一关系实现, 可以在任意一方添加唯一外键指向另一方的主键​

一对多:在多方加入一方的主键 作为外键
多对多:独立处联系,并将联系包含双方的主键和自己的属性

1.1 案例分析


数据库设计及规范 - MySQL_数据

-- 创建旅游线路分类表 tab_category
CREATE TABLE tab_category(
cid INT PRIMARY KEY AUTO_INCREMENT, -- 旅游线路分类主键
cname VARCHAR(100) NOT NULL UNIQUE -- 旅游线路分类名称
)

-- 创建旅游线路表 tab_route
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT,
rname VARCHAR(100) NOT NULL UNIQUE,
price DOUBLE,
rdate DATE, -- 上架时间
cid INT, -- 外键, 所属分类
FOREIGN KEY (cid) REFERENCES tab_category(cid)
)

-- 创建用户表 tab_user
CREATE TABLE tab_user(
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
PASSWORD VARCHAR(30) NOT NULL,
NAME VARCHAR(100),
birthday DATE,
sex CHAR(1) DEFAULT '男',
telephone VARCHAR(11),
email VARCHAR(100)
)

/*
创建收藏表 tab_favorite
rid 旅游线路id, 外键
date 收藏时间
uid 用户id, 外键
rid 和 uid不能重复, 设置复合主键, 同一个用户不能收藏同一个线路两次
*/
CREATE TABLE table_favorite(
rid INT,
DATA DATETIME,
uid INT,
-- 创建复合主键
PRIMARY KEY(rid, uid),
FOREIGN KEY (rid) REFERENCES tab_route(rid),
FOREIGN KEY (uid) REFERENCES tab_user(uid)
)

数据库设计及规范 - MySQL_主键_02

2. 数据库设计的范式


设计数据库时, 需要遵循一些规范. 要遵循后边的范式要求, 必须先遵循前边的所有范式要求
​​​数据库范式​

数据库设计及规范 - MySQL_数据_03


上面数据库设计不合理, 通过下面一步步的修改来设计合理的数据表.

2.1 第一范式(1NF)


每一列都是不可分割的原子数据项

数据库设计及规范 - MySQL_外键_04


如果不是原子数据项的话, 建表的列数据都无法创建.

存在的问题

  1. 严重的数据冗余
  2. 添加时存在问题, 无法添加特定的某一项, 而是需要把列数据全部添加
  3. 删除时存在问题, 想要删除某一个数据, 这样连带的所有数据将会被删除

2.2 第二范式(2NF)


在1NF的基础上, 非码属性必须完全依赖于码 (在1NF基础上消除非主属性对主码的部分函数依赖)

所以说, 第二范式就是消除第一范式的部分函数依赖.

2.2.1 何为部分函数依赖?

  • 函数依赖 : 如果通过A属性(属性组)的值, 可以确定唯一B属性的值, 则称B依赖于A
    eg : ​​学号 --> 姓名 : 通过学号可以确定姓名 (学号, 课程名称) --> 分数 : 通过学号和课程名称可以确定分数​
  • 完全函数依赖 : 如果A是一个属性组, 则B属性值的确定需要依赖于A属性组的中所有的属性值
    eg : ​​(学号, 课程名称) --> 分数 : 分数需要依赖于学号和课程名称这个属性组的所有属性才可以确定​
  • 部分函数依赖 : 如果A是一个属性组, 则B属性值的确定只需要依赖于A属性组中某一些值即可
    eg : ​​(学号, 课程名称) --> 姓名 : 姓名的确定只需要该组中的学号即可以确定, 则称为部分依赖​

2.2.2 码的概念

如果在一张表中, 一个属性或属性组, 被其他所有属性所完全依赖, 则称这个属性(属性组)为该表的码
​​​码可以为属性或属性组, 通过码可以确定其他的所有属性. 例如上面数据中的(学号, 课程名称) 就是该表中的码, 该属性组可以确定其他的所有属性​​​
主属性 : 码属性组中的所有属性
非主属性 : 除码属性组中的属性

在1NF的基础上, 消除部分函数依赖

数据库设计及规范 - MySQL_范式_05

2.3 第三范式(3NF)


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

2.3.1 何为传递函数依赖?


如果通过A属性(属性组)的组, 可以确定唯一B属性的值, 在通过B属性(属性组)的值可以确定唯一C属性的值, 则称C传递函数依赖于A
eg : 学号 --> 系名 , 系名 --> 系主任 : 因此可以通过学号来确定系主任 — 学号 --> 系主任

数据库设计及规范 - MySQL_数据_06