数据库的约束 not null, unique, default, primary key, foreign key, check

约束可以理解成 数据库提供的一种针对数据的合法性进行验证的机制, 在创建表的时候使用

1. 约束类型

  • NOT NULL - 指示某列不能存储 NULL 值, 表里的这个内容是必填项
  • UNIQUE - 保证某列的每行必须有唯一的值, 不能重复  每次插入/修改时, 都要先触发查询, 如果当前插入/修改的值已经存在, 就会插入/修改失败
  • DEFAULT - 规定没有给列赋值时的默认值  一般在指定列插入时会用到, 如果没有规定默认值, 默认值就为NULL
  • PRIMARY KEY - 主键  NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
  • FOREIGN KEY - 外键  涉及到两个表之间的关系 保证一个表中的数据匹配另一个表中的值的参照完整性。
  • CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句

2. not null

create table 表名 (列名 类型 not null,...);

创建一个学生表, 如果没加not null:

 Null这一列为YES, 表示这一列可以为空

加上not null:

 Null这一列为NO, 表示这一列不可以为空

当我们在对这一列的数据进行添加和修改时, 不可以附空值:

2. unique

 create table 表名 (列名 类型 unique,...);

创建一个学生表, 如果没加unique:

是允许插入重复数据的

加上unique:

 KEY这一列中id为UNI, 表示id这一属性是unique的

当我们在对这一列的数据进行添加和修改时, 不可以添加和修改为重复值:

3. default

create table 表名 (列名 类型 default 默认值,...);

创建一个学生表, 如果没加default:

没有指定id为2时的name, 那么默认值为NULL

加上default:

 Default这一列对应的name为'无名氏', 将name的默认值设为'无名氏'

再进行指定列插入时, 不指定name:

4. primary key

create table 表名 (列名 类型 primary key,...);

注意: 一个表中只能有一个主键, 但一个主键不一定只对应一个列, 可以是多个列联合作为主键, 称为联合主键 

指定student表中id作为主键:

Key这一列id为PRI, 表示id为主键, 并且Null为NO, 主键不能为NULL 

 因为主键的条件是not null + unique, 所以可以这样定义:

默认也是主键  

自增主键:

一般来说, 我们会使用整数id作为主键, 那么在实际开发中, 我们如何保证id的值是非空且唯一的呢?

在mysql中提供了"自增主键", 在每次插入新的数据时, 都能把主键基于最大的主键值+1

语法:

create table 表名 (列名 类型 primary key auto_increment,...);

例:

将学生表的id设为自增主键

Extra中auto_increment就是对自增主键的说明

插入数据:

此时, 插入的null并非是真的null值, 而是根据自增规则, 自动插入数据, 默认从0开始自增

当然这种情况下, 我们也可以手动指定id, 不一定非要依赖自增主键:

此时再次指定null, 下一个id应该是101:

如果将id为100和101都删去, 再次插入null, 下一个id是102!

如此, 5-99这些id, 就不会再自增主键时出现了

基于分布式系统下生成唯一id:

自增主键, 本质上上mysql服务器存储了当前表中的最大id, 再进行累加的, 但是如果基于分布式系统, 存储数据的时候, 每一个机器都存储了部分数据, 这些数据分别都有最大值, 那么显然"自增主键"就无能为力了

那么在分布式系统中, 生成唯一id算法有很多种, 此处给出一个最简单最朴素的方式, 其他的生成算法核心思路大同小异的:

时间戳(ms) + 机器的编号(应用程序所谓机器) + 随机因子(随机数)

---> 得到一个字符串

---> 计算hash值, 得到一个整数, 作为id 

简单介绍计算字符串hash值的算法:

java中自带一个比较简单的计算方式, 但是在实际开发中用得不多, 在实际开发中, md5, sha1用的多, 但其实这几种算法都是数学问题, 只是套用的公式不同, 想要了解具体的算法并不容易, 但我们更关注的是算法的特性

以md5 为例(其他大同小异), 主要有三个方面特性:

  1. 定长  无论输入的字符串多长, 最终算出来的hash值都是一样长的
  2. 分散  输入的字符串, 那怕只有一点点不一样, 得到的md5值都会差异很大 (这也是称为hash算法的根本)
  3. 不可逆 给你原始字符串, 计算hash值, 对计算机来说非常简单, 但黑泥hash值,还原成原始的字符串, 理论上不可行

5. foreign key

create table 表名 (列名 类型 , 列名 类型, ... , foreign key (当前表中(子表)的某一列名) references 表名2 (表名2中(父表)的某个列名));

