• 数据库语法二之外键


    数据库语法二之外键

    外键(******必备知识点******):
    
        1、外键:用来建立两张表之间的关系
            - 一对多
            - 多对多
            - 一对一
    
    
        2、了解的知识点:
            - 修改表的操作
            - 赋值表操作
    
    研究表与表之间的关系:
        1、定义一张员工表,员工部门表
        id,name,gender,dep_name,dep_desc
    
    
        - 将所有数据存放在一张表中的弊端;
        1、结构不清晰:---不致命
        2、浪费空间:----不致命
        3、可扩展性差----不可忽视的弊端
            - 类似于将所有的python代码存放到一个py文件中,强耦合到一起
    
        - 拆分表解决以上问题
    
        - 需要给两张表之间,建立一种强有力的关系,这就得使用外键
    
        -!!!!注意:如何确认表与表之间的关系是(一对多,多对多,一对一)
            - 注意:要确立两张表之间的关系,必须站在两个位置去思考
                - 站在员工表达位置:多个员工能否对应一个部门?能!
    
                    员工与部门:多 对 一
    
                        员工表单向 多 对 一部门表
    
                - 站在部门表的位置:多个部门能否对应一个员工? 不能!!!
    
            总结:凡是单向 多 对 一 的表达关系,称之为 一对多的外键关系。因为python中的mysql中没有多对一的关系
    
    
    
        - 外键:语法: foreign key(当前表中建立关系的外键字段) references  被关联表名(id)
    
    
        #####注意:创建两张表
            必须先建立被关联表,在建立关联表
    
    
        被关联表:
            dep:
    
                create table dep(
                    id int primary key auto_increment,
                    dep_name varchar(16),
                    dep_desc varchar(255)
                );
    
    
        关联表:
            emp:
    
                create table emp(
                    id int primary key auto_increment,
                    name varchar(16),
                    age int,
                    gender enum('male', 'female', 'others') default 'male',
                    dep_id int not null,
                    foreign key(dep_id) references dep(id)
                );
    
    
        插入数据:
            - 1、必须先插入被关联表(dep)的数据,在插入关联表(emp)的数据
    
    
            # dep:
                insert into dep(dep_name, dep_desc) values('nb_外交部', '国际形象大使部门'),
                ('sb_教学部', '造程序员部门!!!'),
                ('技术部', '技术有限部门');
    
    
    
            # emp:
                insert into emp(name, age, gender, dep_id)
                values('tank', 17, 'male', 1),
                ('jason', 50, 'male', 2),
                ('sean', 66, 'male', 2),
                ('egon', 73, 'male', 2),
                ('owen', 95, 'female', 3);
    
                # 当在关联表中查看时如果在key列中能看到MUL则代表外键绑定成功
    
                # 若插入一条被关联数据中没有的id号,则会报错
                insert into emp(name, age, gender, dep_id) values('大饼', 100, 'others', 999);
    
        # 更新数据或删除数据
            - 更新数据
            # 报错
            update emp set dep_id= 100 where id=2;
            # 报错
            update dep set id=100 where id=1;
    
    
            # 先删除已关联的dep_id字段,才能修改dep表中的关联id字段
            delete from emp where id=1;
            update dep set id=100 where id=1;
    
            - 删除数据
                - 先删除关联表中的记录,再删除被关联表中的记录
                - 删除emp表中的dep_id 为2的记录
                delete from emp where dep_id=2;
    
                - 再删除dep表中id为2的记录
                delete from dep where id=2;
    
    
            那这样虽然可以删除数据,但是,每一次都得先删除关联的表中的数据,在删除被关联表中的数据,很麻烦,那接下来这种方法就是解决这个问题的
    
    
        - 级联更新与级联删除
            - on update cascade
            - on delete cascade
    
        - 创建表
            # 被关联表:
                dep2:
                    create table dep2(
                        id int primary key auto_increment,
                        dep_name varchar(16),
                        dep_desc varchar(255)
                    );
    
    
            # 关联表:
                emp2:
                    create table emp2(
                        id int primary key auto_increment,
                        name varchar(16),
                        age int,
                        gender enum('male', 'female', 'others') default 'male',
                        dep_id int not null,
                        foreign key(dep_id) references dep2(id)
                        on update cascade
                        on delete cascade
                    );  #注意在使用级联更新或删除时后面都不要加逗号,可理解为他们都是最后一行代码
    
    
            - 插入数据
            # dep:
                insert into dep2(dep_name, dep_desc) values('nb_外交部', '国际形象大使部门'),
                ('sb_教学部', '造程序员部门!!!!'),
                ('技术部', '技术有限部门');
    
            # emp:
                insert into emp2(name, age, gender, dep_id)
                values('tank', 17, 'male', 1),
                ('jason', 70, 'male', 2),
                ('sean', 50, 'male', 2),
                ('egon', 88, 'male', 2),
                ('owen', 95, 'female', 3);
    
                # 报错,
                insert into emp(name, age, gender, dep_id) values('大饼', 100, 'others', 999);
    
            - 更新数据或删除数据
                - 更新记录
                    update dep2 set id=200 where id=1;
    
                - 删除记录
                    delete from emp2 where id=5;
    
    
            注意: mysql中没有 多对一 只有 一对多
    
    
    
        - 多对多:
            同样的道理也得站在两张表的位置去思考
    
            - 错误实发:
                - 创建book表
                    create table book(
                        id int primary key auto_increment,
                        title varchar(20),
                        price int,
                        book_content varchar(255),
                        author_id int,
                        foreign key(author_id) references author(id)
                        on update cascade
                        on delete cascade
                    );
    
    
                - 创建author表
                    create table author(
                        id int primary key auto_increment,
                        name varchar(20),
                        age int,
                        book_id int,
                        foreign key(book_id) references book(id)
                        on update cascade
                        on delete cascade
                    );
    
    
    
             # 问题:那么为什么会出现这种情况呢?
                因为无法知道那张表是被关联表
    
    
             # 解决方法:利用第三张表, 为两张表建立“多对多外键关系”
    
                - book:
                    create table book(
                        id int primary key auto_increment,
                        title varchar(20),
                        price int,
                        book_content varchar(255)
                    );
    
    
                - author:
                    create table author(
                        id int primary key auto_increment,
                        name varchar(16),
                        age int
                    );
    
    
    
    
                - book2author:
                    create table book2author(
                        id int primary key auto_increment,
                        book_id int,
                        author_id int,
                        foreign key(book_id) references book(id)
                        on update cascade
                        on delete cascade,
                        foreign key(author_id) references author(id)
                        on update cascade
                        on delete cascade
                    );
    
            - 插入数据
                - book
                insert into book(title, price, book_content) values
                ('金瓶Mei', 588, '讲述朦胧时光的小故事'),
                ('python从入门到断气', 2000, '学习如何一夜秃头'),
                ('三体', 200, '跟着刘慈欣进入宇宙奇幻世界');
    
    
    
                - author
                insert into author(name, age) values('egon', 68), ('jason', 88);
    
    
                - book2author
    
                insert into book2author(book_id, author_id) values
                (1, 1),
                (1, 2),
                (2, 2),
                (3, 1);
    
    
                # 报错,插入的数据,book_id, author_id 必须存在
                insert into book2author(book_id, author_id) values (4, 4);
    
    
                # 更新或删除
                    # 更新
                        - update book set price=6666 where id=1;
                        - update book set id=4 where id=1;
    
    
                    ####注:此时的更新或删除只会对自己以及第三方的数据有影响, 并不会影响到其他的table
    
    
                    # 删除
                        - delete from book where id=4;
    
    
        - 一对一:
            - 两张表之间的关系一一对应,将一张数据量比较大的表,拆分成两张表。
                - user_info:
                    id, name, age, gender, hobby, id_card
    
    
                - user:
                    id, name, age, detail_id(这个就是外键)
    
    
                - detail:
                    id, gender,hobby,id_card
    
                user与detail表建立了 一对一的外键关系
                foreign key 应该建立在 使用频率较高的一方。
    
            - 创建表
                # 被关联表
                create table customer(
                    id int primary key auto_increment,
                    name varchar(16),
                    media varchar(32)
                );
    
    
    
                # 关联表
                create table student(
                    id int primary key auto_increment,
                    addr varchar(255),
                    phone char(11),
                    id_card char(18),
    
                    # 外键必须设置为唯一的
                    customer_id int unique,
                    foreign key(customer_id) references customer(id)
                    on update cascade
                    on delete cascade
                );
    
    
            - 插入数据
                insert into customer(name, media) values
                ('hcy', 'facebook'),
                ('zsb1', 'ig'),
                ('zsb2', 'vk'),
                ('hb', '探探');
    
    
    
                insert into student(addr, phone, id_card, customer_id) values
                ('上海', '12345678912', '1466711446248431348', 1),
                ('北京', '12345678911', '1466711446248431349', 2);
    
    
    
                # 报错,一对一 关系必须一一对应
                insert into student(addr, phone, id_card, customer_id) values ('上海', '12345678912', '1466711446248431348', 1)
    
    
    
    - 了解:
        - 修改表的操作:
            - 语法:注意:mysql 不区分大小写
                1、修改表名
                    alter table 表名 rename 新的表名;
    
                2、增加字段
                    alter table 表名 add 字段名 数据类型 (完整的约束条件),
                                    add 字段名 数据类型 (完整的约束条件);  #添加到最后一列
    
    
                    alter table 表名 add 字段名 数据类型 (完整的约束条件) first;  # 添加到第一列
    
                    alter table 表名 add 字段名 数据类型 (完整的约束条件) after 字段名;  # 添加到某一列之后
    
    
                3、删除字段
                    alert table 表名 drop 字段名;
    
                4、修改字段
                    alter table 表名 modify 字段名 数据类型 (完整的约束条件);   #修改数据类型
    
                    alter table 表名 change 旧字段名 新字段名 旧数据类型 (完整的约束条件);   # 修改字段名,保留字段类型
    
                    alter table 表名 change 旧字段名 新字段名 新数据类型 (完整的约束条件);   # 修改字段名与字段类型
    
    
        复制表的操作:
            复制表结构 + 记录 (key不会复制:主键、外键和索引)
            create table new_service select * from service;
    
    
            只复制表结构
            # 将select * from service where 1=2;  -----> 不要真实数据,只需要表结构
            create  table new_customer select * from customer where 1=2;
    
    
    
    
    
    
  • 相关阅读:
    (已解决)mac安装mysql出现:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/my...
    非root用户启动redis容器报错mkdir: cannot create directory '/bitnami/redis': Permission denied
    VirtualBox虚拟机E_INVALIDARG (0x80070057)
    非root用户启动redis容器报错mkdir: cannot create directory '/bitnami/redis': Permission denied
    添加共享文件夹
    Skipping acquire of configured file ···doesn't support architecture 'i386' acquire of configured file
    docker镜像运行错误排查
    debian9使用国内源安装docker以及一些使用方法
    docker创建镜像及push镜像出错问题
    mongodb参数
  • 原文地址:https://www.cnblogs.com/yafeng666/p/12030339.html
Copyright © 2020-2023  润新知