MySQL之表的约束(上)

news2024/9/24 9:24:47

目录

空属性(NULL)

 实例建表

插入操作

默认值(default)

建表

 插入操作

NULL与default的结合

 列描述

建表

 zerofill

建表

 插入操作

主键

建表

插入 

 主键的增加与去掉

去掉

增加

 复合主键

 插入的影响

真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。

表中一定要有各种约束,通过约束,让我们未来插入数据库中的数据是符合预期的。约束本质是通过技术手段倒逼程序员插入正确的数据(不正确不会让你插入)。返回来,站在mysql视角,凡是插入的数据都是符合数据约束的。

约束的最终目标:(预先把规则设计好,让别人按照规则插入)保证数据的完整性和可预期性。

表的约束很多,这里主要介绍如下几个: null/not null,default, comment, zerofill,primary key,auto_increment,unique key

空属性(NULL)

在mysql中NULL代表没有(什么都没有)而‘ ’或“ ”代表空串,这个串有但是是空的(mysql中单双引号都可以表示字符串)类似于我没有银行卡与我有卡但是卡里没钱。NULL不参与计算。

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

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

 实例建表

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

站在正常的业务逻辑中:

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

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

建表顺序:

1. 建立数据库create database school;

2. 使用当前数据库use school;

3. 在当前数据库中建表create table if not exists myclass(
    -> class_name varchar(20) not null,
    -> class_room varchar(20) not null,
    -> other varchar(20)
    -> );

查表desc myclass;

如果建表时不输入not null那么就默认是null。

NULL这一列就代表了对应这一列未来插入是否为空,no代表如果你插入空值或者没插入那么我就不让你插入 ,这意味着当插入新行或更新现有行时,该列必须始终包含一个值,而不能为 NULL。

 实际上在mysql保存的创表操作是这个:

插入操作

insert into myclass (class_name,class_room,other) values ('高三1班','101教室','普通班');

insert into myclass (class_name,class_room) values ('高三2班','102教室');


没有向other插入数据,那么就默认NULL,没有加非空约束;

insert into myclass (class_name) values ('高三2班');
ERROR 1364 (HY000): Field 'class_room' doesn't have a default value报错信息

insert into myclass (class_name,class_room) values ('高三2班',NULL);
ERROR 1048 (23000): Column 'class_room' cannot be null不能为空

那么就能拦住任何向name和room中插入空值,则必须插入数据值;

 not null就是限定你插入时必须插入合法数据不能是NULL。没有not null约束即可以插入NULL

默认值(default)

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

建表

mysql> create table if not exists t1(
    -> name varchar(20) not null,
    -> age tinyint unsigned default 18,
    -> gender char(1) default '男'
    -> );


可以看到默认情况下age为18,gender为男

 插入操作

insert into t1 (name,age,gender) values ('张三','19','女');//全列插入

insert into t1 (name) values ('李四');//使用默认值

对于default来说,如果用户插入时有自己的具体数据那么就用自己的,若没有就用默认值 。

NULL与default的结合

mysql> create table if not exists t2(
    -> name varchar(20) not null,
    -> age tinyint default 18,
    -> gender char(1) not null default '男');//语法允许

那么在看具体mysql怎么解释


name只设定了not null,mysql没有自己在后面加default那么说明name列不能为空

对于insert into t2 (name,age,gender) values (NULL,20,'男');ERROR 1048 (23000): Column 'name' cannot be null来说,是非空约束了。

对于insert into t2 (age,gender) values (20,'男');ERROR 1364 (HY000): Field 'name' doesn't have a default value报错信息不一样,我在插入时忽略了name列没有插入则是default约束因为我没有设置默认default值
换句话来说如果我插入NULL,你不让我插入是NULL约束,但是我不对你插入忽略你,也没有设置default值那么就是default约束

那么对于gender来说:
对他忽略没出错因为有默认值。如果用户忽略某个列就用default值

 default和not null不冲突而是相互补充的。当用户想插入的时候受not null约束(必须是合法数据不能是NULL),当忽略这一列时受到default约束 (设置defaule值使用默认值,没有设置default值就错误)

如果自己在建表时自己没有设置default值和not null,那么MySQL会对自己的sql做优化

show create table xxx\G可以看出优化,优化后默认带default,没有带not null。

如果用户自己设置了not null但没有设置default值,那么mysql也不会优化带default。

 列描述

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

建表

mysql> create table if not exists t3(
    -> name varchar(20) not null comment '这个是用户名',
    -> age tinyint unsigned default 18 comment '这个是用户的年纪',
    -> gender char(1) default '男' comment '这个是用户的性别'
    -> );

desc表发现跟以前的没区别:通过desc查看不到注释信息

insert into t3 values ('张三',19,'女');//发现插入也没区别

那么我们想看到的话就show create table t3\G 可以看到列信息的描述字段

 zerofill

建表

mysql> create  table if not exists t4(
    -> a int unsigned not null,
    -> b int unsigned not null
    -> );

但是我们查表时发现自己带了(10),自己建表时没有设置数据大小。

