MySQL之表的约束(上)

目录

空属性(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-数学作为一个整体了。

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

burpsuite官方靶场之命令注入

1.简单的命令注入 1.1 达成目标 成功执行whoami查看当前用户的名字。 1.2 攻击步骤 观察该靶场的页面,发现这是一个展示其商品信息的页面,点击view details可以展示每个商品的详情。 来到一个商品的详情页,发现画框部分是检查商品库存的功…

合合信息大模型“加速器”重磅上线

大模型技术的发展和应用,预示着更加智能化、个性化未来的到来。如果将大模型比喻为正在疾驰的科技列车,语料便是珍贵的“燃料”。本次世界人工智能大会期间,合合信息为大模型打造的“加速器”解决方案备受关注。 在大模型训练的上游阶段&…

CSS 后代选择器正确写法 爸爸儿子之间有代沟

CSS 后代选择器正确写法 爸爸儿子之间有代沟 example&#xff1a; > <body> > <div class"outer"> > <span class"inner"></span> > </div> > </body> > <head> > <style>…

如何在浏览器控制台Console中引入外部 JS

想要在某个网页执行一些脚本&#xff0c;却发现某个工具类&#xff0c;如 ajax 请求的 axios 该网页没有引入&#xff0c;或者引入了但控制台却访问不到&#xff0c;这时要怎么办呢&#xff1f; 只需要控制台执行如下代码就好了 var script document.createElement(script);…

Postman使用指南①网页版使用

postman官网地址&#xff1a;Postman API Platform 进入后点击右上角免费注册&#xff0c;注册后登录 登录之后即可在网页使用&#xff0c;无需下载

C语言学习笔记[22]:分支语句switch

switch语句 switch语句也是一种分支语句&#xff0c;常用于多分支的情况 switch语句的语法形式是&#xff1a; switch(整型表达式) {语句项; }而语句项是什么呢&#xff1f; case 整型常量表达式:语句; switch语句中的break 对于case 语句来说&#xff0c;我们day输入的多…

电动卡丁车语音芯片方案选型:让驾驶体验更智能、更安全

在追求速度与激情的电动卡丁车领域&#xff0c;每一次升级都意味着更加极致的驾驶体验。而今天&#xff0c;我们要介绍的&#xff0c;正是一款能够显著提升电动卡丁车智能化与安全性的语音芯片方案——为您的爱车增添一份独特的魅力与安全保障。 智能化升级&#xff0c;从“听…

ABeam德硕 | ABeam残疾员工运动员参观上海中心办公室,中野洋辅先生亲切慰问

近日&#xff0c;ABeam荣幸地邀请到公司的四位残疾员工运动员们来到上海中心办公室进行参观&#xff0c;并带领他们解锁「咨询顾问的工作日常」&#xff0c;领略咨询行业的魅力。 继半年前ABeam一行去往上海市残疾人文化体育促进中心拜访&#xff0c;这次的行程由ABeam全程安排…

开源网安入选全景图,成为唯一覆盖“开发安全”全领域厂商

​7月4日&#xff0c;知名网络安全媒体数说安全正式发布了《2024年中国网络安全市场全景图》&#xff0c;本次全景图共收录了408家国内优秀的网络安全企业&#xff0c;旨在为网络安全行业主管部门、从业者、产品及服务的使用者和购买单位以及资本机构提供全面、精准且具参考价值…

昇思25天训练营Day11 - 基于 MindSpore 实现 BERT 对话情绪识别

模型简介 BERT全称是来自变换器的双向编码器表征量&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;&#xff0c;它是Google于2018年末开发并发布的一种新型语言模型。与BERT模型相似的预训练语言模型例如问答、命名实体识别、自然语言推理、…

【matlab】状态空间模型与传递函数模型的建立与转换

目录 SISO系统 MIMO系统 状态空间模型 状态空间模型到传递函数模型的转换 传递函数模型到状态空间模型的转换 (1) 转换函数ss() (2) 规范形转换函数canon() (3) 常微分方程(传递函数)转换为状态空间模型函数dif2ss() 状态空间模型的变换 特征值、特征向量与广义特征向量的计算…

Java的基础语法

叠甲&#xff1a;以下文章主要是依靠我的实际编码学习中总结出来的经验之谈&#xff0c;求逻辑自洽&#xff0c;不能百分百保证正确&#xff0c;有错误、未定义、不合适的内容请尽情指出&#xff01; 文章目录 1.第一份程序1.1.代码编写1.2.代码运行1.2.1.命令行编译1.2.2.IEDA…

Science Advances|用于肌电检测的柔性微针电极阵列(健康监测/柔性传感/柔性电子)

2024年5月1日,美国南加州大学Hangbo Zhao课题组在《Science Advances》上发布了一篇题为“Highly stretchable and customizable microneedle electrode arrays for intramuscular electromyography”的论文。论文内容如下: 一、 摘要 可伸缩的三维穿透式微电极阵列在多个领…

Linux环境安装Maven

1.下载安装包 访问Maven官网下载地址&#xff1a;Maven – Download Apache Maven进行下载对应的安装包。 本文档使用的是apache-maven-3.9.8-bin.tar.gz 2.将下载好的安装包上传到环境上&#xff0c;本处是在/usr目录下新建了一个Maven的目录&#xff0c;如下&#xff1a; …

在线白板工具大揭秘:为何它成为远程团队的必备神器?

一直觉得白板是个很好的工具&#xff0c;不管是学习还是工作&#xff0c;它都能够帮助我们更好地整理思路。 作为一名经常需要远程协作和创意脑暴的职场人&#xff0c;显然传统普通的白板工具已经不够用了。 在这个数字化时代&#xff0c;我们更需要一个电子白板&#xff0c;一…

计算机如何存储浮点数

浮点数组成 在计算机中浮点数通常由三部分组成&#xff1a;符号位、指数位、尾数位。IEEE-754中32位浮点数如下&#xff1a; 上图32bit浮点数包含1bit的符号位&#xff0c;8比特的指数位和23bit的尾数位。对于一个常规浮点数&#xff0c;我们来看看它是如何存储和计算的。这里…

FPGA的理解,个人的见解,不一定对

类似于面包板上搭建电路&#xff0c;但是使用的是逻辑单元模块&#xff1b;如加法器&#xff0c;减法器&#xff0c;寄存器等 没有模拟电路的电容&#xff0c;电阻&#xff1b;但是逻辑单元的底层实现&#xff0c;使用MOS管等电路实现电路的开关&#xff1b;从而表示0&#xf…

1002-15SF 同轴连接器

型号简介 1002-15SF是Southwest Microwave的29.2 mm (V) DC 至 67 GHz 连接器。该连接器用于连接电缆和设备的组件&#xff0c;它可以提供电气连接和机械支撑。广泛应用于通信、电子、航空航天、军事等领域。 型号特点 电缆的中心导体插入连接器后部的母插座内置应力释放装置可…

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

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

GD 32点亮流水灯

1. 0 软件架构设置 2.0 API 接口以及数据结构定义 3.0 程序代码实现 程序项目的结构如下所示&#xff1a; 第一步&#xff1a;编写LED驱动&#xff0c;初始化驱动程序 创建结构体&#xff1a;第一个参数表示GPIO使能&#xff0c;第二个参数表示单片机的IO口&#xff0c;第三个…