mysql 一对多约束条件_MySQL数据库/约束条件与表关系.md · 静谧之裳/python-learn - Gitee.com...

# 一、约束条件

**约束条件**

|约束条件|说明|

|:---:|:---:|

|`zerofill`|零值填充约束|

|`unsigned`|无符号约束|

|`not null`|非空约束|

|`default`|默认值约束|

|`unique key`|唯一约束 |

|`auto_increment`|自增长约束|

| `primary key` |主键约束|

| `foreign key` |外键约束|

## 1.1 `zerofill`零值填充约束

**当传入字段的数据宽度不够时,使用0进行填充**

```sql

create table zero_fill(id int(3) zerofill);

insert into zero_fill values(1);

select * from zero_fill;

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1119/233845_f9e60a9a_7841459.png "屏幕截图.png")

## 1.2 `unsigned`无符号约束

**对于数值类型的数据进行的约束**

```sql

create table unsigned_table(id int unsigned);

insert into unsigned_table values(-10),(200); --开启严格模式,插入负数报错

insert into unsigned_table values(0),(200);

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1119/234302_a19242ba_7841459.png "屏幕截图.png")

## 1.3 `not null`非空约束

**非空约束的字段,在插入值时必须进行插入; 如果不插入则报错**

```sql

create table not_null(id int, name varchar(20) not null);

insert into not_null values (1, "小兰");

insert into not_null(id) values (2); -- 非空字段未插入值,报错

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1119/234644_6c0cf0a8_7841459.png "屏幕截图.png")

## 1.4 `default value`默认约束

**插入值时,如果没有指定值;则自动填充默认值**

```sql

create table default_value(id int, gender enum("male", "female", "other") default "male");

insert into default_value(id) values(1); -- 非默认值,要指定字段插入

insert into default_value values(2, "female");

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1119/235145_fcfd9591_7841459.png "屏幕截图.png")

## 1.5 `unique key`唯一约束

**有些字段中的值必须唯一的,使用此约束条件**

* **单列唯一**

```sql

create table unique_key(id int unique key, name char(4));

insert into unique_key values(1, "小明"), (1, "小芳"); -- 报错

insert into unique_key values(1, "小明"), (2, "小芳");

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/000156_97de721e_7841459.png "屏幕截图.png")

* **联合唯一**

> 对于单个字段可以重复,联合起来不能重复,

```sql

create table unique_key2(

id int,

ip varchar(30),

port int,

unique key(ip, port) -- 设置联合唯一

);

insert into unique_key2 values(1, "127.0.0.1", 8080); -- 成功

insert into unique_key2 values(2, "127.0.0.1", 8081); -- 成功

insert into unique_key2 values(2, "127.0.0.1", 8080); -- 失败

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/000756_ffe4f72a_7841459.png "屏幕截图.png")

## 1.6 `primary key`主键约束

> 1. **非空且唯一**

> 2. `Innodb`存储引擎,在创建表时必须使用`primary key`。

> * 一张表中有且只有一个主键

> * 如果没有出现主键约束,则 **第一次出现not null unique key** 约束的做为主键

> * 如果没有设置主键,也没有设置`not null unique key`, `Innodb`会采用内部的隐藏字段做为主键. 这个字段不能使用

> 3. **通常将`id`字段做为表的主键**

```sql

create table primary_key1(id int primary key);

create table primary_key2(

id int not null unique key,

addr char(32) not null unique key

);

create table primary_key3(

id int,

name char(16),

primary key(id, name)

);

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/144527_1bfdf746_7841459.png "屏幕截图.png")

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/144835_aa056826_7841459.png "屏幕截图.png")

## 1.7 `auto_increment` 自增长约束

> 一张表中只有 **一个** 字段自增长。 **非空且唯一** 的字段才可以添加自增长约束

>

> **通常是给主键添加约束的**

>

> 数据删除后,不会清空计数器, 也即是: 自增长继续

>

> **truncate tb_name;** 清空tb_name中的数据,并重置计数器

```sql

create table auto_increment_table(

id int primary key auto_increment,

name char(5)

);

insert into auto_increment_table(name) values("小明"),("小芳");

```

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/145544_ae0eed70_7841459.png "屏幕截图.png")

# 二、表关系

设计数据库时,我们要尽量将不同的信息存放在不同的表之中。

> 1. 解耦合,对于数据的扩展性好。

> 2. 提高了数据的查询和修改效率,降低存储空间。

如果在设计数据库时,将所有数据存放到一个表之中的后果

> 1. 浪费存储空间, 对于不同的记录之间的数据项可能存在相同的数据

> 2. 修改某个字段的效率低, 如果修改的字段存在多个相同的值,那么修改数据时,这些相同的值都会发送改变,增加了数据库服务的压力(**后果非常严重**)

## 2.1 `foreign key`外键约束

> 1. 用于约束字段只能填充某张表中 **已经存在** 的值

> 2. 用于实现表之间的关系

## 2.2 表关系

创建表时,需要考虑表关系;需要双向考虑。

### 2.2.1 一对多

对于 **学生和学院的关系** , **学生只能在一个学院** ,但是 **学院可以有多个学生, _也即是: 多个学生对应一个学院_ **, (学生和学院之间的关系位 **单向一对多关系** , 也即是 **一对多关系** )。

```sql

-- 创建学院表

create table academy(

academy_id int primary key auto_increment,

academy_name varchar(20)

);

