外键 级联更新/删除 复制表 修改表

引入 所有的信息都记录在一张表中所带来的问题

1.表的结构不清晰   太乱
2.浪费硬盘空间     dep_name 重复太多
3.表的扩展性极差(无法忽略的缺点)    想改其中的一个部门需要连着改好多

类似于我们将所有的代码都写在用一个py文件内

  确立表与表之间的关系 一定要换位思考(必须两方都考虑周全之后才能得出结论)

一对多

    以员工表和部门表为例
    先站在员工表看能否有多个员工对应一个部门
      翻译过来:
      一个部门能否有多个员工
        可以!!!(暂时只能确定员工单向多对一部门)
    再站在部门表看能否有多个部门对应一个员工
      翻译过来:
      一个员工能否属于多个部门
      不可以!!!
    结论:员工表和部门表之间仅仅是单向的多对一
  那么它们的表关系就是"一对多"
  表关系中没有多对一一说,只有一对多
  (无论是多对一还是一对多都叫"一对多")

如何让两种表有代码层面上真正的关联 就必须使用外键
什么是外键?
  让表与表有硬性层面上的关系

foreign key
外键约束
  1.在创建表的时候 必须先创建被关联表(*****)
  2.插入数据的时候 也必须先插入被关联表的数据(****)

建表
        create table dep(
            id int primary key auto_increment,
            dep_name varchar(32),
            dep_desc varchar(128)
        );

        create table emp(
            id int primary key auto_increment,
            emp_name varchar(64),
            emp_gender enum(‘male‘,‘female‘,‘others‘) default ‘male‘,
            dep_id int,
            foreign key(dep_id) references dep(id)
        );

    插入数据
        insert into dep(dep_name,dep_desc) values(‘外交部‘,‘搞外交‘),
        (‘教学部‘,‘教书育人‘),
        (‘技术部‘,‘技术能力有限部门‘)
        ;

        insert into emp(emp_name,dep_id) values(‘jason‘,1),
        (‘egon‘,2),
        (‘tank‘,2),
        (‘kevin‘,3);

代码

修改表数据

update dep set id=200 where id = 1;
update emp set dep_id = 300 where id = 1;

delete from dep where id = 3;

外键虽然能够帮你强制建立表关系 但是也会给表之间增加数据相关的约束

1.删除数据的时候 先删员工表的数据 再删部门表的数据(也就是先删除被关联表 数据也是先删除被关联表的数据)
delete from emp where id = 4;
delete from dep where id = 3;

联级更新

