MySQL表的约束

目录

前言

1.什么是约束

2.空属性

3.默认值

4.列描述

5.zerofill

6.主键

7.自增长

8.唯一键

9.外键

总结


前言

hello,各位小伙伴大家好,本章内容为大家介绍关于MySQL约束的相关内容,关于约束这个概念,如果是第一次接触可能会有一点难以理解,不过也不用担心,相信看完这篇文章对约束这个概念会有一个清晰的认识。

1.什么是约束

在谈MySQL表的约束之前,先举一个生活中的例子,我们在学校中读书,会受到学校中各种各样规矩的约束,本质上在学校制定许多的规矩是为了更好的管理学生,而在MySQL中也有许多的规矩,这些规矩是为了规范程序员在向数据库插入数据的时候正确操作,体现为对程序员的一种约束,下面我们就具体来看看,建表的时候都有哪些约束。

2.空属性

两个值:null(默认的) 和 not null(不为空)

数据库默认字段基本都是为空,但是在实际开发中,尽可能保证字段不为空,因为数据为空,没办法参与运算

sql 复制代码
mysql> select null;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
mysql> select 1+null;
+--------+
| 1+null |
+--------+
|  NULL |
+--------+
1 row in set (0.00 sec)

案例:
创建一个班级表,包含班级名和班级所在的教室。
站在正常的业务逻辑中:
如果班级没有名字,你不知道你在哪个班级
如果教室名字可以为空,就不知道在哪上课
所以我们在设计数据库表的时候,一定要在表中进行限制,班级名和教室名都不能为空,这就是"约束"。

sql 复制代码
//创建表
mysql> create table myclass( class_name varchar(20) not null, class_room varchar(20) not null);
Query OK, 0 rows affected (0.03 sec)

//表结构
mysql> desc myclass;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| class_name | varchar(20) | NO   |     | NULL    |       |
| class_room | varchar(20) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

//正常插入数据
mysql> insert into myclass values('通信211','4406');
Query OK, 1 row affected (0.00 sec)
//给非空属性字段不插入值报错
mysql> insert into myclass (class_name) values('通信211');
ERROR 1364 (HY000): Field 'class_room' doesn't have a default value

总结:在创建属性字段的时候,默认情况是null,可以为空,指定为not null,在插入数据的时候不能为空,必须有值,而必须有值,则体现为MySQL建表的一种约束

3.默认值

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

sql 复制代码
//创建表
mysql> create table if not exists stu(
    -> name varchar(12) not null,
    -> age tinyint unsigned default 18,
    -> sex char(2) default '男'
    -> );
Query OK, 0 rows affected (0.03 sec)

//表结构
mysql> desc stu;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name  | varchar(12)         | NO   |     | NULL    |       |
| age   | tinyint(3) unsigned | YES  |     | 18      |       |
| sex   | char(2)             | YES  |     | 男      |       |
+-------+---------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

//全插入
mysql> insert into stu (name,age,sex) values ('张三','20','男');
Query OK, 1 row affected (0.00 sec)

//按照默认值进行插入
mysql> insert into stu (name) values ('李四');
Query OK, 1 row affected (0.01 sec)

//插入后的数据
mysql> select* from stu;
+--------+------+------+
| name   | age  | sex  |
+--------+------+------+
| 张三   |   20 | 男   |
| 李四   |   18 | 男   |
+--------+------+------+
2 rows in set (0.00 sec)

设置了default的列,在插入数据的时候,可以对列进行省略。

4.列描述

列描述:comment,没有实际含义,专门用来描述字段,体现为一种软性约束

sql 复制代码
//创建表,通过comment对每个字段进行描述
mysql> create table if not exists t7(
    -> name varchar(20) not null comment "姓名",
    -> age int default 18 comment '年龄'
    -> );
Query OK, 0 rows affected (0.03 sec)

//查看表结构
mysql> show create table t7\G;
*************************** 1. row ***************************
       Table: t7
