码迷,mamicode.com
首页 > 其他好文 > 详细

三十九、表与表之间的三种关系

时间:2019-05-14 18:57:04      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:add   for   val   区别   就是   lte   弊端   code   let   

把所有数据都存放于一张表的弊端:

1、组织结构不清晰

2、浪费硬盘空间

3、扩展性极差

 

一、一对多:员工和部门

 1、如何查找表与表之间的关系

以员工和部门表为例。查找表关系需要做到换位思考(站在两边去找表关系)
    先站在员工表:
        找员工表的多条数据能否对应部门表的一条数据
        翻译:
            多个员工能否属于一个部门
            可以!之后不能直接下结论,还需要站在部门表的角度再确认关系

    再站在部门表:
        找部门表的多条数据能否对应员工表的一条数据
        翻译:
            多个部门能否有同一个员工
            不可以!
    只有站在两边表的角度都分析过了,才能够下结论
    员工表单向多对一部门表


2、外键foreign key

①在创建表时,先建被关联的表dep,才能建关联表emp
        先建被关联的表dep:
            create table dep(
                id int primary key auto_increment,
                dep_name char(16),
                dep_desc char(64)
            );

        再建关联表emp:
            create table emp(
                id int primary key auto_increment,
                name char(16),
                gender enum(male,female) not null default male,  # default后面的默认值空格直接书写即可
                dep_id int,
                foreign key(dep_id) references dep(id)
            );

    ②在插入数据时,必须先插入被关联的表dep,在插入关联表emp
        先插入被关联的表dep:
            insert into dep(dep_name,dep_desc) values
            (外交部,形象代言人),
            (教学部,教书育人),
            (技术部,技术能力有限部门);

        再插入关联的表emp:
            insert into emp(name,gender,dep_id) values
            (jason,male,1),
            (egon,male,2),
            (kevin,male,2),
            (tank,male,2),
            (jerry,female,3);

            update dep set id=100 where id=2;  会报错
            delete from dep where id=100;      会报错

            当我想修改emp里的dep_id或dep里面的id时返现都无法成功
            当我想删除dep表的教学部的时候,也无法删除

    方式1:先删除教学部对应的所有的员工,再删除教学部
    方式2:受限于外键约束,导致操作数据变得非常复杂,能否有一张简单的方式,
            让我不需要考虑在操作目标表的时候还需要考虑
            关联表的情况,比如我删除部门,那么这个部门对应的员工就应该跟着立即清空


3、怎么解决可以修改emp里的dep_id或dep里面的id(给外键字段新增功能:同步更新同步删除(级联删除级联更新)):

先把之前创建的表删除,先删员工表,再删部门表,最后按章下面的方式重新创建表关系

先建被关联的表dep:
            create table dep(
                id int primary key auto_increment,
                dep_name char(16),
                dep_desc char(64)
            );

        在建关联表emp:
            create table emp(
                id int primary key auto_increment,
                name char(16),
                gender enum(male,female,others) not null default male,
                dep_id int,
                foreign key(dep_id) references dep(id)
                on update cascade  # 同步更新
                on delete cascade  # 同步删除
            );

            insert into dep(dep_name,dep_desc) values
            (外交部,形象代言人),
            (教学部,教书育人),
            (技术部,技术能力有限部门);

            insert into emp(name,gender,dep_id) values
            (jason,male,1),
            (egon,male,2),
            (kevin,male,2),
            (tank,male,2),
            (jerry,female,3);

            update dep set id=100 where id=2;   # 把dep表中字段id是2的改成100
            delete from dep where id=100;       # 把dep表中字段id是100的删除

 


二、多对多:图书和作者

1、如何查找表与表之间的关系

仍然站在两张表的角度:
        站在图书表:一本书可不可以有多个作者,可以!那就是书多对一作者
        站在作者表:一个作者可不可以写多本书,可以!那就是作者多对一书
        双方都能一条数据对应对方多条记录,这种关系就是多对多!

    先来想如何创建表?图书表需要有一个外键关联作者,作者也需要有一个外键字段关联图书。问题来了,先创建谁都不合适!如何解决?
    建立第三张表,该表中有一个字段fk左表的id,还有一个字段是fk右表的id


2、外键foreign key

    创建book表:
        create table book(
            id int primary key auto_increment,
            title char(16),
            price int
        );
    创建author表:
        create table author(
            id int primary key auto_increment,
            name char(16),
            gender char(16)
        );
    创建book2author表:
        create table book2author(
            id int primary key auto_increment,
            book_id int,
            author_id int,
            foreign key(author_id) references author(id)
            on update cascade
            on delete cascade,
            foreign key(book_id) references book(id)
            on update cascade
            on delete cascade
        );

    表book中插入数据:
        insert into book(title,price) values
        (金青梅,100),
        (围城,200),
        (python全栈开发,3000);
    表author中插入数据:
        insert into author(name,gender) values
        (jason,male),
        (egon,female),
        (kevin,male);
    表book2author中插入数据:
        insert into book2author(book_id,author_id) values
        (1,1),
        (1,2),
        (1,3),
        (2,1),
        (2,3),
        (3,1),
        (3,2);

 


三、一对一:客户表和学生表

(老男孩的客户与学生之间,报名之前都是客户,只有报了名的才能是学生)

 左表的一条记录唯一对应右表的一条记录,反之也一样

   创建顾客表:
        create table customer(
            id int primary key auto_increment,
            name char(16) not null,
            qq char(16) not null,
            phone char(16) not null
        );

    创建学生表:
        create table student(
            id int primary key auto_increment,
            class_name char(20) not null,
            customer_id int unique,
            foreign key(customer_id) references customer(id)
            on delete cascade
            on update cascade
        );


总结:三种外键关系都是用foreign key,区别在于如何使用以及其他条件限制即可做出三种关系

 

四、修改表

①修改表名
        alter table 表名 rename 新表名;

②增加字段
        alter table 表名 add 字段名 数据类型[完整性约束条件];
                         add 字段名 数据类型[完整性约束条件];

        alter table 表名 add 字段名 数据类型[完整性约束条件] first;

        alter table 表名 add 字段名 数据类型[完整性约束条件] after 字段名;

③删除字段
        alter table 表名 drop 字段名;

④修改字段:modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
        alter table 表名 modify 字段名 数据类型[完整性约束条件];

        alter table 表名 change 旧字段名 新字段名 旧数据类型[完整性约束条件];

        alter table 表名 change 旧字段名 新字段名 新数据类型[完整性约束条件];

 

五、复制表

①复制表结构+记录 (key不会复制: 主键、外键和索引)
    create table new_service select * from service;

②只复制表结构
    create table new1_service select * from service where 1=2; 条件为假,查不到任何记录

 

三十九、表与表之间的三种关系

标签:add   for   val   区别   就是   lte   弊端   code   let   

原文地址:https://www.cnblogs.com/zhangguosheng1121/p/10863871.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!