👦个人主页:@Weraphael
✍🏻作者简介:目前学习计网、mysql和算法
✈️专栏:MySQL学习
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨
前言
在数据类型篇章,我们证明了数据类型本身就是一种约束!通过约束,数据库可以保证数据的合法性和准确性,避免不合法或无效的数据进入数据库。但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是
- 表的约束很多,这里主要介绍如下八个:
- 空属性
null/not null
- 默认值
default
- 列描述
comment
zerofill
- 主键
primary key
- 自增长
auto_increment
- 唯一键
unique key
- 外键
目录
- 前言
- 一、空属性null/not null
- 二、默认值default
- 三、列描述comment
- 四、zerofill
- 五、主键primary key
- 六、自增长auto_increment
- 七、唯一键unique
- 八、外键
- 九、综合案例
一、空属性null/not null
在 MySQL
中,当创建表时,可以使用 null
或 not null
来定义列是否允许存储null
值。
null
:表示该列可以存储null
值。not null
:表示该列不允许存储null
值。
注意:如果不明确指定列的空属性,默认情况下,列的默认值就是null
值。如果希望某列不允许为空,则需要显式地将其设置为 not null
。
- 注意:区分空值
``
和null
值在
MySQL
中,空值表示字段中没有具体数值或内容,但仍然有数据类型;而null
值表示缺少值或未知值,实际上是真的没有值。
【语法】
字段 数据类型 [not null];
这种约束其实在生活中非常常见,比如要报考四级,那么就必须去官网报名,而报名的前提就是要注册。当我们看到注册列表前有*
,那么说明此信息必填,如果有其中一个不填,那么系统就不让你注册,这就是空属性的约束。
【使用案例】
创建一个班级表供学生使用,包含班级名、班级所在的教室和授课老师。
站在正常的业务逻辑中:
- 如果班级没有名字,你不知道你在哪个班级。
- 如果教室名字可以为空,就不知道在哪上课。
- 而老师学生一般不怎么关心,只要能到班级上课就行
所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这就是 【约束】
- 建表
- 查看表结构
YES
代表字段的值可以为空null
,而NO
代表字段的值不可为null
- 向表中插入数据
如果不对class_name
和class_room
插入元素或者插入的值为null
,那么必定会触发错误。
二、默认值default
在MySQL
数据库中,可以为表中的列设置默认值。它的作用是:如果没有为该列提供值,将会自动使用默认值填充该列(默认情况下,列的默认值就是null
值),如果有则使用用户提供的值。(类似于C++
的默认参数)
【用法】
如果不对gender
字段插入指定数据,那么就会使用默认值'男'
三、列描述comment
在MySQL
中,使用comment
关键字可以为字段添加描述信息,以便记录该列的含义、用途或其他相关信息。这些描述信息对于开发人员、数据库管理员和其他使用者来说都是非常有用的,可以帮助他们更好地理解和使用数据库表的结构。(本质上就是注释)
在MySQL
中,可以通过以下方式为列添加描述:
那么开发人员要如何查看这些描述信息呢?使用以下命令
show create table [表名] \G
# \G - 人性化显示
四、zerofill
在MySQL
中,zerofill
是一种列属性,一般用于无符号整型数据类型。其作用是:在显示数值型字段时,在该字段值的前面填充零,以达到指定的位数。这主要用于美化数据展示和保持数据的一致性。(本质上就是格式化输出)
【语法】
# 以int整型为例
字段 int(num) unsigned zerofill
一般情况下,其中num
表示字段的显示宽度,即显示的最大位数。如果不显示指定num
,默认num = 10
【使用案例】
例如,如果创建了一个表d9
,并且指定了一个 zerofill
属性的整数列,当在该列中插入一个数字时,MySQL
会用零来填充该数字,直到达到指定的位数。这样有助于保持数据的可读性和一致性。
如果插入一个值为1
的记录到num
列中,MySQL
将会以零填充,直到达到指定位数,显示为001
。
但是如果插入的值的位数超过了指定位数,那么还是以插入的值为保准来存储,不会发生截断
需要注意的是,使用zerofill
属性仅影响在查询结果中显示的值,实际存储在数据库中的值并不会被修改。
五、主键primary key
在MySQL
中,主键是用于唯一标识表中每一行数据的字段或字段组合。主键具有以下特性:
- 唯一性:主键列的值必须是唯一的,不允许出现重复的值。
- 非空:主键列的值不能为
NULL
,即不能为空。 - 一张表只能有一个主键。
通常情况下,可以通过在创建表时使用primary key
关键字来指定主键,示例如下:
# 写法一:
create table 表名(
id int primary key,
name varchar(32)
);
# 写法二:
create table 表名(
id int,
name varchar(32),
primary key(id)
);
注:Key
字段代表索引信息。如果Key
字段为PRI
,表示该列是表的主键。
在上述示例中,id
字段被指定为主键。如果需要多个字段作为主键,可以使用复合主键:
create table 表名(
字段1 类型,
字段2 类型,
...
primary key(字段1, 字段2, ...)
);
这里要注意复合主键的唯一性,要将复合主键看成一对。在上面的示例中,(字段1, 字段2)
组合成了一个复合主键。这意味着每一组(字段1, 字段2)
的值必须是唯一的,确保了表中的每行数据都有一个唯一标识符。
假设只有一对复合主键(a, b)
,且有数据(1,1)
,如果插入(1,2)
或者(2,1)
并不会触发唯一性约束,因为每个单独的值并不会导致复合主键重复。只有当插入的复合主键值正好与现有行的复合主键值完全相同时,比如 (1, 1)
,才会触发唯一性约束。
【其他操作】
- 添加主键
添加的前提:所添加主键的字段必须满足非空性和唯一性。建议:在建表时就把主键确定下来。
alter table 表名 add primary key(字段1, 字段2, ...);
- 删除主键
alter table 表名 drop primary key;
六、自增长auto_increment
在MySQL
中,可以通过使用自增长来为表中的某一列创建自增长的值。当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1
操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
特点如下:
- 任何一个字段要做自增长,前提是主键
- 自增长字段必须是整数
【使用案例】
那我们怎么知道当前字段中的最大值是多少呢?
- 使用函数
last_insert_id
select last_insert_id();
因此,MySQL
默认是从0
开始自增长的。当插入新行数据时,可以不必指定自增长列的值,数据库会自动为该列分配下一个可用的自增值。
七、唯一键unique
一个人的信息往往有很多需要唯一性,也就是说数据不能重复,但是一张表中只能有一个主键。
因此在MySQL
中,唯一键就可以解决表中有多个字段需要唯一性约束的问题。
这样一看,唯一键好像和主键差不多,可其实并不是。主键除了保证数据的唯一性,还要保证非空性,而唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
然而,如果在一个唯一键字段上再增加一个非空约束,那么这个字段的属性就和主键相似了。
但还是会有些区别:我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。
八、外键
以上学习的约束都是内聚在一张表内的某一字段。在MySQL
中,外键是一种用于建立 表与表之间关联关系的约束。
外键常用于定义主表和从表之间的关系,那什么是主表?什么是从表呢?
- 首先,外键所在的表是从表,被外键关联的表是主表( 外键约束要定义在从表上)
- 被外键关联的主表的列必须是唯一的(主表则必须是有主键约束或
unique
约束)
当定义外键后,要求外键列数据必须在主表的主键列存在或为null
。并且如果主表的某列被从表引用为外键,那么这个主表的列不能进行任何修改!
【语法】
foreign key (从表字段名) references 主表名(列)
【使用案例】
对上面的示意图进行设计:
- 先创建主键表
myclass
- 再创建从表
- 插入数据
【主表】
【从表】
- 向学生表
stu
插入一个班级号为3
的学生,由于myclass
表中没有这个班级,所以受外键约束,插入不成功
- 插入班级
id
为null
,比如来了一个学生,目前还没有分配班级
九、综合案例
有一个商店的数据,记录客户及购物情况,有以下三个表组成:
-
商品
goods
(商品编号goods_id
,商品名goods_name
, 单价unitprice
, 商品类别category
, 供应商provider
) -
客户
customer
(客户号customer_id
,姓名name
,住址address
,邮箱email
,性别sex
,身份证card_id
) -
购买
purchase
(购买订单号order_id
,客户号customer_id
,商品号goods_id
,购买数量nums
)
- 创建商品数据库表
create table goods(
good_id int primary key auto_increment comment '商品编号',
goods_name varchar(32) not null comment '商品名',
unitprice float not null comment '商品单价',
category varchar(32) set('零食','饮料', '生活用品') not null comment '商品类别',
provider varchar(32) not null comment '供应商'
);
- 创建客户数据库表
create customer(
customer_id int primary key auto_increment comment '客户编号',
customer_name varchar(32) not null comment '客户姓名',
address varchar(256) not null 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 1 comment '购买数量',
foreign key (customer_id) references customer(customer_id),
foreign key (goods_id) references goods(goods_id)
);