MySQL表的约束

目录

前言

1.什么是约束

2.空属性

3.默认值

4.列描述

5.zerofill

6.主键

7.自增长

8.唯一键

9.外键

总结


前言

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

1.什么是约束

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

2.空属性

两个值: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(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.默认值

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

//创建表
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,没有实际含义,专门用来描述字段,体现为一种软性约束

//创建表,通过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

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唯一标识一个学生

//创建表,指定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

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

alter table 表名 add primary key(字段列表);

删除主键

alter table 表名 drop primary key;

复合主键

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

案例:

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

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操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键

自增长的特点:

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

自增长字段必须是整数;

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

案例:

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的值

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)

8.唯一键

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

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

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。

语法:

foreign key 字段名 references 主表(列)

案例: 

 a.创建主表:

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.创建从表:

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.正常插入数据:

mysql> insert into myclass values  (10,'C++大牛班'),(20,'java大神班');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0
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的同学,因为没有这个班级,所以插入不成功

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.数据显示

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

 我们下次再见。

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

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

相关文章

JAVA ---- 经典排序算法

目录 一. 插入排序 1. 直接插入排序 代码演示 2.希尔排序( 缩小增量排序 ) 二. 选择排序 1.直接选择排序 代码: 2. 堆排序 代码 三. 交换排序 1. 冒泡排序 代码 2. 快速排序 代码(有注释): 动图来自网…

ubuntu创建多用户并使用ssh链接

添加多个同时登录的用户 以下内容中的“username”根据自己需求自己定义 1.创建新用户 sudo useradd username2.给新用户添加管理权限 sudo vim /etc/sudoers打开的文件中添加如下内容 username ALL(ALL:ALL) ALL3.设置密码 输入: sudo passwd username打开的…

「软件测试」最全面试问题和回答,全文背熟不拿下offer算我输

一般要应聘关于测试的工作,面试题会不会很难?下面小编整理了软件测试面试题及答案,欢迎参考! 一、引言 1.1 文档目的 本次文档是为了收集在面试中遇到的一问题与常见的一些答案并不是唯一答案 二、职业规划 2.1 简单的自我介绍下 面试宫&#xff…

点大商城V2_2.5.0 全开源版 商家自营+多商户入驻 百度+支付宝+QQ+头条+小程序端+unipp开源前端安装测试教程

播播资源安装点大商城V2_2.5.0 全开源版测试后发现后台总体体验下来比较简洁,营销功能还是挺多该有的都有了,相比上一版优化很多细节。首页和会员中心均支持DIY装修,底部菜单也一样,安装测试中目前未发现BUG,小程序整体…

etcd实现大规模服务治理应用实战

导读:服务治理目前越来越被企业建设所重视,特别现在云原生,微服务等各种技术被更多的企业所应用,本文内容是百度小程序团队基于大模型服务治理实战经验的一些总结,同时结合当前较火的分布式开源kv产品etcd,…

文献阅读笔记——求解车辆路径问题及其变体的元启发式算法的分类综述

论文题目:A taxonomic review of metaheuristic algorithms for solving the vehicle routing problem and its variants 其他信息:Computers & Industrial Engineering|2020|Raafat Elshaer⁎, Hadeer Awad 文章贡献:1)对使…

如何用Python搭建监控平台

监控和运维,是互联网工业链上非常重要的一环。监控的目的就是防患于未然。通过监控,我们能够及时了解到企业网络的运行状态。一旦出现安全隐患,你就可以及时预警,或者是以其他方式通知运维人员,让运维监控人员有时间处…

什么是计算机蠕虫?

计算机蠕虫诞生的背景 计算机蠕虫的诞生与计算机网络的发展密切相关。20世纪60年代末和70年代初,互联网还处于早期阶段,存在着相对较少的计算机和网络连接。然而,随着计算机技术的进步和互联网的普及,计算机网络得以迅速扩张&…

S32 Design Studio for ARM(S32DS)下载和安装

1. S32 Design Studio for ARM 介绍 S32 Design Studio for ARM(下面简称S32DS),是 NXP 官方在 2014 年官方推出的,专门面向 S32K、KEA、MAC57D54H等系列微控制器的集成开发环境。 S32DS是由Eclipse和一些插件集成而来的开发平台…

