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 特性!

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

相关推荐
海市公约1 小时前
MySQL核心概念及SQL语句与数据类型详解
mysql·sql语句·数据类型·运算符·ddl·dml·数据库入门
x***r1511 小时前
heidisql数据库客户端使用步骤详解(附HeidiSQL连接MySQL与SQL执行教程)
数据库·sql·mysql
段一凡-华北理工大学2 小时前
2026 高炉炼铁智能化技术全景与演进路径~系列文章04:云-边-端协同架构:高炉智能化底层支撑体系
数据库·人工智能·深度学习·神经网络·安全·架构·高炉炼铁智能化
青山师2 小时前
B+树与InnoDB索引深度解析:数据库索引的底层原理与工程实践
数据结构·数据库·b树·性能优化·b+树·索引优化·mysql性能
小学鸡!2 小时前
IoTDB数据库导入导出数据
数据库·iotdb
尚雷55802 小时前
Oracle ASM 存储更换与整体迁移实战整理
数据库·oracle·ocr·asm
Nontee2 小时前
如何用 MySQL 实现一个可重入的锁?
数据库·mysql
麦聪聊数据2 小时前
数据服务轻量化:基于API架构的企业数据统一交付与消费方案
数据库·架构
坚定学代码3 小时前
如何在c++中使用MySQL
开发语言·c++·mysql