这是因为实际执行时sql会自己补充优化带(10)

 可以看到int(10),这个代表什么意思呢?整型不是4字节码?这个10又代表什么呢?其实没有zerofill这个属性,括号内的数字是毫无意义的

 插入操作

insert into t4 values (1,2);//全列插入

更改表属性操作: alter table t4 modify b int unsigned zerofill not null;//对b列添加zerofill属性


发现数据变了,b多了很多前缀0;

继续插入:insert into t4 values (100,200);

 那么zerofill就是给特定的列添加zerofill属性,他的结果就是我们在进行显示的时候如果宽度小于设定的宽度(就是int(x)圆括号里的数字)时自动填充0如果够宽度了那么就不用管该是什么长度就是什么长度不用加0。要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是1。这样未来在显示时是等宽的。


可以看到最终在mysql中存储的是还是2和200(以16进制显示hex());

 alter table t4 modify a int not null;

alter table t4 modify b int unsigned not null;


可以看到a比b多一个是因为有符号位,又为什么默认是10呢?因为一个整数四个字节32bit位,有符号取值范围为 (-(2^{31})) 到 (2^{31} - 1),无符号整数,所有32位都用来表示数值本身,范围是 (0) 到 (2^{32} - 1);无论是2^32(42亿多)还是2^31(21亿多)最终转化为十进制都是十位,十位足够把整数保存下来。

所以zerofill并不影响存储,他只是影响我们后续的格式化显示(zerofill约束);

主键

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

建表

mysql> create table t5 (
    ->  id int unsigned primary key comment '学号',
    ->  name varchar(20) not null);


可以发现有属性列key,key列代表当前列是否为主键列那么有pri说明就是主键。

同时带主键了那么就自动默认添加not null约束了(如果自己没写not null约束)。

插入 

insert into t5 values (1,'张飞');

insert into t5 values (1,'刘备');//再次插入就出错了

ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'//主键冲突,所以相同的key不让插入

所以只能插入不同的主键值

 那么主键约束带来的就是未来程序员插入时不能主键冲突,键对应的字段中不能重复,一旦重复,操作失败。所以我们就能根据主键拿出绝对唯一的值。
同时也能根据主键修改值:update t5 set name='王老板' where id=2;

 主键的增加与去掉

主键可以在建表时添加,也可以在建表后添加。

去掉


当前id是主键,那么怎么去掉呢?

更改一张表alter table t5 drop primary key;因为主键在一张表里只有一个,所以不用说在哪一列。
那么这时就可以冲突插入了,insert into t5 values (2,'刘备');//没有主键约束了

这时候表的结构也发生变化了,没有主键显示了。

增加

alter table t5 add primary key(id);//向id列增加主键
但是报错了ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'//主键冲突
为什么呢?
因为我们之前在相同的id插入不同的name使冲突。所以要想把id列增加主键就要id列要么没有数据要么就一个不冲突的数据。

现在只能删除多的数据:delete from t5 where name='刘备';
增加主键:alter table t5 add primary key(id);

最终可以看到主键被添加了。

 复合主键

虽然表中最多只有一个主键,但不意味着一个表中的主键只能添加给一列(一个主键可以添加到一列或者多列上);

我们把多列上的主键叫做复合主键。

mysql> create table t6(
    -> id int unsigned default 0,
    -> course char(10) comment '课程代码',
    -> score tinyint unsigned default 60 comment '成绩',
    -> primary key(id,course)
    -> );

id和course合并充当主键(他俩合起来才称为一个主键)。

 插入的影响

insert into t6 values(1234,'语文',90);

insert into t6 values(1235,'语文',85);

那为什么会是这样呢?id和course都是primary key,为什么course一样了mysql并没有拦截?
insert into t6 values(1234,'数学',90);同样也允许这样。

而再次插入就不允许了。我们可以看到mysql把1234-数学作为一个整体了。

 所以我们可以用多个主键,但是当作为主键的同时跟历史数据冲突了才不让插入,报错。

分开彼此之间可以重复,但是合并就不能重复。

 所以主键是确定列唯一性的。可以通过主键快速查找。

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

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

相关文章

阶段三:项目开发---搭建项目前后端系统基础架构:任务13:实现基本的登录功能

任务描述 任务名称: 实现基本的登录功能 知识点: 了解前端Vue项目的基本执行过程 重 点: 构建项目的基本登陆功能 内 容: 通过实现项目的基本登录功能,来了解前端Vue项目的基本执行过程,并完成基…

【机器学习】属性降维:揭示数据的简化之美

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 属性降维:揭示数据的简化之美引言什么是属性降维?为何降…

(二)前端javascript中的数据结构之栈

栈是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。 栈是限定仅在表的一端进行插入和删除操作…

SpringBoot源码阅读(3)——监听器

ApplicationListener类初始化位置 在类SpringApplication的构造方法,第267行 在META-INFO/spring.factories中配置的实现类 spring-boot # Application Listeners org.springframework.context.ApplicationListener\ org.springframework.boot.ClearCachesApplic…

一分钟教会你,iPhone和安卓手机虚拟摄像头如何连接电脑?手机连接电脑虚拟摄像头!

