MySQL:表的约束

news/2024/11/22 20:34:05/

目录

一.   表的约束和约束的目标

二.   空属性

三.   默认值default

四.   列描述

五.   zerofill

六.   主键

6.1   建表时定义主键

6.2   去掉主键

6.3   建表后添加主键

6.4   复合主键

七.   自增长

八.   唯一键

九.   外键


一.   表的约束和约束的目标

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

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

二.   空属性

两个值:null和not null

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

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)

案例:创建一个班级表,包含班级名和班级所在的教室。

站在正常的业务逻辑中:

  • 如果班级没有名字,你不知道你在哪个班级。
  • 如果教室名字为空,就不知道在哪上课。

所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这就是“约束”。

mysql> create table myclass(-> class_name varchar(20) not null,-> class_room varchar(10) not null);
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(10) | NO   |     | NULL   |       |
+------------+-------------+------+-----+---------+-------+//插入数据时,没有给教室数据插入失败:mysql> insert into myclass(class_name) values('class1');
ERROR 1364 (HY000): Field 'class_room' doesn't have a default value

三.   默认值default

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

mysql> create table tt10 (-> name varchar(20) not null,-> age tinyint unsigned default 0,-> sex char(2) default '男'-> );
Query OK, 0 rows affected (0.00 sec)
mysql> desc tt10;
+-------+---------------------+------+-----+---------+-------+
| Field | Type               | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name | varchar(20)         | NO   |     | NULL   |       |
| age   | tinyint(3) unsigned | YES |     | 0       |       |
| sex   | char(2)             | YES |     | 男     |       |
+-------+---------------------+------+-----+---------+-------+

如果数据在插入时不给定值,则使用默认值。

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

default和not null不冲突,而是互相补充的。

对于not null而言,当用户插入数据的时候,就分为null和合法数据。

对于default而言,当用户忽略这一列的时候,如果设置了default,则使用默认值;如果没有设置default,则报错。

而对于age列:

下来再来看这个:

为什么还是让插入了呢?

而如果为我们没有在创建表的时候显示声明默认值,MySQL会优化,自动加上默认值为NULL。

四.   列描述

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

可以看到通过desc是看不到注释信息的,得用show才能看到。

五.   zerofill

对数字类型后面的长度很迷茫,对于下面这个表:

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

插入元素,显示:

如果我们修改在b的后面加上zerofill限定:

zerofill起到一个让一列的元素格式化显示(等宽显示)的作用。比如一个班一百多号同学,编号时,有一位数,有两位、三位数。我们就可以设置zerofill让其等宽。

加上zerofill并不会影响数值大小

而如果我们将int后面的数字变成小于插入的数的位数,会怎么样?

可以看到,如果插入的数的位数大于设置的int后面的数,那么正常插入就行。如果插入的数的位数小于设置的int后面的数,那么就得补0。

所以数据类型后面的数字代表可以表示的最大位数。

六.   主键

6.1   建表时定义主键

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

主键是不能发生冲突的:

则证明只要插入表中的元素,主键一定不冲突,则可以根据主键对数据进行增删查改。

6.2   去掉主键

如果想去掉主键:

6.3   建表后添加主键

上面描述的是建表时就在相应数据类型后面表明主键,我们还可以在建表之后再添加主键。

并且建表之后添加主键需要保证在表中需要设置主键的那列元素不能冲突。

6.4   复合主键

前面说过,一张表中最多只有一个主键,但是并不意味着一个主键只能关联一列,一个主键可以关联多列,这种主键就叫做复合主键。

id和couse_id合起来才能称为一个主键。

对于复合主键,只有组成复合主键的数据跟历史数据都一样的时候,才会发生主键冲突。

七.   自增长

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

自增长的特点:

  • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)。
  • 自增长字段必须是整数。
  • 一张表最多只能有一个自增长。

为什么会这样呢?

主要是因为方框内的设定,意思是下一次插入没有指定则就是1002。

那是不是对于每个空表,插入没有指定的值的时候都是从1开始呢?其实我们可以在创建表的时候就指定:

这样就指定初始为500。

也可以直接获取上次插入的auto_increment的值:

mysql > select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                1 |
+------------------+

八.   唯一键

创建带有唯一键的表:

