外键

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)
;
两张表之间的关系 一一对应,将一张数据量比较大的表,拆分成两张表。
 posted on 2019-12-12 16:35  Rannie`  阅读(347)  评论(2编辑  收藏  举报
去除动画
找回动画