MySQL —— 表的约束

news2024/10/2 3:32:53

文章目录

    • 1. null 空属性
    • 2. default 默认值
    • 3. comment 列描述
    • 4. zerofill 格式化输出
    • 5. primary key 主键
    • 6. auto_increment 自增长
    • 7. 唯一键
    • 8. unique key 外键

前言: 表的约束主要是靠数据类型。有些情况,光靠数据类型约束是不够的,比如想要限制某个字段它的值是唯一的,不能重复,这就需要额外的约束。本章只介绍 null/not null,default, comment, zerofill,primary key,auto_increment,unique key 这些约束,都比较的常用。


1. null 空属性

null是空属性,意思就是它的值不存在。注意:是不存在 ,这样记忆不容易混。有C语言基础可能以为 null 就是空指针?在c/c++里,null,0,"" 它们的数值是一样的,它们是有值的。但是 MySQL中的null 它没值,不参与任何运算。

mysql> select null;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.00 sec)

mysql> select null+1;
+--------+
| null+1 |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)

默认情况下,如果不对字段进行限制,那么字段默认是可以为null的,但是 有的字段不能默认为空。比如你的信息表,有名字,有学号,有班级,这个班级不能默认为空,也就是说你插入一个学生信息,必须告诉人家所在班级:

mysql> create table student1(id int,name varchar(10),class int not null);
Query OK, 0 rows affected (0.03 sec)

mysql> desc student1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| class | int(11)     | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into student1 values(1,'bob',102);
Query OK, 1 row affected (0.01 sec)

mysql> insert into student1(id,name) values(2,'dd');
ERROR 1364 (HY000): Field 'class' doesn't have a default value
mysql> 

指定not null的字段,是不允许为null,所以插入一组值的时候,必须得插入这个字段的值,不过 它也可以有默认值,这就是下面讲的了。

2. default 默认值

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

简单说就是,你插入一组值,有的值你没主动插入,但是它可以用默认值。

mysql> create table student2(id int,name varchar(10),class int not null default 102);
Query OK, 0 rows affected (0.03 sec)

mysql> desc student2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| class | int(11)     | NO   |     | 102     |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into student2(id,name) values(1,'kk');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student2  values(2,'gg',103);
Query OK, 1 row affected (0.00 sec)

mysql> select * from student2;
+------+------+-------+
| id   | name | class |
+------+------+-------+
|    1 | kk   |   102 |
|    2 | gg   |   103 |
+------+------+-------+
2 rows in set (0.00 sec)

看上面例子,class 默认值是102,所以我插入值可以不插入class,尽管它是not null,结果没有报错,使用了它的默认值102。

3. comment 列描述

这个就是注释,对表中的列 进行 注释。

mysql> create table test1(id int comment '这是身份证号');
Query OK, 0 rows affected (0.03 sec)

mysql> show create table test1\G;
*************************** 1. row ***************************
       Table: test1