2.级联更新级联删除
            create table dep1(
                id int primary key auto_increment,
                dep_name varchar(32),
                dep_desc varchar(128)
            );

            create table emp1(
                id int primary key auto_increment,
                emp_name varchar(64),
                emp_gender enum(‘male‘,‘female‘,‘others‘) 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(emp_name,dep_id) values(‘jason‘,1),
            (‘egon‘,2),
            (‘tank‘,2),
            (‘kevin‘,3);

        update dep set id=200 where id = 3;
        delete from dep where id = 2;

多对多

图书与作者表
  一定要换位思考
  先站在图书
    多本书能否有一个作者
    一个作者能否写多本书 可以!!!

  再站在作者
    多个作者能否和写一本书
    一本书能否有多个作者 可以!!!

如果双方都是可以,那么就是多对多
强调 foreign key只是用来帮你建表关系的 不是某个关系特有的方法

create table book(
                id int primary key auto_increment,
                title varchar(32),
                price int,
                author_id int,
                foreign key(author_id) references author(id)
                on update cascade  # 同步更新
                on delete cascade  # 同步删除

            );

            create table author(
                id int primary key auto_increment,
                name varchar(32),
                age int,
                book_id int,
                foreign key(book_id) references book(id)
                on update cascade  # 同步更新
                on delete cascade  # 同步删除
            );

错误演示

注意上述的建法是错误的 多对多关系的建立 必须手动创建第三张表 用来专门记录两种表之间的关系

先建两种普通的表  不需要设置外键
        create table book(
                id int primary key auto_increment,
                title varchar(32),
                price int
            );
        create table author(
                id int primary key auto_increment,
                name varchar(32),
                age int
            );
        create table book2author(
                id int primary key auto_increment,
                book_id int,
                foreign key(book_id) references book(id)
                on update cascade
                on delete cascade,
                author_id int,
                foreign key(author_id) references author(id)
                on update cascade
                on delete cascade
        );

        insert into book(title,price) values(‘大闹天空‘,199),(‘聊斋‘,299),(‘jason教你删别人的库,让别人跑去吧‘,1);

        insert into author(name,age) values(‘jason‘,18),(‘tank‘,38);

        insert into book2author(book_id,author_id) values(4,3);  # 报错
        insert into book2author(book_id,author_id) values(1,1),(1,2),(2,1),(3,1),(3,2); 

一对一

1.一对一的场景 当你的表特别庞大的时候 你可以考虑拆分表

2.联想老男孩的客户和学生

通常将关系字段 称之为 外键字段
  一对多的外键字段 建在多的一方
  多对多 建在第三张表了
  一对一 外键字段建在任意一方都可以 但是推荐你建在查询频率较高的一方

create table authordetail1(
            id int primary key auto_increment,
            phone int,
            addr char(255)

    );

    create table author1(
        id int primary key auto_increment,
        name char(4),
        age int,
        authordetail_id int unique,
        foreign key(authordetail_id) references authordetail1(id)
        on update cascade
        on delete cascade
    );

一对一代码演示

判断表关系的最简单的语法
        图书与出版社  一对多
            一本书可不可以有多个出版社  不可以!!!
            一个出版社可不可以出版多本书  可以!!!
            一对多的关系

        图书与作者表  多对多
            一本书可不可以有多个作者    可以!!!
            一个作者可不可以写多本书     可以!!!
            多对多的关系

        作者与作者详情  一对一
            一个作者可不可以有多个详情  不可以!!!
            一个作者详情可不可以有多个作者  不可以!!!
             要么两者是一对一
             要么两者之间没任何关系            

例子总结

    了解知识点
        1.修改表的完整语句
            1. 修改表名
                  ALTER TABLE 表名
                                      RENAME 新表名;
            2. 增加字段
                  ALTER TABLE 表名
                                      ADD 字段名  数据类型 [完整性约束条件…],
                                      ADD 字段名  数据类型 [完整性约束条件…];
                  ALTER TABLE 表名
                                      ADD 字段名  数据类型 [完整性约束条件…]  FIRST;  # 直接移到最前面
                  ALTER TABLE 表名
                                      ADD 字段名  数据类型 [完整性约束条件…]  AFTER 字段名;  # 寻找插哪个字段的后面
            3. 删除字段
                  ALTER TABLE 表名
                                      DROP 字段名;
            4. 修改字段  # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
                  ALTER TABLE 表名
                                      MODIFY  字段名 数据类型 [完整性约束条件…];
                  ALTER TABLE 表名
                                      CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

    # 查询语句执行的结果也是一张表,可以看成虚拟表

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

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

    create table new1_service select * from service where 1=2;  

    create table t4 like employees;
    

原文地址:https://www.cnblogs.com/lddragon/p/11384378.html

时间: 2024-10-12 13:11:55

外键 级联更新/删除 复制表 修改表的相关文章

mysql外键级联更新删除

MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作,包括RESTRICT.NO ACTION.SET NULL和CASCADE.其中RESTRICT和NO ACTION相同,是指在子表有关联记录的情况下父表不能更新:CASCADE表示父表在更新或者删除时,更新或者删除子表对应记录:SET NULL则是表示父表在更新或者删除的时候,子表的对应字段被S

Oracle外键级联删除和级联更新

1 级联删除 Oracle在外键的删除上有NO ACTION(类似RESTRICT).CASCADE和SET NULL三种行为. 下面以学生-班级为例说明不同情况下的外键删除,学生属于班级,班级的主键是学生的外键. -- 班级表 CRATE TABLE TB_CLASS ( ID NUMBER NOT NULL, --班级主键 NAME VARCHAR2(50), --班级名称 CONSTRAINT PK_TB_CLASS PRIMARY KEY (ID) ); -- 学生表 CREATE TA

【Mysql】外键级联与级联的劣势

在建表的时候时候,可以对于删除delete.修改update设置为级联.用一个例子先说明外键级联级联的概念 假如数据库中本以存在一张usertable如下: 此user表非常简单,id为主键. 下面我将新建一张cascade_test表如下,这里的user_id与usertable的主键id形成参照完整性,并同时建立删除与修改的级联: 如果用SQL语句建立上图的表则如下: CREATE TABLE `test`.`cascade_test` ( `id` INTEGER UNSIGNED NOT

数据库复制:修改表结构、新增表、新增存储过程 会被复制到订阅服务器

[SQL Server高可用性]数据库复制:修改表结构.新增表.新增存储过程 会被复制到订阅服务器? 在SQL Server上配置好数据库复制后: 1.如果给表加了字段,会不会复制到订阅服务器呢?如果是删除1个字段呢? 2.如果新创建了1个表,会不会被同步过去呢? 3.如果新建了一个存储过程,会不会同步过去呢? 本文将会通过实验,回答上述问题. 1.首先,需要配置数据库复制. 这里为了简单起见,用了机器上的2个SQL Server 2008R2的实例. 两个实例分别是:MSSQLSERVER.S

MySQL数据库 外键,级联, 修改表的操作

1.外键: 用来建立两张表之间的关系 - 一对多 - 多对多 - 一对一 研究表与表之间的关系: 1.定义一张 员工部门表 id, name, gender, dep_name, dep_desc - 将所有数据存放在一张表中的弊端: 1.结构不清晰 ---> 不致命 2.浪费空间 ---> 不致命 3.可扩展性极差 ---> 不可忽视的弊端 - 类似于将所有python代码存放在一个py文件中,强耦合到一起了----> 解耦合 ----> 拆分表 - 拆分表解决以上问题.

[Django]orm中的外键级联删除

这里的系统环境为django1.6   os为win7 今天有个需求说的是添加一个地区表,然后用外键和几个非常重要的实体表来做关联(地区表作为其他表的外键),写完地区的删除操作的时候,测试了下代码,功能正常.可是眼睛移动到控制台输出的时候傻了 connexesql ->DELETE FROM `mngm_device` WHERE `mngm_device`.`area_id` IN (%s, %s, %s) connexesql ->DELETE FROM `ad_ad` WHERE `ad

表的操作-建立表-删除表-修改表的名字-修改列的名字及数据类型-删除/添加主键-在表的最后增加一列-查看表的结构

USE db; -- 列出查看当前数据库中的所有表 SHOW TABLES; SHOW TABLES LIKE 's%'; CREATE TABLE 表名 ( 列名 类型 修饰 约束, sid INT(3) UNSIGNED ZEROFILL PRIMARY KEY AUTO_INCREMENT sgender ENUM('男','女','保密') DEFAULT '男' )ENGINE=MYISAM DEFAULT CHARSET=utf8; -- 建立表 CREATE TABLE IF NO

iOS sqlite3外键级联删除问题解决

最近学习使用数据库,以前上学的时候也学过外键和级联删除. NSString *sql=@"CREATE TABLE PlanModel (Id integer,name text,constraint plan_key primary key (Id))"; NSString *sql=@"CREATE TABLE SystemModel (Id integer,planId integer,name text,foreign key (planId) references

mysql建立表及表的简单操作-插入数据-删除主键-删除表-修改表的数据-删除表的数据

-- 1.使用数据库 USE ren; -- 2.建立student表 CREATE TABLE student ( sid INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,   -- UNSIGNED(无符号) AUTO_INCREMENT(自增) sname VARCHAR(10),    -- 只能保存10个字符 saddress VARCHAR(15)   -- 只能保存15个字符 )ENGINE=MYISAM DEFAULT CHARSET=utf8;