数据库的设计

    1. 多表之间的关系(三种)

       1) 分类和实现关系:(红色部分重要)

关系

举例

 

建表原则

一对一

人和身份证

员工表

人和简历

护照

人和身份证分析:一个人只有一个身份证,一个身份证只能对应一个人

一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键。

一对多

(多对一)

部门和员工

班级和学生 

客户和订单

分类和商品

部门和员工分析:一个部门有多个员工,一个员工只能对应一个部门

在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键

* 用的最多

多对多

老师和学生
老师和学生
学生和课程

学生和课程分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择

需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键

      2) 关系表图示:

                                 

macmysql表关系图工具 mysql数据库表关系图_非主属性

综合案例:
旅游线路分类表和线路表的关系,线路和用户之间的关系图解:
        

macmysql表关系图工具 mysql数据库表关系图_外键_02

   
2.  一对多案例:
        

需求:一个旅游线路分类中有多个旅游线路

       图片: 

macmysql表关系图工具 mysql数据库表关系图_非主属性_03

-- 建表-- 创建旅游线路分类表 tab_category

create table tab_category (
cid int primary key auto_increment, -- cid 旅游线路分类主键,自动增长
cname varchar(100) not null unique -- cname 旅游线路分类名称非空,唯一,字符串 100
)

-- 添加旅游线路分类数据:
insert into tab_category (cname) values ('周边游'), ('出境游'), ('国内游'), ('港澳游');

select * from tab_category;


-- 创建旅游线路表 tab_route

create table tab_route(
rid int primary key auto_increment, -- 旅游线路主键,自动增长
rname varchar(100) not null unique, -- 旅游线路名称非空,唯一,字符串 100
price double,                       -- 价格
rdate date,                         -- 上架时间,日期类型
cid int,                            -- 外键,所属分类
foreign key (cid) references tab_category(cid)   -- 省略了constraint 外键名称 
)

-- 添加旅游线路数据
INSERT INTO tab_route VALUES 
(NULL, '【厦门+鼓浪屿+南普陀寺+曾厝垵 高铁 3 天 惠贵团】尝味友鸭面线 住 1 晚鼓浪屿', 1499,
'2018-01-27', 1),
(NULL, '【浪漫桂林 阳朔西街高铁 3 天纯玩 高级团】城徽象鼻山 兴坪漓江 西山公园', 699, '2018-02-
22', 3),
(NULL, '【爆款¥1699 秒杀】泰国 曼谷 芭堤雅 金沙岛 杜拉拉水上市场 双飞六天【含送签费 泰风情 广州
往返 特价团】 ', 1699, '2018-01-27', 2),
(NULL, '【经典•狮航 ¥2399 秒杀】巴厘岛双飞五天 抵玩【广州往返 特价团】 ', 2399, '2017-12-23',
2),
(NULL, '香港迪士尼乐园自由行 2 天【永东跨境巴士广东至迪士尼去程交通+迪士尼一日门票+香港如心海景酒店
暨会议中心标准房 1 晚住宿】 ', 799, '2018-04-10', 4);

select * from tab_route;

   表与表的关系图:            

                  

macmysql表关系图工具 mysql数据库表关系图_非主属性_04

   

3. 多对多关系案例
         

需求:一个用户收藏多个线路,一个线路被多个用户收藏

  图片:    

                    

macmysql表关系图工具 mysql数据库表关系图_外键_05

     

-- 创建用户表 tab_user  create table tab_user (uid int primary key auto_increment, -- uid用户主键,自增长
username varchar(100) unique not null, -- username 用户名长度 100,唯一,非空
password varchar(30) not null, -- password 密码长度 30,非空
name varchar(100), -- name 真实姓名长度 100
birthday date, -- birthday 生日
sex char(1) default '男', -- sex 性别,定长字符串 1
telephone varchar(11), -- telephone 手机号,字符串 11
email varchar(100) -- email 邮箱,字符串长度 100
)

-- 添加用户数据
INSERT INTO tab_user VALUES
(NULL, 'cz110', 123456, '老王', '1977-07-07', '男', '13888888888', '66666@qq.com'),
(NULL, 'cz119', 654321, '小王', '1999-09-09', '男', '13999999999', '99999@qq.com');

select * from tab_user;


-- 用户和旅游线路是多对多的关系, 需要第三方表
-- 创建收藏表 tab_favorite

create table tab_favorite (
rid int,                -- rid 旅游线路 id,外键
date datetime,          -- date 收藏时间
uid int,                -- uid 用户 id,外键
primary key(rid,uid),   -- rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次
foreign key (rid) references tab_route(rid), -- 用户外键关联
foreign key(uid) references tab_user(uid)    -- 路线外键关联
)

-- 增加收藏表数据

INSERT INTO tab_favorite VALUES
(1, '2018-01-01', 1), -- 老王选择厦门
(2, '2018-02-11', 1), -- 老王选择桂林
(3, '2018-03-21', 1), -- 老王选择泰国
(2, '2018-04-21', 2), -- 小王选择桂林
(3, '2018-05-08', 2), -- 小王选择泰国
(5, '2018-06-02', 2); -- 小王选择迪士尼

select * from tab_favorite;

              

macmysql表关系图工具 mysql数据库表关系图_主键_06


             第三张表关联了用户表的id和线路表的id


             第三张表中的复合主键,也称作联合主键,primary key(rid,uid) 这两个外键(rid和uid)联合起来作为tab_favorite的主键


             rid和uid是不能重复的, 因为一个线路不能收藏两次



到此为止表就设计完了,看效果 


                          

macmysql表关系图工具 mysql数据库表关系图_主键_07



 

 

 

3. 数据库范式
            1) 范式:
好的数据库设计对数据的存储性能和后期的程序开发, 都会产生重要的影响。
                         建立科学的, 规范的数据库就需要满足一些规则来优化数据的设计和存储, 这些规则就称为范式
             2)目前关系数据库有六种范式:

第一范式(1NF)

数据库表的每一列都是不可分割的原子数据项, 每一列不可再拆分

第二范式(2NF)

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

第三范式(3NF)

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

巴斯-科德范式(BCNF)

 

第四范式(4NF)

 

第五范式(5NF,又称完美范式)

 

满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF) ,
其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就没有什么太大的问题。
         

          2) 只介绍前三种范式
     
   根据案例介绍