Create Table: CREATE TABLE `t7` (
  `name` varchar(20) NOT NULL COMMENT '姓名',
  `age` int(11) DEFAULT '18' COMMENT '年龄'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

5.zerofill

zerofill对数据进行格式化显示,如果宽度小于设定的宽度,自动填充0

sql 复制代码
mysql> create table if not exists t8(
    -> id int zerofill,
    -> name varchar(20) not null
    -> );
Query OK, 0 rows affected (0.04 sec)

//插入数据
mysql> insert into t8 values (1,'张三');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t8 values (2,'李四');
Query OK, 1 row affected (0.01 sec)

//插入数据的时候宽度小于设定的宽度用0填充。
mysql> select* from t8;
+------------+--------+
| id         | name   |
+------------+--------+
| 0000000001 | 张三   |
| 0000000002 | 李四   |
+------------+--------+
2 rows in set (0.00 sec)

//int类型数据宽度为10位
mysql> show create table t8\G;
*************************** 1. row ***************************
       Table: t8
Create Table: CREATE TABLE `t8` (
  `id` int(10) unsigned zerofill DEFAULT NULL,
  `name` varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

注:自动填充0,这是最后显示的结果,在MySQL中实际存储的还是1和2。

作用:在一些对数据格式有要求的地方使用,使得数据更加规范。

6.主键

主键:primary key用来唯一约束该字段里面的数据,不能重复,不能为空,一张表最多只能有一个主键,主键所在的列通常是整数类型

案例:

给学生的id添加主键,用id唯一标识一个学生

sql 复制代码
//创建表,指定id为主键
mysql> create table if not exists student(
    -> id int primary key comment '学号',
    -> name varchar(20) not null,
    -> age tinyint default 18
    -> );
Query OK, 0 rows affected (0.04 sec)

//插入数据
mysql> insert into student values(1,'张三',20);
Query OK, 1 row affected (0.01 sec)

mysql> insert into student values(2,'张三',20);
Query OK, 1 row affected (0.00 sec)

//当id值出现重复或者为空时不能向表中插入数据
mysql> insert into student values(2,'张三',20);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql> insert into student values(1,'张三',20);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into student (name,age)values('张三',20);
ERROR 1364 (HY000): Field 'id' doesn't have a default value

当表创建好以后但是没有主键的时候,可以再次追加主键

sql 复制代码
alter table 表名 add primary key(字段列表);

删除主键

sql 复制代码
alter table 表名 drop primary key;

复合主键

在创建表的时候,有多个属性字段作为主键,这里的多个属性字段作为主键不是说一张表中有多个主键,而是多个主键共同约束作为一个主键

案例:

创建一张表,该表中有多个属性字段作为主键

sql 复制代码
mysql> create table if not exists t9(
    -> id int unsigned,
    -> course char(10) comment '课程代码',
    -> score tinyint default 60 comment '成绩',
    -> primary key(id,score) --id和score共同作为复合主键
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> desc t9;
+--------+------------------+------+-----+---------+-------+
| Field  | Type             | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| id     | int(10) unsigned | NO   | PRI | NULL    |       |
| course | char(10)         | YES  |     | NULL    |       |
| score  | tinyint(4)       | NO   | PRI | 60      |       |
+--------+------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)


mysql> insert into t9 values(1,'数学',65);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 values(2,'数学',65);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t9 values(2,'数学',65);
ERROR 1062 (23000): Duplicate entry '2-65' for key 'PRIMARY' --主键冲突

7.自增长

auto_increment:当对应的字段不给值,会自动的被系统触发,系统从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键

自增长的特点:

任何一个字段要做自增长,前提本身是一个索引;

自增长字段必须是整数;

一张表最多只能有一个自增长

案例:

sql 复制代码
mysql> system clear;
mysql> create table if not exists t10(
    -> id int unsigned primary key auto_increment,
    -> name varchar(20) not null
    -> );
Query OK, 0 rows affected (0.03 sec)

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

mysql> insert into t10 (name) values('李四');
Query OK, 1 row affected (0.01 sec)

//默认从1开始自增长
mysql> select* from t10;
+----+--------+
| id | name   |
+----+--------+
|  1 | 张三   |
|  2 | 李四   |
+----+--------+
2 rows in set (0.00 sec)

自增长实现的原理:

获取上次插入的auto_increment的值

sql 复制代码
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

8.唯一键

一张表中往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键,而唯一键的存在可以解决表中有很多字段需要唯一性约束的问题。

唯一键和主键不同在于,唯一键允许为空,而主键不允许为空。另外主键更多的是标识唯一性的,而唯一键更多是保证在业务上,不要和别的信息产生冲突。

sql 复制代码
mysql> create table if not exists t11( 
    -> id tinyint primary key,
    -> name varchar(20) not null,
    -> class_name varchar(20) unique comment '班级名,不能为空'
    -> );
Query OK, 0 rows affected (0.03 sec)
//唯一键约束不能重复
mysql> insert into t11 values (1,'zhangsan','A');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t11 values (2,'zhangsan','A');
ERROR 1062 (23000): Duplicate entry 'A' for key 'class_name'
//可以为空
mysql> insert into t11 (id,name) values (2,'zhangsan');
Query OK, 1 row affected (0.00 sec)

mysql> select* from t11;
+----+----------+------------+
| id | name     | class_name |
+----+----------+------------+
|  1 | zhangsan | A          |
|  2 | zhangsan | NULL       |
+----+----------+------------+
2 rows in set (0.00 sec)

9.外键

MySQL是关系型数据库,一般表跟表之间是有关联关系的,举个简单的例子,有两张表,一张表是班级表,另一张是学生表,因为学生是属于班级的,所以一般将班级表称为是主表,而学生表称为是从表。

外键就是用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是主键约束或者是唯一键约束。当定义外键之后,要求外键列数据必须在主表的主键列存在或为null。

语法:

sql 复制代码
foreign key 字段名 references 主表(列)

案例:

a.创建主表:

sql 复制代码
mysql> create table if not exists myclass(
    -> id int primary key,
    -> name varchar(20) not null comment '班级名'
    -> );
Query OK, 0 rows affected (0.03 sec)

b.创建从表:

sql 复制代码
mysql> create table if not exists stu(
    -> id int primary key,
    -> name varchar(20) not null comment '学生名',
    -> class_id int,
    -> foreign key (class_id) references myclass(id)
    -> );
Query OK, 0 rows affected (0.06 sec)

c.正常插入数据:

sql 复制代码
mysql> insert into myclass values  (10,'C++大牛班'),(20,'java大神班');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0
sql 复制代码
mysql> insert into stu values (100,'张三',10);
Query OK, 1 row affected (0.01 sec)

mysql> insert into stu values (200,'李四',20);
Query OK, 1 row affected (0.01 sec)

mysql> insert into stu values (300,'王五',null);
Query OK, 1 row affected (0.01 sec)

d.插入一个班级号为30的同学,因为没有这个班级,所以插入不成功

sql 复制代码
mysql> insert into stu values (400,'赵六',30);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))