注意:  引用父表的这个列, 要么是主键, 要么是unique, 不然不能当做外键使用

例:

如果不加外键链接, 创建student表和class表:

 给class添加数据:

给student添加数据:

此时我们看到, 给学生班级id设成100也是可以通过的,  但实际班级id没有100, 所以就会出现问题

加外键链接, 创建student表和class表:

此时, student的classID和class的classID就建立了联系, student中classID的值, 必须在class中classID中存在!!  

class表, 就对student表产生了制约, 此时就把class表(制约别人的表) 称为"父表"(parent table), 把student表(被制约的表) 称为"子表"(child table)

此时向表中添加数据:

因为class表中没有classID为100的班级, 所以添加失败, 触发了外键约束

删除父表中的外键约束:

删除classID为3可以成功, 而删除classID为1不成功, 因为在子表中已经使用个这个classID

所以实际上, 确实是父亲约束儿子, 儿子不能随意添加和修改, 但同时儿子也在约束父亲, 不能随意删除和修改, 是双向约束的过程!!

考虑一个场景: 一个电商网站, 肯定会有两个数据库:

商品表(id,name,price...)

订单表(orderid, ...,goodid)

订单表中, 存在一些记录, 引用自商品表的某个数据

未来某一天, 我不买这个商品了, 要下架, 如果这时想要删除这件商品, 还不被允许的, 那应该怎么办呢?

答案是: 添加标记字段

商品表(id,name,price... isOK)

isOK如果是1, 表示有效数据, isOK是0, 表示无效数据

当我们要删除商品时, 不再是delete, 而是将isOK改成0, 后续用户查询商品列表时, 也是通过条件, 只返回isOK为1的记录, 此时即保证了数据能够删除, 也不违背外键约束, 这种删除称为逻辑删除

其实在硬盘上删除一个文件, 也不是说把硬盘上的对应空间的数据给擦除, 也是标记成无效(标记成无效后, 可能就会被系统用来存储别的数据了)

那么如何删除数据才是安全的呢?  --- 物理删除!!(把硬盘砸了)

6. check

check mysql5.7并不支持, 主要的作用是在执行语句之前判断是否满足check后的条件

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

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

相关文章

mysql存储比特位