-- 创建学生表

create table student(

student_id int primary key auto_increment,

student_name varchar(20),

student_gender int,

ac_id int,

foreign key(ac_id) references academy(academy_id) -- 当前表字段ac_id与 表academy表(academy_id)关联

on update cascade -- 同步更新

on delete cascade -- 同步删除

);

insert into academy(academy_name) values("计算机"),("理学院"),("人文");

insert into student(student_name, student_gender, ac_id) values("小明", 1, 1),("小芳", 2, 3), ("小兰", 2, 3), ("小蓝", 1, 2);

```

> 1. 创建外键约束时,**在多的一方创建外键约束**

> 2. 创建表时,**先创建被关联表**

> 3. 录入数据时,**先录入被关联表**

> 4. **外键约束语法**: **`foreign key(字段) references 表名(字段)`**。

> 5. 被关联表(`academy`)中没有的数据,不能在关联表(`student`)中插入。

> 6. 如果被关联表(`academy`)中的数据被插入到了关联表(`student`),则被关联表(`academy`)中的被关联字段(`academy_id`)的数据不能修改, 也不能删除此条记录。

> 7. 如果要修改被关联表(`academy`)中的被关联字段(`academy_id`)的数据,则应当对关联表(`student`)中的关联字段(`ac_id`)一起修改。

> 8. 如果要删除被关联表(`academy`)中的被关联字段(`academy_id`)的数据,则应当对关联表(`student`)中的关联字段(`ac_id`)一起删除。

> 9. 级联更新,级联删除。**`foreign key(字段) references 表名(字段) on update cascade on delete cascade`**

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/160511_54db8bcf_7841459.png "屏幕截图.png")

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/160536_7032653d_7841459.png "屏幕截图.png")

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/160731_0f373d2a_7841459.png "屏幕截图.png")

![输入图片说明](https://images.gitee.com/uploads/images/2020/1120/160831_95aacc3c_7841459.png "屏幕截图.png")

### 2.2.2 多对多

对于作者和作品的关系;一部作品可以有多个作者编写,一名作者也可以编写多本书。(作者和作品 之间存在 **双向的一对多关** 系,也即是: **多对多关系**)

```sql

-- 创建作者表

create table author(

id int primary key auto_increment,

name varchar(10),

age int,

book_id int,

foreign key(boo_id) references book(id)

on update cascade -- 同步更新

on delete cascade -- 同步删除

);

-- 创建book表

create table book(

id int primary key auto_increment,

book_name varchar(20),

price float,

author_id int,

foreign key(author_id) references author(id)

on update cascade -- 同步更新

on delete cascade -- 同步删除

);

```

> 如果这样创建表存在如下问题

> 1. 创建表`author`时,需要关联`book`表,此时`author`表无法创建。

> 2. 创建表`book`时,需要关联`author`表,此时`book`表无法创建。

>

因此创建多多关系表时,需要两外创建一张关系表,用于存放两张表的关系

```sql

create table author(

id int primary key auto_increment,

name varchar(10),

age int

);

-- 创建book表

create table book(

id int primary key auto_increment,

book_name varchar(20),

price float

);

--- 创建book和author关系表

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 -- 同步删除

);

```

> 1. 数据表之间不存在关系

> 2. 它们之间的关系由第三张表体现

> 3. 操作数据,受到影响的只是对三张表(关系表)

### 2.2.3 一对一

对于一张有很多字段的表,通常都会将表拆分为多个表.

> **好处**

> 1. 查询时,不用一次性的查询出全部的信息;节省数据传输时间

> 2. 可以更好的包含用户的数据安全

对于用户表,会有各种各样的字段信息。通常将表拆分两个表,一张表存放用户的基本信息,另一张表存放用户的详细信息.

```sql

-- 创建用户详情表

create table user_details(

id int primary key auto_increment,

age int,

gender enum("male, female")

);

-- 创建用户表

create table user(

id int primary key auto_increment,

name varchar(20),

user_detail_id int unique,

foreign key(user_detail_id) references user_details(id)

on update cascade -- 同步更新

on delete cascade -- 同步删除

);

```

> 1. 一对一关系的表的外键字段,通常建立在**查询频率最高的表中**

> 2. 一对一关系的表的关键字段通常需要给 **唯一约束** .

# 三、表结构修改

1. 修改表名

```sql

alter table old_tb_name rename to new_tb_name;

```

2. 添加字段

```sql

alter table tb_name add 字段名 字段类型(宽度) 约束条件;

alter table tb_name add 字段名 字段类型(宽度) 约束条件 first;

alter table tb_name add 字段名 字段类型(宽度) 约束条件 after 字符名;

```

3. 删除字段

```sql

alter table tb_name drop 字段名

```

4. 修改字段

```sql

alter table tb_name modify 字段名 字段类型(宽度) 约束条件;

alter table tb_name change 旧字段名 新字段名 新字段类型(宽度) 约束条件;

```

# 四、复制表

`sql`语句查询的结果也是一张表, 从旧表复制数据给新表

```sql

create table new_table_name select * from old_table_name;

```

> 1. 不能复制主键,外键,索引

> 2. 只能复制表结构和数据

```sql

create table new_table_name select * from od_table_name where ...;

```

> 如果后面的条件没有对应数据,也会创建表出来

一键复制

编辑

Web IDE

原始数据

按行查看

历史

你可能感兴趣的:(mysql,一对多约束条件)