e.数据显示

sql 复制代码
mysql> select* from stu;
+-----+--------+----------+
| id  | name   | class_id |
+-----+--------+----------+
| 100 | 张三   |       10 |
| 200 | 李四   |       20 |
| 300 | 王五   |     NULL |
+-----+--------+----------+
3 rows in set (0.00 sec)

mysql> select* from myclass;
+----+---------------+
| id | name          |
+----+---------------+
| 10 | C++大牛班     |
| 20 | java大神班    |
+----+---------------+
2 rows in set (0.00 sec)

总结

本篇文章为大家介绍了MySQL中约束相关的话题,总结为一句话,约束是在建表的时候进行的,目的是为了防止在后续数据插入的时候出现不合法的数据,实现这个目的方法就是上面介绍的这些规则,相信掌握了这些规则之后,对数据库的操作又有了一个不小的提升。

我们下次再见。

相关推荐
小诸葛的博客20 分钟前
pg入门1——使用容器启动一个pg
数据库
sleP4o44 分钟前
Python操作MySQL
开发语言·python·mysql
大熊程序猿1 小时前
python 读取excel数据存储到mysql
数据库·python·mysql
落落落sss1 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
jnrjian1 小时前
Oracle 启动动态采样 自适应执行计划
数据库·oracle
知识分享小能手2 小时前
mysql学习教程,从入门到精通,SQL DISTINCT 子句 (16)
大数据·开发语言·sql·学习·mysql·数据分析·数据库开发
lamb张2 小时前
MySQL锁
数据库·mysql
ForRunner1232 小时前
使用 Python 高分解决 reCAPTCHA v3 的指南
数据库·python·microsoft
躺平的花卷3 小时前
Python爬虫案例六:抓取某个地区某月份天气数据并保存到mysql数据库中
数据库·爬虫·python·mysql