Create Table: CREATE TABLE `test1` (
  `id` int(11) DEFAULT NULL COMMENT '这是身份证号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.01 sec)

ERROR: 
No query specified
mysql> 

这个就是注释作用。

4. zerofill 格式化输出

这个比较有意思了,能解决我们之前学习的一个困惑:

在这里插入图片描述
有没有人好奇过,这个int(11),这个11是个啥?有人可能会想 这是 字节大小?字符长度? 都不是 。它的意思是默认对齐,不过要显示默认对齐前,必须要有zerofill属性。

mysql> alter table test1 change id id int(6) unsigned zerofill;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table test1\G;
*************************** 1. row ***************************
       Table: test1
Create Table: CREATE TABLE `test1` (
  `id` int(6) unsigned zerofill DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

现在我插入一个数据,我们看看现象:

mysql> insert into test1 values(4);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test1;
+--------+
| id     |
+--------+
| 000004 |
+--------+
1 row in set (0.00 sec)

mysql> 

这就是种格式化输出,看上去没啥卵用,我也没咋用过,哈哈。

5. primary key 主键

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

  • 指定主键:
mysql> create table student3(id int primary key not null  comment '学号不可以重复',name varchar(10));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into student3 values(1,'bob');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student3 values(1,'yy');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into student3 values(2,'bob');
Query OK, 1 row affected (0.02 sec)

mysql> select * from student3;
+----+------+
| id | name |
+----+------+
|  1 | bob  |
|  2 | bob  |
+----+------+
2 rows in set (0.00 sec)

mysql> desc student3;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> 

  • 一个表只能有一个主键,不可以重复:
mysql> create table student4(id int primary key not null  comment '学号不可以重复',name varchar(10) primary key);
ERROR 1068 (42000): Multiple primary key defined
  • 如果一个表中没有主键,要追加主键:
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> alter table test2 add primary key(name);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | NO   | PRI |         |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

desc 显示 mysql表结构,其中那个key,看到了吧,就是索引,字段的属性。

  • 也可以删除一个表中的主键:
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | NO   | PRI |         |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> alter table test2 drop primary key;
Query OK, 4 rows affected (0.06 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | NO   |     |         |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
  • 复合主建:

有种情况,它允许单一的字段出现重复,但是 不允许多个字段出现重复。这个情况就得用复合主键,这样做,表里面还是只有一个主键,只不过这个主键是复合主键。

mysql> create table student4(id int,name varchar(10),gander varchar(2) not null,primary key(id,name));
Query OK, 0 rows affected (0.02 sec)

mysql> desc student4;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | 0       |       |
| name   | varchar(10) | NO   | PRI |         |       |
| gander | varchar(2)  | NO   |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into student4 values (1,'bob','男');
Query OK, 1 row affected (0.01 sec)

mysql> insert into student4 values (1,'zz','男');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student4 values (2,'bob','男');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student4 values (1,'bob','女');
ERROR 1062 (23000): Duplicate entry '1-bob' for key 'PRIMARY'
mysql> 

6. auto_increment 自增长

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

自增长的特点:

  • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长
mysql> create table people(id tinyint primary key auto_increment,name varchar(10) not null default '');
Query OK, 0 rows affected (0.02 sec)

mysql> insert into people values(1,'张飞');
Query OK, 1 row affected (0.00 sec)

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

mysql> select * from people;
+----+--------+
| id | name   |
+----+--------+
|  1 | 张飞   |
|  2 | 李四   |
+----+--------+
2 rows in set (0.00 sec)

mysql> insert into people values(100,'吕布');
Query OK, 1 row affected (0.01 sec)

mysql> insert into people(name) values('关羽');
Query OK, 1 row affected (0.00 sec)

mysql> select * from people;
+-----+--------+
| id  | name   |
+-----+--------+
|   1 | 张飞   |
|   2 | 李四   |
| 100 | 吕布   |
| 101 | 关羽   |
+-----+--------+
4 rows in set (0.00 sec)

7. 唯一键

一个表中只能有一个主键,这个主键不能为null,并且不能重复;有的数据 也要保持唯一性,但是表中已有主键,只能使用唯一键。

注意:唯一键,是允许为null的,null并不参与任何计算,多个null也没关系,相当于多个不存在。

mysql> create table student (
-> id char(10) unique comment '学号,不能重复,但可以为空',
-> name varchar(10)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into student(id, name) values('01', 'aaa');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student(id, name) values('01', 'bbb'); --唯一约束不能重复
ERROR 1062 (23000): Duplicate entry '01' for key 'id'
mysql> insert into student(id, name) values(null, 'bbb'); -- 但可以为空
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+------+------+
| id | name |
+------+------+
| 01 | aaa |
| NULL | bbb |
+------+------+

8. unique key 外键

这个约束是,表和表之间的约束,或者说是一种 映射关系:

在这里插入图片描述

在上述外键关系中:主表是班级表,从表是学生表。因为 学生表的班级id只能是175,或者176,为什么?因为班级表中只有175和176两个班。

也就是说:班级表约束了学生表中class_id的范围,这就是外键约束

那么现在来做一下 实验,构建学生表 和 班级表的 外键关系:

mysql> create table class(id int primary key,
class_name varchar(10) not null);
Query OK, 0 rows affected (0.02 sec)

mysql> create table student(id int primary key,
name varchar(10) not null,
class_id int,
foreign key(class_id) references class(id));
Query OK, 0 rows affected (0.04 sec)

mysql> desc class;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| id         | int(11)     | NO   | PRI | NULL    |       |
| class_name | varchar(10) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> desc student;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int(11)     | NO   | PRI | NULL    |       |
| name     | varchar(10) | NO   |     | NULL    |       |
| class_id | int(11)     | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into class values(175,'加强班');
Query OK, 1 row affected (0.01 sec)

mysql> insert into class values(176,'普通班');
Query OK, 1 row affected (0.01 sec)

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

mysql> insert into student values(2,'李四',176);
Query OK, 1 row affected (0.00 sec)

mysql> insert into student values(3,'王五',178);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`hh1`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
mysql> 

这就是它的实验,大家可以下去自己敲的玩玩。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/369984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】ThreadLocal原理

​ ThreadLocal ThreadLocal意为线程本地变量,用于解决多线程并发时访问共享变量的问题。 每个线程都会有属于自己的本地内存,在堆(也就是上图的主内存)中的变量在被线程使用的时候会被复制一个副本线程的本地内存中&#xff0c…

【H5 | CSS | JS】如何实现网页打字机效果?快收下这份超详细指南(附源码)

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…

在C#中初测OpencvSharp4

一、配置OpenCV 首先,我们新建一个工程,然后就是给这个工程配置OpenCV了,最简单的方法还是Nuget,来我们右键一个Nuget: 打开Nuget后,你可以直接输入OpenCVSharp4来查找,当然,如果你…

公司新来的00后真是卷王,工作没两年,跳槽到我们公司起薪20K都快接近我了

都说00后躺平了,但是有一说一,该卷的还是卷。这不,前段时间我们公司来了个00后,工作都没两年,跳槽到我们公司起薪18K,都快接近我了。后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。…

罗永浩进场之后,苹果入局之前:XR又寒冬了吗?

科技圈的悲欢并不相通。ChatGPT狂飙之际,XR领域正在迎来至暗时刻。岁末年初,就在罗永浩重返高科技创业,计划进军XR(扩展现实)类领域的时间段前后,接连出现了押注元宇宙的Meta裁员,Meta旗下VR工作室Ready At…

【华为OD机试模拟题】用 C++ 实现 - 快递业务站(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

【华为OD机试模拟题】用 C++ 实现 - 流水线(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 分积木(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 吃火锅(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - RSA 加密算法(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 构成的正方形数量(2023.Q1) 【华为OD机试模拟…

数据库|(六)连接查询

(六)连接查询1. 笛卡尔乘积2. 连接查询分类2.1 按年代分2.2 按功能分3. 等值连接(sql 92标准)3.1 特点3.2 一般使用3.3 为表取别名3.4 两表顺序可以调换3.5 可以加筛选3.6 可以加分组3.7 可以加排序3.8 可以实现三表连接4. 非等值连接(sql 92标准)5. sql…

【深度学习】GPT系列模型:语言理解能力的革新

GPT-1🏡 自然语言理解包括一系列不同的任务,例如文本蕴涵、问答、语义相似度评估和文档分类。尽管大量的未标记文本语料库很充足,但用于学习这些特定任务的标记数据却很稀缺,使得判别式训练模型难以达到良好的表现。我们证明&…

Spring(入门)

1. 什么是spring,它能够做什么?2. 什么是控制反转(或依赖注入)3. AOP的关键概念4. 示例 4.1 创建工程4.2 pom文件4.3 spring配置文件4.4 示例代码 4.4.1 示例14.4.2 示例2 (abstract,parent示例)4.4.3 使用有参数构造方法创建jav…

【华为OD机试模拟题】用 C++ 实现 - 找数字(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

显示器管理工具:BetterDisplay Pro Mac

BetterDisplay Pro Mac 是一个非常棒的工具!它可以让您将显示器转换为完全可缩放的屏幕,允许亮度控制,提供 XDR/HDR 升级(在兼容显示器上超过 100% 的额外亮度),完全调光为黑色,帮助您为 Mac 创…

PRML笔记3-绪论中最小化错误分类率的理解

这个小节的内容很少,因为自己数学水平实在太差,所以理解不到之处还请批评指正。 在分类任务中我们希望尽可能减少错误的分类,例如我们有一些病人的临床数据,希望通过这些临床数据对患者的诊断提供帮助,比如根据临床数据…

gazebo仿真环境中添加robotiq 2f 140的gripper_controller控制器

gazebo仿真环境中添加robotiq 2f 140的gripper_controller控制器 搭建环境: ubuntu: 20.04 ros: Nonetic sensor: robotiq_ft300 gripper: robotiq_2f_140_gripper UR: UR3 reasense: D435i 通过下面几篇博客配置好了ur3、力传感器、robotiq夹爪、rea…

vuejs文件传参方式

vue2版本 vscode 大致总结一下几种情况: 1.父传子,父组件利用props向子组件传递数据 1.在父组件的子组件标签上绑定一个属性,挂载要传输的变量 2.在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数…

RayVentory updated

RayVentory updated RayVentory Aspera连接器12.5.0.11850[更新1] 增加了对Docker容器的支持。 已将Xen虚拟机的设备类型更改为“Virtual_Machine”。 RayVentory扫描引擎12.5.3579.69[更新1] 添加了法语UI翻译预览。 RayVentory提供了硬件和软件的全面清单,并提供了…

mars3d获取视窗的范围

期望效果 :1.我现在想获取到当前视窗的地图范围,请问有什么⽅法可以拿到吗 2.⽐如当前视窗地图范围的边界点,每个边界点的经纬度 回复:1.mars3d的API⽂档中有相关的⽅法 2.具体使⽤可以参考⽂档地址:http://mars3d.cn/api/Map.htm…

长期跑步需要买个运动耳机吗、最好用的5款跑步耳机推荐

告别了寒冬,迎来了暖春。我的健身计划也开始提上了日程。最开始跑步还有点新鲜感,但是时间一久,自己在公园跑步那种枯燥感就会袭来,一个坚持跑步一年多的朋友告诉我,可以试一下跑步时听听音乐,既能锻炼身体…

JVM虚拟机栈

1、概述Java虚拟机栈(Java Virtual Machine Stack),早期也叫Java栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用,是线…

Codeforces Round #850 (Div. 2, based on VK Cup 2022 - Final Round)(A~E)

t宝酱紫喜欢出这种分类讨论的题&#xff1f;&#xff01;A1. Non-alternating Deck (easy version)给出n张牌&#xff0c;按照题目给的顺序分给两人&#xff0c;问最后两人手中各有几张牌。思路&#xff1a;模拟。AC Code&#xff1a;#include <bits/stdc.h>typedef long…