【MySQL】表的约束

前言

在MySQL中,给表设置约束能有效的保证数据的完整性和准确性,例如数据类型其实就是一种约束。但是光有数据类型作为约束是不够的,需要一些额外的约束来保证数据的合法性,下面就介绍一些常见的约束及其用法。

空属性

空属性包括null和not null这两个值。如果表中某个字段(列)是not null,那么在后面插入数据时该字段的值就不能为null(默认为null)。注意null和空格字符串的区别,null是表示该字段没有值,而空格字符串是表示该字段有值,只不过是空格。并且,null是没有办法参与运算的

案例

创建一个班级表,包含班级名和班级所在的教室。
要求:班级名和班级所在的教室否不能为空

演示
在这里插入图片描述
如果对非空属性字段设置空值,就会报错。
在这里插入图片描述

默认值

如果我们想对表中某一字段设置一个默认值,在插入数据时不指明该字段,该字段的值就是默认值。否则就使用用户插入的值。该约束的关键字是default

案例

创建一个学生表,字段包括姓名,年龄、性别
要求:姓名不能为空,年龄默认值为18,性别默认为男
在这里插入图片描述
上图案例中创建的student表中的age字段和sex字段就有默认值约束,如果不指定该列数据,就会使用默认值。
在这里插入图片描述
在这里插入图片描述

值得注意的是,插入数据时,如果省略某列不写,mysql会先检查有没有设置default值,没有就会报错。而如果指名某列的值为NULL时,mysql会再去检查该字段是不是非空的。检查default和NULL约束的时机是不一样的,default在前面。这是关于报错优先级的一个区别。

列描述

列描述:comment,没有实际含义,就是给字段添加备注的。
在这里插入图片描述
注意,用desc是查看不了表中的comment信息的,可以使用show create table查看。

zerofill

zerofill是一种属性,用于在整数类型中填充零以达到指定的显示宽度。当使用zerofill时,mysql会自动将该列设置为unsigned,即不能为负值。可以将zerofill看成是格式化输出的一种方式。

在这里插入图片描述
我们可以看到,如果插入数据的宽度小于指定的宽度,zerofill约束就会在前面补上0。如果大于指定宽度,那就不显示前置0,比如:
在这里插入图片描述

主键(重点)

主键:primary key用来唯一的约束该字段的数据,不能重复且不能为空,一张表中最多包含一个主键。

创建表时指定主键

在这里插入图片描述

主键约束

主键对应的字段不能是重复的也不能为空,否则插入失败,如下面案例
在这里插入图片描述

添加主键

当表创建好之后添加主键

alter table 表名 add primary key(字段列表)

在这里插入图片描述

删除主键

删除主键可以使用下面sql语句

alter table 表名 drop primary key;

在这里插入图片描述

复合主键

如果有多个字段需要设置为主键,可以使用复合主键。复合键中字段的组合是唯一的,且每个字段都不能为空
在这里插入图片描述
注意与单列主键的区别,复合主键的唯一性是指主键的所有字段的组合是唯一的,比如
在这里插入图片描述
上图中由于id只是主键中的一个字段,所以单单id相同也是能插入的。但是id和name不能分别都相同。

自增长

关键字:auto_increment当auto_increment约束的字段没有指定插入数据,那么系统会默认将上一个值+1并赋予该字段。通常与主键搭配使用。

下面创建一张学生表,并将id字段设为自增。
在这里插入图片描述
下面插入数据时不指明id,观察系统会为其设置什么值:
在这里插入图片描述
即使没有指定插入id数值,系统会默认将id从1开始每次加1。如果中间我们手动指明了其id值,那下一次自增系统的默认值就是这次+1。比如:
在这里插入图片描述
如何查看下一个自增字段的默认值呢?可以使用show create table语句查看
在这里插入图片描述

唯一键

一张表中往往有许多地段是唯一的,比如学生的身份证号以及学号,但是一张表中只有一个主键。于是我们可以将那些非主键有需要唯一性的字段添加unique约束。
在这里插入图片描述
和主键不一样的是,unique并不会影响字段是否可以为空