macmysql表关系图工具 mysql数据库表关系图_外键_08


   第一范式(1NF):每一列都是不可分割的原子数据项   


                        分析 : 以上表中系就不是原子项,还可以进行分割


                         解决: 如下表符合第一范式, 一般创建表出来后都会满足第一范式


                         

macmysql表关系图工具 mysql数据库表关系图_外键_09


                         以上表中出现的新问题如下


                          

macmysql表关系图工具 mysql数据库表关系图_macmysql表关系图工具_10

                           
  第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
         几个概念:
                    1. 函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
                        例如:学号-->姓名。  (学号,课程名称) --> 分数           
                         分析:  姓名依赖学号,    分数依赖学号和课程名称

                    2. 完全函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值。
                        例如:(学号,课程名称) --> 分数
                        分析:    分数依赖于 学号和课程名称这个属性组, 少一个学号或者课程名称都不可以, 这是完全依赖

                    3. 部分函数依赖:A-->B, 如果A是一个属性组,则B属性值的确定只需要依赖于A属性组中某一些值即可。
                        例如:(学号,课程名称) -- > 姓名
                        分析:   学号就可以确定姓名, 课程名称可以忽略,这是部分函数依赖

                    4. 传递函数依赖:A-->B, B -- >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A
                        例如:学号-->系名,系名-->系主任
                         分析: 根据学号可以确定在哪个系, 根据系可以确定哪个系主任, 那么这个学号拥有的系主任也就确定了

                    5. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码


                        例如:该表中码为:(学号,课程名称)


                        * 主属性:码属性组中的所有属性 :学号 和 课程名称


                        * 非主属性:除过码属性组的属性


                    学号和课程名称可以确定分数,  分数完全依赖于学号和课程名称这个属性组, 那么这个属性组就叫做该表的码


                    

macmysql表关系图工具 mysql数据库表关系图_外键_09

非主属性 对 主码 的部分依赖 


                          姓名 系名 系主任 仅 依赖于 学号 不依赖于课程名称,这是部分依赖,我们就是要消除部分依赖


                                                           

macmysql表关系图工具 mysql数据库表关系图_macmysql表关系图工具_12

                 

macmysql表关系图工具 mysql数据库表关系图_macmysql表关系图工具_13

       


 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)


                

macmysql表关系图工具 mysql数据库表关系图_macmysql表关系图工具_14

学生表中 学号 被 系名 所依赖,  系主任 依赖于 系名 , 系主任传递依赖于学号, 消除这种传递依赖 ,


                 需要把学生表再分成两张表来解决传递依赖的问题


                

macmysql表关系图工具 mysql数据库表关系图_外键_15


               存在的问题得以全部解决了!



                    

学了以上范式在后续做数据库设计 业务分析的时候,应用这些范式设计出更加合理的数据库表

                                                            <结束 >
重点是表关系: 

表与表的关系

关系的维护

一对多

主外键的关系

多对多

中间表,两个一对多

一对一

1) 特殊一对多,从表中的外键设置为唯一

2) 从表中的主键又是外键