一、介绍 二、SQL CREATE TABLE bits_table (id INT PRIMARY KEY AUTO_INCREMENT,bit_value BIGINT UNSIGNED );-- 插入一个 8 位的 BIT 值 INSERT INTO bits_table (bit_value) VALUES (B10101010);-- 查询并格式化输出 SELECT id,bit_value,CONCAT(b, LPAD(BIN(bit_value),…

解决小皮面版搭建php网站数据库连接不了

首先进入mysql bin目录下 并执行cmd mysql -u root -pCREATE USER userlocalhost IDENTIFIED BY pass;GRANT ALL PRIVILEGES ON *.* TO userlocalhost;GRANT SELECT, INSERT, UPDATE ON database_name.* TO xxwlocalhost;FLUSH PRIVILEGES;select host ,user from mysql.user…

pdf文件怎么编辑?分享3个专业的pdf软件!

在数字化时代,PDF文件已成为我们工作、学习中的得力助手。然而,面对需要修改的PDF文件,许多人却感到无从下手。今天,就让我们一起探索如何轻松编辑PDF文件,并介绍几款实用的编辑软件,让你轻松应对各种PDF编…

Linux DAY 6 _systemctl

systemctl命令,通过这个命令控制系统操作 语法:systemctl start | stop | status | enable | disable 服务名 start 启动 stop 关闭 status 查看状态 enable 开启开机自启 disable 关闭开机自启 服务名: NetworkManager 主网络服务 net…

DFE_offset失调校准

1.校准原因 *制造工艺的限制:晶体管在制造过程中,由于工艺的限制,不可能做到完全对称,这导致了输入级晶体管的性能存在微小的差异。 *输入级偏置电流的不对称:输入级晶体管的偏置电流也会存在差异,这也会…

如何在OpenHarmony上使用SeetaFace2人脸识别库?

简介 相信大部分同学们都已了解或接触过OpenAtom OpenHarmony(以下简称“OpenHarmony”)了,但你一定没在OpenHarmony上实现过人脸识别功能,跟着本文带你快速在OpenHarmony标准设备上基于SeetaFace2和OpenCV实现人脸识别。 项目效…

如何理解kmp的套娃式算法啊?

概念 KMP算法,全称Knuth Morris Pratt算法 。文章大部分内容出自《数据结构与算法之美》 核心思想 假设主串是a,模式串是b 在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,对已经对比过的字符,是否能找到…

向上调整建堆与向下调整建堆的时间复杂度 AND TopK问题

目录 前言建堆的时间复杂度TOPK问题总结 前言 本篇旨在介绍使用向上调整建堆与向下调整建堆的时间复杂度. 以及topk问题 博客主页: 酷酷学!!! 感谢关注~ 建堆的时间复杂度 堆排序是一种优于冒泡排序的算法, 那么在进行堆排序之前, 我们需要先创建堆, 为什么说堆排序的是优于…

YOLOv8绘制map曲线图

yolov8源码绘制的map曲线图不够清晰,python代码绘制的曲线图导入word之后清晰度也不够高,所以选择使用matlab来绘制曲线图,matlab可以直接复制图窗到word中,在转换成pdf也不会失真。点击编辑,复制图窗即可复制到word中…

【Linux】:Linux 2.6内核 调度队列和调度原理

朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux 2.6内核 调度队列和调度原理,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言&#xff1a…

做抖店需要截流吗?聊下抖店的出单玩法和运营思路

我是王路飞。 做抖店需要截流吗? 关于抖店的玩法,一直都是众说纷纭,谁都想发表点自己的意见。 尤其是很多新手,可能以前接触过淘宝等传统电商,对截流等玩法有个基本了解,就认为抖店是不是也是这样玩的。…

使用Flask ORM进行数据库操作的技术指南

文章目录 安装Flask SQLAlchemy配置数据库连接创建模型类数据库操作插入数据查询数据更新数据删除数据 总结 Flask是一个轻量级的Python Web框架,其灵活性和易用性使其成为开发人员喜爱的选择。而ORM(对象关系映射)则是一种将数据库中的表与面…

免费开源人脸识别系统,支持RESTful API

简介 CompreFace 是一个免费开源的人脸识别项目,您不需要具备机器学习技能就能安装设置和使用 CompreFace,官方提供了基于 docker 的部署方法,可以方便地部署在本地或者云端服务器上。 CompreFace 提供了 RESTful API,用于人脸识别…

超详细的前后端实战项目(Spring系列加上vue3)(一步步实现+源码)前端篇(一)

最近想着一步步搭建一个前后端项目,将每一步详细的做出来。(如果有不足或者建议,也希望大佬们指出哦) 前端初始化 1.根据vue脚手架创建vue项目 这里可以用很多方法创建vue项目,大家看着创建吧,只要能创建…

C++、与C语言的一些变化、新增的一些函数类型、面向对象程序设计的基本特点

C 面向对象的编程思想 万物皆对象 类库: MFC Qt opencv opengl cout:标准输出流对象 endl:换行符 新的数据类型 bool型:逻辑真假—— true、false 变量的存储类型 auto:变量在定义时由编译器自动推到…

Linux网络配置全攻略:解读/etc/network/interfaces文件的精髓

欢迎来到我的博客,代码的世界里,每一行都是一个故事 Linux网络配置全攻略:解读/etc/network/interfaces文件的精髓 前言文件结构与基本概念配置网络接口的常用参数高级网络配置技巧实用工具与调试技巧实战案例与最佳实践 前言 在我们的日常生…

JVM(7):虚拟机性能分析和故障解决工具之jstat工具

1 jstat(JVM Statistics Monitoring Tool)作用 监视虚拟机各种运行状态信息,可以显示本地或者是远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据 2 命令格式 jstat [options vmid [interval[count]]] 参数解释 第一个参数:options 代…

谷歌插件编写

目录 manifest.json {"manifest_version": 3,"name": "Floating Ball","version": "1.0","description": "A floating ball on the right side of the webpage.","permissions": ["act…

C语言 数组——计算最大值的函数实现

目录 计算最大值 计算最大值的函数实现 应用实例:计算班级最高分​编辑​编辑 返回最大值所在的下标位置 返回最大值下标位置的函数实现​编辑 一个综合应用实例——青歌赛选手评分​编辑​编辑​编辑​编辑​编辑 计算最大值 计算最大值的函数实现 应用实例&…

hcia datacom学习(8):静态NAT、动态NAT、NAPT、Easy IP、NAT server

1.私网地址 在现实环境中,企业、家庭使用的网络是私网地址(内网),运营商维护的网络则是公网地址(外网)。私网地址是在局域网(LAN)内使用的,因此无法被路由,不…