外键

外键:foreign key用于定义主表和从表之间的关系。外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。定义外键时,要求外键列数据必须在主表中存在或为null。

foreign key (字段名) references 主表() 

比如某数据库现有两张表,一张学生表,一张班级表:
在这里插入图片描述
我们可以认为学生表是班级表的一个从表,班级表是学生表的主表。每个学生都要有唯一的一个班级id,对于班级表来说,可以有多个学生对于一个班级id。不可能存在一个学生的班级id不在班级班级表中
于是在创建表的时候,我们可以键学生表和班级表联系起来,建立表与表之间之间的关系
先建立主表
在这里插入图片描述
再建立从表
在这里插入图片描述
foreign key (class_id) references class0(id)语句表示,在student0表中建立外键约束,将class_idclass表中的id字段建立关联

在这里插入图片描述

综合案例

有一个商店的数据,记录客户及购物情况,有以下三个表组成:

  1. 商品goods(商品编号goods_id,商品名goods_name, 单价unitprice, 商品类别category, 供应商provider)
  2. 客户customer(客户号customer_id,姓名name,住址address,邮箱email,性别sex,身份证card_id)
  3. 购买purchase(购买订单号order_id,客户号customer_id,商品号goods_id,购买数量nums)

要求:

  • 每个表的主外键
  • 客户的姓名不能为空
  • 邮箱不能重复
  • 客户的性别只能是男或者女

思路:
商品表的主键是商品id,客户表的主键是客户d,订单表的主键是订单号。订单表有两个外键,一个是客户号,一个是商品号。客户表和商品表是订单表的主表。

-- 创建数据库
create database if not exists bit32mall
default character set utf8 ;
-- 选择数据库
use bit32mall;
-- 创建数据库表
-- 商品
create table if not exists goods
(
   goods_id  int primary key auto_increment comment '商品编号',
   goods_name varchar(32) not null comment '商品名称',
   unitprice  int  not null default 0 comment '单价,单位分',
   category  varchar(12) comment '商品分类',
   provider  varchar(64) not null comment '供应商名称'
);
-- 客户
create table if not exists customer
(
   customer_id  int primary key auto_increment comment '客户编号',
   name varchar(32) not null comment '客户姓名',
   address  varchar(256) comment '客户地址',
   email  varchar(64) unique key comment '电子邮箱',
   sex  enum('男','女') not null comment '性别',
   card_id char(18) unique key comment '身份证'
);
-- 购买
create table if not exists purchase
(
   order_id  int primary key auto_increment comment '订单号',
   customer_id int comment '客户编号',
   goods_id  int comment '商品编号', 
   nums  int default 0 comment '购买数量',
   foreign key (customer_id) references customer(customer_id),
   foreign key (goods_id) references goods(goods_id)
);

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-08 18:56:03       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-08 18:56:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-08 18:56:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-08 18:56:03       20 阅读

热门阅读

  1. 11本AI人工智能相关电子书推荐(带下载地址)

    2024-06-08 18:56:03       11 阅读
  2. 深度学习 - PyTorch简介

    2024-06-08 18:56:03       6 阅读
  3. springAMQP(示例)

    2024-06-08 18:56:03       8 阅读
  4. QT5.5.0中使用lambda表达式时遇到的问题

    2024-06-08 18:56:03       6 阅读
  5. C++的算法:拓扑排序的原理及应用

    2024-06-08 18:56:03       5 阅读
  6. 百度大模型算法实习岗上岸经验分享!

    2024-06-08 18:56:03       10 阅读
  7. 矩阵相乘torch.einsum()

    2024-06-08 18:56:03       8 阅读
  8. mybatisplus QueryWrapper or 写法

    2024-06-08 18:56:03       10 阅读
  9. window.clearInterval(timer) 清除定时器

    2024-06-08 18:56:03       12 阅读
  10. Docker

    Docker

    2024-06-08 18:56:03      8 阅读
  11. Redis命令使用示例(一)

    2024-06-08 18:56:03       9 阅读