0


【MySQL】表的约束(上)详解

📢博客主页: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

就不为空

  1. 先按正常逻辑插入一行完整的数据
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)

顺利插入,并打印出来了

  1. 试试 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

字段为空

  1. 试试 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)
  1. 先试试是否有用
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)

有效!

  1. 插入一行只有姓名的数据
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:如果设置了,用户将来插入,有具体的数据,就用用户的,没有就用默认的

  1. 倘若当前值为 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】表的约束(上) 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述

标签: mysql android 数据库

本文转载自: https://blog.csdn.net/2301_77954967/article/details/144346175
版权归原作者 JhonKI 所有, 如有侵权,请联系我们删除。

“【MySQL】表的约束(上)详解”的评论:

还没有评论