kafka消息队列最常用的两种模式,以及应用场景

目录 一、发布-订阅模式 二、点对点模式 三、应用场景 一、发布-订阅模式 发布-订阅模式是最常见的消息传递模式,其中消息发布者将消息发送到一个或多个主题(Topic),而订阅者可以选择订阅一个或多个主题来接收消息。每个订阅者…

实现本地缓存-caffeine

目录 实现caffeine cache CacheManager Caffeine配置说明 创建自定义配置类 配置缓存管理器 编写自动提示配置文件 测试使用 创建测试配置实体类 创建测试配置类 创建注解扫描的测试实体 创建单元测试类进行测试 实现caffeine cache CacheManager SimpleCacheManag…

香橙派4和树莓派4B构建K8S集群实践之七: Jenkins

目录 1. 说明 2. 步骤 2.1 准备工作 2.2 安装 2.2.1 用jenkins原站for k8s的安装仓方法安装 2.2.2 Helm 安装 3. 相关命令 4. 遇到的问题 5. 参考 1. 说明 在k8s上部署jenkins,并用 jenkins.k8s-t2.com访问在namespace为devops下安装在指定节点k8s-master-…

欧姆龙以太网模块如何设置ip连接 Kepware opc步骤

在数字化和自动化的今天,PLC在工业控制领域的作用日益重要。然而,PLC通讯口的有限资源成为了困扰工程师们的问题。为了解决这一问题,捷米特推出了JM-ETH-CP转以太网模块,让即插即用的以太网通讯成为可能,不仅有效利用了…

字符函数和字符串函数上篇(详解)

❤️ 作者简介 :RO-BERRY 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识,对纯音乐有独特的喜爱 📗 日后方向 : 偏向于CPP开发以及大数据方向,如果你也感兴趣的话欢迎关注博主,期待更新 字符函数和字符串函数 &a…

OpenCV——总结《车牌识别》

1.图片中的hsv hsv提取蓝色部分 # hsv提取蓝色部分 def hsv_color_find(img):img_copy img.copy()cv2.imshow(img_copy, img_copy)"""提取图中的蓝色部分 hsv范围可以自行优化cv2.inRange()参数介绍:第一个参数:hsv指的是原图第二个参…

初识vue3/setup/ ref()/ computed/watch/生命周期/父传子

创建项目先不着急学 main.js变了 新加setup reactive ref() computed watch 生命周期 父传子 子传父 ref/模板引用 暴露子组件属性 跨层传数据 defineOptions

用OpenCV进行图像分割--进阶篇

1. 引言 大家好,我的图像处理爱好者们! 在上一篇幅中,我们简单介绍了图像分割领域中的基础知识,包含基于固定阈值的分割和基于OSTU的分割算法。这一次,我们将通过介绍基于色度的分割来进一步巩固大家的基础知识。 闲…

【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取

Spring的开发要点总结 文章目录 【JavaEE】Spring的开发要点总结(1)1. DI 和 DL1.1 DI 依赖注入1.2 DL 依赖查询1.3 DI 与 DL的区别1.4 IoC 与 DI/DL 的区别 2. Spring项目的创建2.1 创建Maven项目2.2 设置国内源2.2.1 勾选2.2.2 删除本地jar包2.2.3 re…

C++万字自学笔记

[TOC] 一、 C基础 C的IDE有CLion、Visual Studio、DEV C、eclipse等等&#xff0c;这里使用CLion进行学习。 0. C初识 0.1 第一个C程序 编写一个C程序总共分为4个步骤 创建项目创建文件编写代码运行程序 #include <iostream>int main() {using namespace std;cout…

Vant源码解析(四)----Popup弹出层,详解样式方法

这个功能&#xff0c;自己也手写过&#xff0c;毕竟有很多弹窗的嘛。 我自己写就是&#xff1a;一个背景层&#xff0c;然后一个盒子里面放内容。再写个显示隐藏事件。够够的了。 Vant的Popup弹出层 页面结构 短短一个背景加内容盒子&#xff0c;vant套了几层。 这是引用的组件…