在当今的远程工作和在线学习时代,摄像头的需求日益增长。然而,有时我们可能会遇到电脑摄像头画质不佳或无法使用的情况。此时,利用手机的高清摄像头作为电脑的虚拟摄像头,便成了一个理想的选择。本文将为您介绍如何将iPhone和安卓…

SpringMVC系列十三: SpringMVC执行流程 - 源码分析

源码分析 执行流程图实验设计前端控制器分发请求处理器映射器处理器适配器调用目标方法调用视图解析器渲染视图作业布置 执行流程图 实验设计 1.新建com.zzw.web.debug.HelloHandler Controller public class HelloHandler {//编写方法, 响应请求, 返回ModelAndViewRequestMa…

拥抱 AGI:PieDataCS 引领云原生数据计算系统新范式

自2023年后,人工智能技术进入了一个更为成熟和广泛应用的阶段,人工通用智能(AGI)这一概念也成为了科技界和产业界热议的焦点。本文将结合 AGI 时代背景,从架构设计到落地实践,详细介绍拓数派云原生数据计算…

掌握全球通用的建模语言,从《Archimate®3.2规范参考卡》开始!

作为企业架构设计的通用语言,Archimate更是一种愿景的体现,一个变革的引擎,它不仅可以与TOGAF标准高效结合,还可助力全球企业无边界协作使用(下滑可了解更多Archimate建模语言的发展和演进)! 本…

PMP 认证权威吗?对项目…业生涯的发展有帮助?

PMP认证到底权威吗? 首先在我看来,PMP认证是否权威要从各个角度进行综合考虑。入行这么多年个人也有不少的体会,那么我们就从多个角度进行分析一下,PMP认证的权威性与促进方面。 在深入探讨这个话题前,我分享一下近期…

双向链表 -- 详细理解和实现

欢迎光顾我的homepage 前言 双向链表是一种带头双向循环的链表。在双向链表中,首先存在着一个头结点;其次每个节点有指向下一个节点的指针next 和指向上一个节点的指针prev &#xff1b…

《网络安全和信息化》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问:《网络安全和信息化》是不是核心期刊? 答:不是,是知网收录的正规学术期刊。 问:《网络安全和信息化》级别? 答:国家级。主管单位:工业和信息化部 主办单位&#…

脑干出血:揭秘其成因、症状与治疗方法

脑干出血,作为脑出血中尤为凶险的一种,主要袭击脑部的核心——脑干区域。脑干,作为连接大脑与脊髓的桥梁,掌管着呼吸、心跳、意识等至关重要的生命功能,一旦受损,后果不堪设想。 脑干出血的成因 首要元凶…

python爬虫入门(四)之Beautiful Soup库

一、什么是Beautiful Soup库 1、Beautiful Soup库是用来做HTML解析的库 Beautiful Soup把看起来复杂的HTML内容,解析成树状结构,让搜索和修改HTML结构变得更容易 2、第三方库,先安装 终端输入pip install bs4 from bs4 import Beautiful…

AI工具杂谈

AI是在帮助开发者还是取代他们? 在软件开发领域,生成式人工智能(AIGC)正在改变开发者的工作方式。无论是代码生成、错误检测还是自动化测试,AI工具正在成为开发者的得力助手。然而,这也引发了对开发者职业…

Pytorch的ImageFolder数据加载器

📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️如遇文章付费,可先看…

burpsuite官方靶场之逻辑漏洞篇

*1.过于信任客户端控件* *1.1 达成目标* 用wiener买一件Lightweight l33t leather jacket。 提供的账户:wiener/peter *1.2攻击步骤* 第一步,登录wienr,并且来到主界面,发现Lightweight l33t leather jacket要$1337&#xff…

面试经典 106. 从中序与后序遍历序列构造二叉树

最近小胖开始找工作了,又来刷苦逼的算法了 555 废话不多说,看这一题,上链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/?envTypestudy-plan-v2&envIdtop-inte…

【Unity】简单举例UI合批,优化draw call

1. UGUI-Editor 首先引入UGUI-Editor插件 链接: https://pan.baidu.com/s/1PpxStvgRCDi9xjUr6j6nCQ?pwdm5ju 提取码: m5ju 或者直接去Github搜索UGUI-Editor 2. 没有UI时 3. 放几个UI看看效果 4. 选中Canvas,右键优化Batch 发现减少了3个,这是因为&…

STM32智能无人机控制系统教程

目录 引言环境准备智能无人机控制系统基础代码实现:实现智能无人机控制系统 4.1 数据采集模块 4.2 数据处理与飞行控制 4.3 通信与导航系统实现 4.4 用户界面与数据可视化应用场景:无人机应用与优化问题解决方案与优化收尾与总结 1. 引言 智能无人机控…

vue3创建项目

1. 安装node.js,添加环境变量,确保cmd里能使用node命令以及npm命令:node --version npm --version 本人安装的版本如下: 2. 安装vue的脚手架 npm install -g vue/cli 3. 创建vue项目:1)使用ui&#xff1…