MySQL表的约束(上)

目录

1.表的约束

2.非空约束

3.default约束

列描述

[zerofill( MySQL8.0 移除了 ZEROFILL 特性!)](#zerofill( MySQL8.0 移除了 ZEROFILL 特性!))


1.表的约束

表的约束:表中一定要有各种约束,通过约束,让我们未来插入数据库表中的数据是符合预期的。约束本质是通过技术手段,倒逼程序员,插入正确的数据。
反过来,站在mysql的视角,凡是插入进来的数据,都是符合数据约束的!

约束的最终目标,保证数据的完整性和可预期性

需要更多的约束条件

2.非空约束

空属性

两个值:null(默认的)和not null(不为空)
数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办
法参与运算。

复制代码
mysql> create table if not exists myclass(
    -> class_name varchar(20) not null,
    -> class_room varchar(20) not null,
    -> other varchar(20)
    -> );
Query OK, 0 rows affected (0.01 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.00 sec)

mysql> show create table myclass \G
*************************** 1. row ***************************
       Table: myclass
Create Table: CREATE TABLE `myclass` (
  `class_name` varchar(20) NOT NULL,
  `class_room` varchar(20) NOT NULL,
  `other` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> insert into myclass (class_name,class_room,other) values ('高三2班','101教室','普通班');
Query OK, 1 row affected (0.00 sec)

mysql> insert into myclass (class_name,class_room) values ('高三3班','103教室');
Query OK, 1 row affected (0.00 sec)

mysql> insert into myclass (class_name,class_room) values ('高三3班',NULL);
ERROR 1048 (23000): Column 'class_room' cannot be null

可以看到class_room就不允许是null,这就叫非空约束

3.default约束

默认值

默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。

default:如果设置了,用户将来插入,有具体的数据,就用用户的,没有就用默认的

复制代码
mysql> create table if not exists t13(
    -> name varchar(20) not null,
    -> age tinyint unsigned default 18,
    -> 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.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)


复制代码
mysql> create table t14(
    -> name varchar(20) not null,
    -> age tinyint default 18,
    -> gender char(1) not null default '男'
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t14 (age,gender) values (20,'男');
ERROR 1364 (HY000): Field 'name' doesn't have a default value

如果我们没有明确指定一列要插入,用的是default;如果建表中,对应默认没有设置default值,无法直接插入

default和not null不冲突,而是互相补充的
-default 当用户忽略这一列的时候,使用默认值(如果设置了);如果没有设置,直接报错
-not null 当用户插入的时候-1.null 2.合法数据

-注意:not null和defalut一般不需要同时出现,因为default本身有默认值,不会为空

复制代码
mysql> insert into t14 (name,age,gender) values ('张三',20,NULL);
ERROR 1048 (23000): Column 'gender' cannot be null
mysql> insert into t14 (name,age) values ('张三',20);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t14;
+--------+------+--------+
| name   | age  | gender |
+--------+------+--------+
| 张三   |   20 | 男     |
+--------+------+--------+
1 row in set (0.00 sec)

mysql> insert into t14 (name,age,gender) values ('李四',20,'男');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t14 (name,age,gender) values ('李四',NULL,'男');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t14 (name,gender) values ('李四','男');
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> select * from t14;
+--------+------+--------+
| name   | age  | gender |
+--------+------+--------+
| 张三   |   20 | 男     |
| 李四   |   20 | 男     |
| 李四   | NULL | 男     |
| 李四   |   18 | 男     |
+--------+------+--------+
4 rows in set (0.00 sec)

如果我们建立一个表的时候没有指明对应的默认值,MySQL会对其做优化默认带上DEFAULT_NULL

复制代码
mysql> create table if not exists t15( name varchar(20), age tinyint unsigned);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t15 (name,age) values ('张三',18);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t15 (name,age) values (NULL,18);
Query OK, 1 row affected (0.00 sec)

mysql> select *from t15;
+--------+------+
| name   | age  |
+--------+------+
| 张三   |   18 |
| NULL   |   18 |
+--------+------+
2 rows in set (0.00 sec)

mysql> insert into t15 (age) values (18);
Query OK, 1 row affected (0.00 sec)

mysql> show create table t15 \G
*************************** 1. row ***************************
       Table: t15
Create Table: CREATE TABLE `t15` (
  `name` varchar(20) DEFAULT NULL,
  `age` tinyint(3) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

注意:只有设置了default的列,才可以在插入值的时候,对列进行省略

列描述

列描述:comment,没有实际含义,专门用来描述字段 ,会根据表创建语句保存,用来给程序员或DBA来进行了解。

复制代码
mysql> create table if not exists t16(
    -> name varchar(20) not null comment '这个是用户的用户名',
    -> age tinyint unsigned default 19 comment '这个是用户的年龄',
    -> gender char(1) default '男' comment '这个是用户的性别'
    -> 
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> show create table t16\G
*************************** 1. row ***************************
       Table: t16
Create Table: CREATE TABLE `t16` (
  `name` varchar(20) NOT NULL COMMENT '这个是用户的用户名',
  `age` tinyint(3) unsigned DEFAULT '19' COMMENT '这个是用户的年龄',
  `gender` char(1) DEFAULT '男' COMMENT '这个是用户的性别'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select * from t16;
+--------+------+--------+
| name   | age  | gender |
+--------+------+--------+
| 张三   |   19 | 女     |
+--------+------+--------+
1 row in set (0.00 sec)

mysql> show create table t16\G
*************************** 1. row ***************************
       Table: t16
Create Table: CREATE TABLE `t16` (
  `name` varchar(20) NOT NULL COMMENT '这个是用户的用户名',
  `age` tinyint(3) unsigned DEFAULT '19' COMMENT '这个是用户的年龄',
  `gender` char(1) DEFAULT '男' COMMENT '这个是用户的性别'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

注意:not null和defalut一般不需要同时出现,因为default本身有默认值,不会为空

zerofill( MySQL8.0 移除了 ZEROFILL 特性!)

刚开始学习数据库时,很多人对数字类型后面的长度很迷茫。通过show看看tt3表的建表语句:

复制代码
mysql> show create table tt3\G
***************** 1. row *****************
        Table: tt3
    Create Table: CREATE TABLE `tt3` (
        `a` int(10) unsigned DEFAULT NULL,
        `b` int(10) unsigned DEFAULT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk
    1 row in set (0.00 sec)

可以看到int(10),这个代表什么意思呢?整型不是4字节码?这个10又代表什么呢?其实没有zerofill这个属性,括号内的数字是毫无意义的。a和b列就是前面插入的数据,如下

复制代码
mysql> insert into tt3 values(1,2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tt3;
+------+------+
|  a   |  b   |
+------+------+
|  1   |  2   |
+------+------+

但是对列添加了zerofill属性后,显示的结果就有所不同了。修改tt3表的属性:

复制代码
mysql> alter table tt3 change a a int(5) unsigned zerofill;
mysql> show create table tt3\G
*************************** 1. row ***************************
        Table: tt3
Create Table: CREATE TABLE `tt3` (
    `a` int(5) unsigned zerofill DEFAULT NULL, --具有了zerofill
    `b` int(10) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk
1 row in set (0.00 sec)

对a列添加了zerofill属性,再进行查找,返回如下结果:

复制代码
mysql> select * from tt3;
+-------+------+
|   a   |   b  |
+-------+------+
| 00001 |   2  |
+-------+------+

这次可以看到a的值由原来的1变成00001,这就是zerofill属性的作用,如果宽度小于设定的宽度(这里 设置的是5),自动填充0。要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是1。为什 么是这样呢?我们可以用hex函数来证明。

复制代码
mysql> select a, hex(a) from tt3;
+-------+--------+
|    a  | hex(a) |
+-------+--------+
| 00001 |   1    |
+-------+--------+

可以看出数据库内部存储的还是1,00001只是设置了zerofill属性后的一种格式化输出而已。

MySQL 8.0 移除了 ZEROFILL 特性!

感谢你的观看,期待我们下次再见!

相关推荐
无敌的牛13 小时前
redis学习过程
数据库·redis·学习
IT北辰13 小时前
神通数据库管理系统V7.0.251210 for Windows(x86 64bit)安装部署
数据库·神通
北顾笙98014 小时前
MySQL-day2
数据库·mysql
Demons_kirit14 小时前
新项目如何连接上自己本地的数据库
数据库
洪晓露15 小时前
将 rke2 集群证书延长至 10 年
运维·服务器·数据库
程序猿乐锅15 小时前
【MySQL | 第八篇】MySQL 视图
数据库·mysql
jieyucx16 小时前
SQL 查询终极高阶通鉴:从零基础拆解到工业级多表联查、窗口函数与索引优化
数据库·sql
ai_coder_ai17 小时前
论 NoSQL 数据库技术及其应用
数据库·nosql
AOwhisky18 小时前
Redis 学习笔记(第一期):概述、安装配置与核心理论
运维·数据库·redis·笔记·学习·云计算
ytttr87318 小时前
C# 定时数据库备份工具
开发语言·数据库·c#