唯一键表达了类似于主键的功能,不能发生冲突。

但是,唯一键是可以为空的,这是区别于主键的地方。

主键与唯一键并不冲突,是互相补充的!!!

像这样主键是有唯一性的,这是没问题的。

如果我插入的元素电话列,发生了冲突,但是主键又只能有一个,所以这里就需要唯一键来约束,保证电话的唯一性。

所以把telphone添加成唯一键:

alter table t20 add constraint unique_telphone unique(telphone);
//添加一个名为 unique_telphone 的唯一键约束,并且这个约束应用于 telphone 列。

关于唯一键和主键的区别:

我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。

九.   外键

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

语法:

foreign key (字段名) references 主表(列)

案例:

这样的student只是有外键之名(关联关系),但是没有外键之实(没有约束)。重新创建一个。

这样插入一个并不属于class表的班级编号的时候,就会报错。

并且如果从表中对应的还有数据,是不能在主表中删除的。

外键需要注意:

(1)从表和主表的关联关系

(2)产生外键约束


总结:

好了,到这里今天的知识就讲完了,大家有错误一点要在评论指出,我怕我一人搁这瞎bb,没人告诉我错误就寄了。

祝大家越来越好,不用关注我(疯狂暗示)

7cadd57a9ab1245ed3fe5e181cf2ea00.png


http://www.ppmy.cn/news/1549123.html

相关文章

ATmaga8单片机Pt100温度计源程序+Proteus仿真设计

目录 1、项目功能 2、仿真图 ​3、程序 资料下载地址:ATmaga8单片机Pt100温度计源程序Proteus仿真设计 1、项目功能 设计Pt100铂电阻测量温度的电路,温度测量范围是0-100摄氏度,要求LCD显示。画出电路图,标注元器件参数&am…

Spring Boot项目pom.xml文件详解

文章目录 Spring Boot项目pom.xml文件详解一、引言二、POM文件基础结构1、POM文件概述 三、项目依赖详解1、Spring Boot Web Starter2、MyBatis Spring Boot Starter3、MySQL Connector/J4、Lombok5、Spring Boot Test Starter 四、构建插件五、总结 Spring Boot项目pom.xml文件…

Python学习------第十天

数据容器-----元组 定义格式,特点,相关操作 元组一旦定义,就无法修改 元组内只有一个数据,后面必须加逗号 """ #元组 (1,"hello",True) #定义元组 t1 (1,"hello") t2 () t3 tuple() prin…

【H2O2|全栈】MySQL的云端部署

目录 前言 开篇语 准备工作 MySQL移除 为什么需要移除? 移除操作 Yum仓库 yum简介 rpm安装 yum库安装 MySQL安装 使用yum安装 开机自启动 检查运行状态 MySQL配置 初始密码 ​编辑登录 修改root密码 退出MySQL 字符集配置 重启数据库 结束语 …

嵌入式学习(13)-塔石TAS-LAN-476串口服务器

一、概述 TAS-LAN-476是一款实现物理串口转物理网口的设备,TAS-LAN-476 是工业级数据终端产品,该产品以以太网的方式为工业用户提供数据传输通道。设备软件功能完善,覆盖绝大多数常规应用场景,用户只需通过简单的设置&#xff0c…

C语言-11-18笔记

1.C语言数据类型 类型存储大小值范围char1 字节-128 到 127 或 0 到 255unsigned char1 字节0 到 255signed char1 字节-128 到 127int2 或 4 字节-32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647unsigned int2 或 4 字节0 到 65,535 或 0 到 4,294,967,295short2 字节…

AFSim脚本学习

定时更新 定时检测两个平台的距离,若距离小于某个值时触发函数 # File generated by Wizard 2.9.0 on Nov 21, 2024.platform_type TANK WSF_PLATFORMicon tankmover WSF_GROUND_MOVERend_moverend_platform_typeplatform tank_red TANKposition 24:42:36.68n 121:…

力扣 LeetCode 226. 翻转二叉树(Day7:二叉树)

解题思路: 递归 翻转二叉树,前序和后序都是可以的,但中序不行 中序会导致左边始终没有处理,所以如果一定要中序,两次内部递归都要用root.left class Solution {public TreeNode invertTree(TreeNode root) {if (ro…