zoukankan      html  css  js  c++  java
  • 外键

    外键

    MySQL外键约束(foreign key)用来在两个表的数据之间建立链接
    一个表中的 FOREIGN KEY 指向另一个表中的 UNIQUE KEY(唯一约束的键),外键是相对于主键说的,是建立表之间的联系的必须的前提。

    外键对应的是参照完整性,一个表的外键可以为空值,若不为空值,则每一个外键的值必须等于另一个表中主键的某个值

    外键是表的一个字段,不是本表的主键,但是对应另一个表的主键,定义外键后,不允许删除另一个表中具有关联关系的行

    定义一个 员工部门表

    如果将所有的数据放到一张表中的弊端:

    1 结构不清晰

    2 浪费空间

    3 库扩展性差 -–-–--—>不可忽视的弊端

    类似于将所有python代码放到了一个py文件中,强耦合到了一起,解耦合,拆分表

    拆分表解决以上问题

    需要给两张表之间,建立一种强而有力的关系,使用 “外键”

    分析步骤:
    #1、先站在左表的角度去找
    是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)
    
    #2、再站在右表的角度去找
    是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
    
    #3、总结:
    #多对一:
    如果只有步骤1成立,则是左表多对一右表
    如果只有步骤2成立,则是右表多对一左表
    
    #多对多
    如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系
    
    #一对一:
    如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可
    

    总结:反射单向 多对一 的表关系,称之为 一对多 的外键关系

    创建两张表

    ​ 1 必须先建立被关联表,在建立关联表

    【实例 1】为了展现表与表之间的外键关系,本例在 test_db 数据库中创建一个部门表 tb_dept1,表结构如下表所示。

    字段名称 数据类型 备注
    id INT(ll) 部门编号
    name VARCHAR(22) 部门名称
    location VARCHAR(22) 部门位置

    创建 tb_dept1 的 SQL 语句运行结果如下所示。

    mysql> CREATE TABLE tb_dept1
        -> (
        -> id INT(11) PRIMARY KEY,
        -> name VARCHAR(22) NOT NULL,
        -> location VARCHAR(50)
        -> );
    Query OK, 0 rows affected (0.37 sec)
    

    创建数据表 tb_emp6,并在表 tb_emp6 上创建外键约束,让它的键 deptId 作为外键关联到表 tb_dept1 的主键 id,输入的 SQL 语句和运行结果如下所示。

    mysql> CREATE TABLE tb_emp6
        -> (
        -> id INT(11) PRIMARY KEY,
        -> name VARCHAR(25),
        -> deptId INT(11),
        -> salary FLOAT,
        -> CONSTRAINT fk_emp_dept1
        -> FOREIGN KEY(deptId) REFERENCES tb_dept1(id)
        -> );
    Query OK, 0 rows affected (0.37 sec)
    mysql> DESC tb_emp6;
    +--------+-------------+------+-----+---------+-------+
    | Field  | Type        | Null | Key | Default | Extra |
    +--------+-------------+------+-----+---------+-------+
    | id     | int(11)     | NO   | PRI | NULL    |       |
    | name   | varchar(25) | YES  |     | NULL    |       |
    | deptId | int(11)     | YES  | MUL | NULL    |       |
    | salary | float        | YES  |     | NULL    |       |
    +--------+-------------+------+-----+---------+-------+
    4 rows in set (1.33 sec)
    

    提示:关联指的是关系数据库中,相关表之间的联系。它是通过相同的属性或属性组来表示的。子表的外键必须关联父表的主键,且关联字段的数据类型必须匹配,如果类型不一样,则创建子表时会出现错误“ERROR 1005(HY000):Can't create table'database.tablename'(errno:150)”。

    #多对多
    三张表:出版社,作者信息,书
    
    多对多:一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即多对多
      
    关联方式:foreign key+一张新的表
    
       - 利用第三张表,为两张表建立“多对多外键关系”。
            - 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_id, author_id必须存在
            insert into book2author(book_id, author_id) values (4, 4);
    
    #一对一
    两张表:学生表和客户表
    一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系
    关联方式:foreign key+unique
    两张表之间的关系 一一对应,将一张数据量比较大的表,拆分成两张表。
    
    #一定是student来foreign key表customer,这样就保证了:
    #1 学生一定是一个客户,
    #2 客户不一定是学生,但有可能成为一个学生
    
    
    create table customer(
    id int primary key auto_increment,
    name varchar(20) not null,
    qq varchar(10) not null,
    phone char(16) not null
    );
    
    
    create table student(
    id int primary key auto_increment,
    class_name varchar(20) not null,
    customer_id int unique, #该字段一定要是唯一的
    foreign key(customer_id) references customer(id) #外键的字段一定要保证unique
    on delete cascade
    on update cascade
    );
    
    
    #增加客户
    insert into customer(name,qq,phone) values
    ('李飞机','31811231',13811341220),
    ('王大炮','123123123',15213146809),
    ('守榴弹','283818181',1867141331),
    ('吴坦克','283818181',1851143312),
    ('赢火箭','888818181',1861243314),
    ('战地雷','112312312',18811431230)
    ;
    
    
    #增加学生
    insert into student(class_name,customer_id) values
    ('脱产3班',3),
    ('周末19期',4),
    ('周末19期',5)
    ;
    两张表之间的关系 一一对应,将一张数据量比较大的表,拆分成两张表。
    
  • 相关阅读:
    C#:新邮件监听及搜索
    PHPexcel导入数据的时候出现object解决方法
    selectpage选择订单的时候,订单数量和金额会动态改变
    三、变量的简述
    TP框架where条件和whereOr条件同时使用
    一.OS运行机制
    二.进制简述
    1.go语言入门
    C# Redis学习系列二:Redis基本设置
    C# Redis学习系列一:Redis的认识、下载、安装、使用
  • 原文地址:https://www.cnblogs.com/kai-/p/12030037.html
Copyright © 2011-2022 走看看