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

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

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; 条件为假,查不到任何记录

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

时间: 2024-10-07 21:50:15

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

斗争程序猿(三十九)——历史朝代大学(三)——我知道几乎满足

文/温国兵 遥望2011年的某个惶惶岁月,那是我与知乎相识的日子. 排除知乎站点的内測用户,我应该算得上第一批用户. 那时知乎网还未开放注冊,仅仅能通过好友邀请注冊,我费了九牛二虎之力,申请了好几次,才拥有了知乎账号.作为一个真实的问答社区.从近几年的运营来看,知乎是成功的. 尽管外界曾质疑知乎站点的盈利模式.但不可否认知乎是伟大的. 众所周知.知乎的原型是国外的Quora.曾经一直以为Quora是多么的神圣.直到今年注冊并使用后,才发觉知乎在用户体验上一点不逊色于Quora.好的站点当如知乎,

QT开发(二十九)——QT常用类(三)

QT开发(二十九)--QT常用类(三) 一.QImage 1.QImage简介 QT中提供了四个处理图像数据的类:QImage.QPixmap.QBitmap.QPicture. QImage提供了允许直接访问像素数据的硬件无关的图像显示方案,能够用作绘图设备. QImage专门为I/O.直接像素访问操作而设计,并进行了优化.访问图片的像素或是修改图片像素,则需要使用QImage,或者借助于QPainter来操作像素. 由于QImage继承自QPaintDevice,QPainter可以直接在Q

Gradle 1.12用户指南翻译——第三十九章. IDEA 插件

本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc 本文翻译所在分支: https://github.com/msdx/gradledoc/tree/1.12. 直接浏览双语版的文档请访问: http://gradledoc.qiniudn.com/1.12/userg

Python进阶(三十九)-数据可视化の使用matplotlib进行绘图分析数据

Python进阶(三十九)-数据可视化の使用matplotlib进行绘图分析数据 ??matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中. ??它的文档相当完备,并且 Gallery页面 中有上百幅缩略图,打开之后都有源程序.因此如果你需要绘制某种类型的图,只需要在这个页面中浏览/复制/粘贴一下,基本上都能搞定. ??在Linux下比较著名的数据图工具还有gnuplot

QT开发(三十九)——GraphicsView框架

QT开发(三十九)--GraphicsView框架 本文主要翻译自QT 5.6.2GraphicsView官方文档 一.GraphicsView框架简介 QT4.2开始引入了Graphics View框架用来取代QT3中的Canvas模块,并作出了改进,Graphics View框架实现了模型-视图结构的图形管理,能对大量图元进行管理,支持碰撞检测,坐标变换和图元组等多种方便的功能. GraphicsView框架结构主要包含三个主要的类QGraphicsScene(场景).QGraphicsVi

centos shell编程5LANMP一键安装脚本 第三十九节课

centos shell编程5LANMP一键安装脚本  第三十九节课 上半节课 下半节课 f

程序员的奋斗史(三十九)——大学断代史(三)——我和知乎邂逅

遥望2011年的某个惶惶岁月,那是我与知乎相识的日子. 排除知乎网站的内测用户,我应该算得上第一批用户.那时知乎网还未开放注册,只能通过好友邀请注册,我费了九牛二虎之力,申请了好几次,才拥有了知乎账号.作为一个真实的问答社区,从近几年的运营来看,知乎是成功的.虽然外界曾质疑知乎网站的盈利模式,但不可否认知乎是伟大的. 众所周知,知乎的原型是国外的Quora.以前一直以为Quora是多么的神圣,直到今年注册并使用后,才发觉知乎在用户体验上一点不逊色于Quora.好的网站当如知乎,简洁美观.操作简便

NeHe OpenGL教程 第三十九课:物理模拟

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十九课:物理模拟 物理模拟简介: 还记得高中的物理吧,直线运动,自由落体运动,弹簧.在这一课里,我们将创造这一切. 物理模拟介绍 如果你很熟悉物理规律,并且想实现它,这篇文章很适合你. 在这篇教程里,你会创建一个非常简单的物理引

三十九、git add详解

一.前言git add命令主要用于把我们要提交的文件的信息添加到索引库中.当我们使用git commit时,git将依据索引库中的内容来进行文件的提交.二.基本git add <path>表示 add to index only files created or modified and not those deleted 我通常是通过git add <path>的形式把我们<path>添加到索引库中,<path>可以是文件也可以是目录.git不仅能判断出&

CCNA实验三十九 再临无线现场 &nbsp;

CCNA实验三十九 再临无线现场 环境:Windows XP  . PacketTracert 5.3 目的: 再次加深对无线模块化使用的理解,还有掌握无线局域网中的WEP.WPA.WPA-PSK加密,了解如何使用加密保护无线网络. 步骤: 创建拓扑如下: 1.分别为三台无线设备添加无线网卡: 2.分别为三台路由器添加无线模块: 3.配置AAA服务器: 4.配置R1路由器: Router>en Router#conf t Router(config)#host R1 R1(config)#ip