MySQL第九篇------多表之间的关系 和 数据库设计

版权声明:未经本人同意不得转载 https://blog.csdn.net/object_oriented_/article/details/87902712

数据库的设计

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

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

关系 举例   建表原则
一对一

人和身份证

员工表

人和简历

护照

人和身份证分析:一个人只有一个身份证,一个身份证只能对应一个人 一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键。

一对多

(多对一)

部门和员工

班级和学生 

客户和订单

分类和商品

部门和员工分析:一个部门有多个员工,一个员工只能对应一个部门 在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
* 用的最多
多对多

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

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

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

      2) 关系表图示:
                                 

综合案例:
旅游线路分类表和线路表的关系,线路和用户之间的关系图解:
           
2.  一对多案例:
        
需求:一个旅游线路分类中有多个旅游线路
       图片: 

-- 建表
-- 创建旅游线路分类表 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;

   表与表的关系图:            
                  
   
3. 多对多关系案例
         
需求:一个用户收藏多个线路,一个线路被多个用户收藏
          图片:    
                    
     

-- 创建用户表 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', '[email protected]'),
(NULL, 'cz119', 654321, '小王', '1999-09-09', '男', '13999999999', '[email protected]');

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;

              
             第三张表关联了用户表的id和线路表的id
             第三张表中的复合主键,也称作联合主键,primary key(rid,uid) 这两个外键(rid和uid)联合起来作为tab_favorite的主键
             rid和uid是不能重复的, 因为一个线路不能收藏两次

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

 

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

第一范式(1NF) 数据库表的每一列都是不可分割的原子数据项, 每一列不可再拆分
第二范式(2NF) 在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
第三范式(3NF) 在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
巴斯-科德范式(BCNF)  
第四范式(4NF)  
第五范式(5NF,又称完美范式)  

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

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

   第一范式(1NF):每一列都是不可分割的原子数据项   
                        分析 : 以上表中系就不是原子项,还可以进行分割
                         解决: 如下表符合第一范式, 一般创建表出来后都会满足第一范式
                         
                         以上表中出现的新问题如下
                          

                           
  第二范式(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. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
                        例如:该表中码为:(学号,课程名称)
                        * 主属性:码属性组中的所有属性 :学号 和 课程名称
                        * 非主属性:除过码属性组的属性
                    学号和课程名称可以确定分数,  分数完全依赖于学号和课程名称这个属性组, 那么这个属性组就叫做该表的码
                    

                  分析:  根据第二范式 这张表中 码是学号和课程名称 我们需要消除非主属性主码 的部分依赖 
                          姓名 系名 系主任 仅 依赖于 学号 不依赖于课程名称,这是部分依赖,我们就是要消除部分依赖
                                                           

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

学生表中 学号 被 系名 所依赖,  系主任 依赖于 系名 , 系主任传递依赖于学号, 消除这种传递依赖 ,
                 需要把学生表再分成两张表来解决传递依赖的问题
                
               存在的问题得以全部解决了!

                    

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

                                                            <结束 >
重点是表关系: 

表与表的关系 关系的维护
一对多 主外键的关系
多对多 中间表,两个一对多
一对一 1) 特殊一对多,从表中的外键设置为唯一
2) 从表中的主键又是外键




         
    

猜你喜欢

转载自blog.csdn.net/object_oriented_/article/details/87902712
今日推荐