zoukankan      html  css  js  c++  java
  • 表与表之间的三种关系

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

    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; 条件为假,查不到任何记录
  • 相关阅读:
    【转】pymongo实现模糊查询
    使用pip安装包提示TLS证书错误解决办法
    sed用法去除行首和行末的中括号
    logstash之filter处理中括号包围的内容
    根据IP查地理位置信息
    shell生成连续天数日期
    linux grep 取出特定字符串并统计个数
    【转】css3实现文字闪烁,改变透明度
    【转】Django中使用POST方法获取POST数据
    [算法]机器人运动范围
  • 原文地址:https://www.cnblogs.com/zhangguosheng1121/p/10863871.html
Copyright © 2011-2022 走看看