📢博客主页:https://blog.csdn.net/2301_779549673
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨
文章目录
📢前言
表的约束:表中一定要有各种约束,通过约束,让我们未来插入数据库表中的教据是符合预期的。约束本质是通过技术手段,倒通程序员,插入正确的数据。反过来,站在
mysql
的视角,凡是插入进来的数据,都是符合数据约束的!
约束的最终目标:保证数据的完整性和可预期性
真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。
表的约束很多,这里主要介绍如下几个:
null/not null,default
,
comment
,
zerofill
,
primary key
,
auto_increment
,
unique key
。
🏳️🌈1、空属性 - NULL
两个值:
null
(默认的) 和
not null
(不为空)
数据库默认字段都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。
案例:
创建一个班级表,包含班级名和班级所在的教室。
站在正常的业务逻辑中:
- 如果班级没有名字,你不知道你在哪个班级
- 如果教室名字可以为空,就不知道在哪上课
所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这
就是“约束”。
mysql> create table ifnot exists myclass(-> class_name varchar(20)not null,-> class_room varchar(20)not null,-> other varchar(20)->);
Query OK,0 rows affected(0.02 sec)
mysql> desc myclass;+------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+------------+-------------+------+-----+---------+-------+| class_name |varchar(20)| NO ||NULL||| class_room |varchar(20)| NO ||NULL||| other |varchar(20)| YES ||NULL||+------------+-------------+------+-----+---------+-------+3 rows in set(0.01 sec)
NULL列表示的就是这一列的空属性,默认为空,加上
not null
就不为空
- 先按正常逻辑插入一行完整的数据
mysql> insert into myclass(class_name, class_room, other)values('高三2班','101教室','普通班');
Query OK,1 row affected(0.00 sec)
mysql> select* from myclass;+------------+------------+-----------+| class_name | class_room | other |+------------+------------+-----------+| 高三2班 |101教室 | 普通班 |+------------+------------+-----------+1 row in set(0.00 sec)
顺利插入,并打印出来了
- 试试 other 字段不插入
mysql> insert into myclass(class_name, class_room)values('高三3班','103教室');
Query OK,1 row affected(0.01 sec)
mysql> select * from myclass;+------------+------------+-----------+| class_name | class_room | other |+------------+------------+-----------+| 高三2班 |101教室 | 普通班 || 高三3班 |103教室 |NULL|+------------+------------+-----------+2 rows in set(0.00 sec)
顺利插入,且无影响,不过
other
字段为空
- 试试 not null 属性字段不插入
mysql> insert into myclass(class_name)values('高三4班');
ERROR 1364(HY000): Field 'class_room' doesn't have a default value
mysql> insert into myclass(class_name, class_room)values('高三4班', null);
ERROR 1048(23000): Column 'class_room' cannot be null
mysql> insert into myclass(class_name, class_room)values(null, null);
ERROR 1048(23000): Column 'class_name' cannot be null
可见,对于
if not null
属性的字段,不论是不插入任何数据,还是把插入数据设为 null ,都无法成功插入
🏳️🌈2、默认值 - DEFAULT
默认值:某一种数据会经常性地出现某个具体地值,可以再一开始就指定好的,在需要真实数据的时候,
用户可以选择性的使用默认值。
假设有一个相亲网站,年龄默认 18 , 性别默认 男
mysql> create table ifnot exists t13(-> name varchar(20)not null,-> age tinyint unsigneddefault18,-> gender char(1)default'男'->);
Query OK,0 rows affected(0.01 sec)
mysql> desc t13;+--------+---------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+---------------------+------+-----+---------+-------+| name |varchar(20)| NO ||NULL||| age |tinyint(3)unsigned| YES ||18||| gender |char(1)| YES || 男 ||+--------+---------------------+------+-----+---------+-------+3 rows in set(0.00 sec)
- 先试试是否有用
mysql> insert into t13(name, age, gender)values('张三',19,'男');
Query OK,1 row affected(0.01 sec)
mysql> select * from t13;+--------+------+--------+| name | age | gender |+--------+------+--------+| 张三 |19| 男 |+--------+------+--------+1 row in set(0.00 sec)
有效!
- 插入一行只有姓名的数据
mysql> insert into t13(name)values('李四');
Query OK,1 row affected(0.01 sec)
mysql> select * from t13;+--------+------+--------+| name | age | gender |+--------+------+--------+| 张三 |19| 男 || 李四 |18| 男 |+--------+------+--------+2 rows in set(0.00 sec)
成功补齐了默认值
可以得出结论,default:如果设置了,用户将来插入,有具体的数据,就用用户的,没有就用默认的
- 倘若当前值为 Not null 并且还有默认值时
mysql> create table ifnot exists t14(-> name varchar(20)not null,-> age tinyint default18,-> gender char(1)not null default'男'->);
Query OK,0 rows affected(0.02 sec)
mysql> desc t14;+--------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+-------------+------+-----+---------+-------+| name |varchar(20)| NO ||NULL||| age |tinyint(4)| YES ||18||| gender |char(1)| NO || 男 ||+--------+-------------+------+-----+---------+-------+3 rows in set(0.00 sec)
mysql> show create table t14;+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table | Create Table |+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+| t14 | CREATE TABLE `t14` (
`name` varchar(20) NOT NULL,
`age` tinyint(4) DEFAULT '18',
`gender` char(1) NOT NULL DEFAULT '男') ENGINE=InnoDB DEFAULT CHARSET=utf8 |+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set(0.00 sec)
插入一行数据试试
mysql> insert into t14(age, gender)values(20,'男');
ERROR 1364(HY000): Field 'name' doesn't have a default value
mysql> insert into t14(name, age, gender)values('张三',20,'男');
Query OK,1 row affected(0.00 sec)
mysql> insert into t14(name, gender)values('赵六','女');
Query OK,1 row affected(0.01 sec)
mysql> select * from t14;+--------+------+--------+| name | age | gender |+--------+------+--------+| 张三 |20| 男 || 赵六 |18| 女 |+--------+------+--------+2 rows in set(0.00 sec)
可见,
- 如果我们没有明确指定一列要插入,用的是default,如果建表中,对应列默认没有设置default值,无法直接插入
- default和NOTNULL不冲突,而是互相补充的
🏳️🌈3、列描述 - comment
列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA
来进行了解。
mysql> create table ifnot exists t16(-> name varchar(20)not null comment '这个是用户的用户名',-> age tinyint unsigneddefault18 comment '这个是用户的年龄',-> gender char(1)default'男' comment '这个是用户的性别'->);
Query OK,0 rows affected(0.03 sec)
mysql> desc t16;+--------+---------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+---------------------+------+-----+---------+-------+| name |varchar(20)| NO ||NULL||| age |tinyint(3)unsigned| YES ||18||| gender |char(1)| YES || 男 ||+--------+---------------------+------+-----+---------+-------+3 rows in set(0.00 sec)
mysql> show create table t16;+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table | Create Table |+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| t16 | CREATE TABLE `t16` (
`name` varchar(20) NOT NULL COMMENT '这个是用户的用户名',
`age` tinyint(3)unsigned DEFAULT '18' COMMENT '这个是用户的年龄',
`gender` char(1) DEFAULT '男' COMMENT '这个是用户的性别') ENGINE=InnoDB DEFAULT CHARSET=utf8 |+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set(0.00 sec)
mysql> insert into t16(name, age, gender)values('张三',122,'男');
Query OK,1 row affected(0.00 sec)
mysql> select * from t16;+--------+------+--------+| name | age | gender |+--------+------+--------+| 张三 |122| 男 |+--------+------+--------+1 row in set(0.00 sec)
能正常插入,但是一般不能通过
desc
查看注释信息,需要通过
show
查看
🏳️🌈4、 zerofill - 显示数值时用零(0)填充到列定义的显示宽度
ZEROFILL
是
MySQL
数据库中的一个属性,主要用于数值类型的列(如INT、BIGINT等)。当在列定义中使用
ZEROFILL
属性时,它会使
MySQL
在显示数值时用零(0)填充到列定义的显示宽度。
mysql> create table ifnot exists t17(-> a intunsignednot null,-> b intunsignednot null
->);
Query OK,0 rows affected(0.02 sec)
mysql> desc t17;+-------+------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+------------------+------+-----+---------+-------+| a |int(10)unsigned| NO ||NULL||| b |int(10)unsigned| NO ||NULL||+-------+------------------+------+-----+---------+-------+2 rows in set(0.00 sec)
mysql> show create table t17;+-------+----------------------------------------------------------------------------------------------------------------------------+| Table | Create Table |+-------+----------------------------------------------------------------------------------------------------------------------------+| t17 | CREATE TABLE `t17` (
`a` int(10)unsigned NOT NULL,
`b` int(10)unsigned NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 |+-------+----------------------------------------------------------------------------------------------------------------------------+1 row in set(0.00 sec)
插入数据看看
mysql> insert into t17(a, b)values(2,3);
Query OK,1 row affected(0.00 sec)
mysql> select * from t17;+---+------+| a | b |+---+------+|2|3|+---+------+1 row in set(0.00 sec)
能正常显示
为 b 字段设置
zerofill
属性
mysql> alter table t17 modify b intunsigned zerofill;
Query OK,0 rows affected(0.00 sec)
Records:0 Duplicates:0 Warnings:0
mysql> desc t17;+-------+---------------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+---------------------------+------+-----+---------+-------+| a |int(10)unsigned| NO ||NULL||| b |int(10)unsigned zerofill | YES ||NULL||+-------+---------------------------+------+-----+---------+-------+2 rows in set(0.00 sec)
mysql> select * from t17;+---+------------+| a | b |+---+------------+|2|0000000003|+---+------------+1 row in set(0.00 sec)
b 字段多了
zerofill
属性,数据也补齐到了10位
这次可以看到b的值由原来的3变成0000000003,这就是zerofill属性的作用,如果宽度小于设定的宽度,自动填充0。要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是1。
🏳️🌈5、主键 - primary key
主键: primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个
主键: 主键所在的列通常是整数类型
mysql> create table ifnot exists test_key(-> id intunsigned primary key,-> name varchar(20)not null
->);
Query OK,0 rows affected(0.02 sec)
mysql> desc test_key;+-------+------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+------------------+------+-----+---------+-------+| id |int(10)unsigned| NO | PRI |NULL||| name |varchar(20)| NO ||NULL||+-------+------------------+------+-----+---------+-------+2 rows in set(0.00 sec)
mysql> show create table test_key\G
***************************1. row ***************************
Table: test_key
Create Table: CREATE TABLE `test_key` (
`id` int(10)unsigned NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY(`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set(0.00 sec)
插入两个主键值相同的数据试试
mysql> insert into test_key values(1,'张飞');
Query OK,1 row affected(0.01 sec)
mysql> select * from test_key;+----+--------+| id | name |+----+--------+|1| 张飞 |+----+--------+1 row in set(0.00 sec)
mysql> insert into test_key values(1,'刘备');
ERROR 1062(23000): Duplicate entry '1'for key 'PRIMARY'
失败了
主键还能作为坐标进行增删查改
mysql> insert into test_key values(2,'刘备');
Query OK,1 row affected(0.01 sec)
mysql> select * from test_key;+----+--------+| id | name |+----+--------+|1| 张飞 ||2| 刘备 |+----+--------+2 rows in set(0.00 sec)
mysql> update test_key set name='曹操' where id =2;
Query OK,1 row affected(0.00 sec)
Rows matched:1 Changed:1 Warnings:0
mysql> select * from test_key;+----+--------+| id | name |+----+--------+|1| 张飞 ||2| 曹操 |+----+--------+2 rows in set(0.00 sec)
👥总结
本篇博文对 【MySQL】表的约束(上) 做了一个较为详细的介绍,不知道对你有没有帮助呢
觉得博主写得还不错的三连支持下吧!会继续努力的~
版权归原作者 JhonKI 所有, 如有侵权,请联系我们删除。