05 MySQL--字段约束、事务、视图

1. CONSTRAINT 约束

创建表时,可以给表的字段添加约束,可以保证数据的完整性、有效性。比如大家上网注册用户时常见的:用户名不能为空。对不起,用户名已存在。等提示信息。
约束包括:

  • 非空约束:not null
  • 检查约束:check
  • 唯一性约束:unique
  • 主键约束:primary key
  • 外键约束:foreign key

1.1 NOT NULL 非空约束

语法格式:

create table t_stu(
  no int,
  name varchar(255) not null,
  age int
);

name字段不能为空。插入数据时如果没有给name指定值,则报错。

1.2 CHECK 检查约束

create table t_stu(
  no int,
  name varchar(255),
  age int,
  check(age > 18)
);

1.3 UNIQUE 唯一性约束

1.3.1 列级唯一约束

#语法格式:
create table t_stu(
  no int,
  name varchar(255),
  email varchar(255) unique
);

1.3.2 表级唯一约束:

使用表级约束可以为多个字段添加联合唯一约束。

create table t_stu(
  no int,
  name varchar(255),
  email varchar(255),
  unique(name,email)
);

1.4 FOREIGN KEY 外键

  • 外键是一种对应关系,一个外键对应一个参照字段 + 一个被参照字段。不像主键就是字段本身,因此外键需要另外命名。
  • 外键的键名中建议包含一个 fk 字段以一目了然这是个外键,如 t_school_schno_fk 。
  • 添加了外键约束的字段中的数据必须来自其他表的字段
  • 假设给a字段添加了外键约束,要求a字段中的数据必须来自b字段,b字段不一定是主键,但至少要有唯一性。例如学生表中引用的学校号 schno,在学校表中,这个字段的所有值都是唯一的
  • 外键约束可以给单个字段添加,叫做单一外键。也可以给多个字段联合添加,叫做复合外键。复合外键很少用。
  • a 表如果引用 b 表中的数据,就把 b 表叫做父表,把 a 表叫做子表。
    1. 创建表时,先创建父表,再创建子表。
    2. 插入数据时,先插入父表,在插入子表。
    3. 删除数据时,先删除子表,再删除父表。
    4. 删除表时,先删除子表,再删除父表。
create table t_school( 
  schno int primary key, 
  sname varchar(255) 
); 
create table t_student( 
  stuno int primary key, 
  name varchar(255), 
  age int, 
  schno int, 
  #创建一个外键
  constraint t_school_sno_fk foreign key(schno) references t_school(schno) 
);

1.4.1 级联操作

CASCADE关键字,可以令父表发生变化时,子表相应做出变化

一般我们的选择是,父表删除时选择级联置空 SET NULL;附表更新时选择级联更新 CASCADE。

  1. 级联删除

创建子表时,外键可以添加:on delete cascade,这样在删除父表数据时,子表会级联删除。谨慎使用。

create table t_student( 
  no int primary key, 
  name varchar(255), 
  age int, 
  sno int, 
  constraint t_school_sno_fk foreign key(sno) references t_school(sno) on delete cascade 
);
  1. 级联更新
create table t_student( 
  no int primary key, 
  name varchar(255), 
  age int, 
  sno int, 
  constraint t_school_sno_fk foreign key(sno) references t_school(sno) on update cascade 
);
  1. 级联置空
create table t_student( 
  no int primary key, 
  name varchar(255), 
  age int, 
  sno int, 
  constraint t_school_sno_fk foreign key(sno) references t_school(sno) on delete set null 
);

1.5 PRIMARY KEY 主键

1.6

  • 创建约束时也可以给约束起名字,将来可以通过约束的名字来删除约束:
create table t_stu(
  no int,
  name varchar(255),
  email varchar(255),
  constraint t_stu_name_email_unique unique(name,email)
);
  • 所有的约束都存储在一个系统表当中:table_constraints。这个系统表在这个数据库当中:information_schema

2. TRANSACTION 事务

事务只针对DML语句有效:因为只有这三个语句是改变表中数据的。

  1. insert
  2. delete
  3. update

2.1 事务四大特性:ACID

  • 原子性(Atomicity):是指事务包含的所有操作要么全部成功,要么同时失败。
  • 一致性(Consistency): 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。例如张三和李四的钱加起来是5000,中间不管进行过多少次的转账操作(update),总量5000是不会变的。这就是事务的一致性。
  • 隔离性(Isolation):一个事务的执行不能被其他事务干扰。例如当多个⽤户并发操作同⼀张表时,多个事务之间必须互不影响。
  • 持久性(Durability):一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

2.2 事务的隔离级别

  • 严重性从高到低排序:脏读 > 不可重复读 > 幻读
  • MS 默认的隔离级别:可重复读(REPEATABLE READ)。大部分数据库的默认隔离级别都是第二、三档。

在这里插入图片描述

2.2.1 数据读取问题

  • 脏读

指的 A 事务读取了 B 事务尚未提交的数据(即脏数据 Dirty Data)。在此情况下,如果 B 事务回滚了或者修改了这些数据,那么 A 事务读取这些脏数据就是不准确的。常发生于转账与取款操作中。

  • 不可重复读

A 事务执行过程中,要多次读取同一个数据行,但在自身没有修改该数据行的情况下,前后读到的数据不一致。这是由于其他事务修改了该数据。

  • 幻读

指在事务执行过程中,前后两次相同的查询条件得到的结果集(数据总量)不一致,可能会变多或变少。

  • 不可重复读和幻读的区别?

(1) 不可重复读是读取了其他事务更改的数据,针对update操作

解决:使用行级锁,锁定该行,事务 A 所有对该行的读取操作完成后才释放锁,这个时候才允许其他事务更改改行。

(2) 幻读是读取了其他事务新增的数据,针对insert和delete操作

解决:使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。

2.2.2 隔离级别

  • READ UNCOMMITTED(读未提交)

该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止任何数据读取问题,是一种理论层面的,在实际的数据库产品中,没有从这个级别起步的。

  • READ_COMMITTED (读提交)

该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。

  • REPEATABLE_READ (可重复读)

该隔离级别表示一个事务在整个过程中可以多次执行某个查询语句,并且每次返回的数据都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读

  • SERIALIZABLE (串行化)

所有的事务串行逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
在该隔离级别下,MS 的 InnoDB 引擎会给读操作隐式加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。

  • MVCC(多版本并发控制)

mysql中,默认的事务隔离级别是可重复读(repeatable-read),为了解决不可重复读,innodb采用了MVCC(多版本并发控制)来解决这一问题。 MVCC是利用在每条数据后面加了隐藏的两列(创建版本号和删除版本号),每个事务在开始的时候都会有一个递增的版本号,用来和查询到的每行记录的版本号进行比较。 MYSQL MVCC

2.2.3 查看与设置隔离级别

  • 查看当前会话的隔离级别:select @@transaction_isolation;
  • 查看全局的隔离级别:select @@gobal.transaction_isolation;

设置事务隔离级别:

  • 会话级:set session transaction isolation level read committed;
  • 全局级:set global transaction isolation level read committed;

2.3 可重复读隔离级别的具体实现

理论上隔离级别为可重复读时,只能杜绝脏读、不可重复读两个问题
但 MS 实现的可重复读,在很大程度上也避免了幻读问题(并不能完全解决)。

解决方案包括两种:

  • 针对快照读(普通 SELECT 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好的避免了幻读问题。
  • 针对当前读(执行任何 DML 语句都会执行一次当前读),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select … for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好的避免了幻读问题。

2.3.1 快照读是如何解决幻读的

普通的select语句都是采用的快照读。

什么是快照读?
顾名思义:事务隔离级别是可重复读的前提下,在整个事务的处理过程中,第一次执行 SELECT 语句时,会保存一个快照(第一次读取时固定下来的数据),今后只要执行相同的 SELECT 语句,都是读取的快照。

底层实现原理是:
由 MVCC(多版本并发控制)实现。
实现的方式是开始事务后,在执行第一个查询语句后,会创建一个 Read View,后续的查询语句利用这个 Read View,通过这个 Read View 就可以在 undo log 版本链找到事务开始时的数据,所以事务过程中每次查询的数据都是一样的,即使中途有其他事务插入了新纪录,是查询不出来这条数据的,所以就很好的避免了幻读问题。

演示:

事务A事务B
mysql> use powernode
mysql> use powernode
mysql> start transaction;
mysql> start transaction;
mysql> select * from a; //快照读
image.png
mysql> insert into a values(5);
mysql> commit;
mysql> select * from a; //快照读
image.png

2.3.2 当前读是如何解决幻读的

当前读,顾名思义:每一次都读取最新的数据。

当前读包括:update、delete、insert、select…for update,即所有 DML 语句。这个很好理解,因为增删改的时候都要基于最新的数据进行增删改。

而select…for update原理是:对查询范围内的数据进行加锁,不允许其它事务对这个范围内的数据进行增删改。也就是说这个select语句范围内的数据是不允许并发的,只能排队执行,从而避免幻读问题。

select…for update加的锁叫做:next-key lock。我们可以称其为:间隙锁 + 记录锁。间隙锁用来保证在锁定的范围内不允许insert操作。记录锁用来保证在锁定的范围内不允许delete和update操作。

假如有这样的数据:
image.png
SQL语句是这样写的:

select * from a where id between 2 and 4 for update;

那么id在[2-4]区间的所有记录行被锁定,不能插入3是通过间隙锁来搞定的。不能修改或删除2和4是通过记录锁来搞定的。

2.3.3 出现幻读的两种情况

在同一个事务处理过程中,如果前后两次都采用快照读,或者都采用当前读,则不会出现幻读问题。

如果第一次使用快照读,后面使用了当前读,则会出现幻读问题。

第一种产生幻读的场景

在 A 事务中第一次查询使用快照读,B 事务插入数据。然后在 A 事务中第二次查询使用当前读。则会产生幻读现象。

第二种产生幻读的场景

在事务 A 中第一次查询使用快照读,在事务 B 中插入一条数据,然后在事务 A 中更新事务 B 插入的那条记录,最后在事务A中再次使用快照读。则会发生幻读现象。
|

总结可重复读的幻读问题

要避免特殊场景下发生幻读的现象的话,就是尽量在开启事务之后,马上执行 select … for update 这类当前读的语句,因为它会对记录加 next-key lock,从而避免其他事务插入一条新记录。


3. VIEW 视图

3.1 视图的概念

视图是由数据库中的一个表或多个表导出的虚拟表,其内容由查询定义,其作用是方便用户对数据的操作。

同真实的表一样,视图包含一系列带有名称的列和行数据。

数据库中存储的是:表的定义 + 符合表定义的数据 + 视图的定义。
使用视图查询数据时,数据库系统会从原来的表中取出对应的数据放置于视图中。

视图中的数据是依赖于原来的表中的数据的。一旦表中的数据发生改变,显示在视图中的数据也会发生改变。
同时,对视图的更新,也会影响到原来表的数据。

视图是存储在数据库中的查询的SQL语句,

它主要出于两种原因:

  1. 视图可以隐藏表的字段名。不论是为了安全。例如,员工信息表,可以用视图只显示姓名、工龄、地址,而不显示社会保险号和工资数等;抑或是使复杂的查询易于理解和使用。这个视图就像一个“窗口”,从中只能看到指定的的数据列。这意味着你可以在这个视图上使用SELECT *,而你看到的将是你在视图定义里给出的那些数据列。
  2. 便于修改。如果一段很复杂的 SQL 语句在程序的多个地方被使用,如果此时想修改,就要多个地方同时修改,并且别忘了这段语句很复杂。如果我们提前将这段语句创建为视图,那么在修改时只要修改视图即可。类似于程序设计中的抽象过程。

3.2 视图的基本操作

  1. 只能将select语句创建为视图。
  2. 创建视图
#如果已经存在则 replace ,类似于 create table if not exists,用来保底确保操作无误
create or replace view v_emp as select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
  1. 修改视图
alter view v_emp as select e.ename,d.dname,d.deptno from emp e join dept d on e.deptno = d.deptno;
  1. 删除视图
    1. drop view if exists v_emp;
  2. 对视图增删改(DML:insert delete update)可以影响到原表数据。

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

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

相关文章

6.6 完数(project) educoder项目实训

前言 在最近的Python课上,做到这样一个“有趣”的作业,求得前n个完数,并输出其与其真约数的约数的加和式子,刚开始没怎么在意这个题,想着不就是做过好几遍了的语言基础练习题嘛,但是接下来的几小时没想到都…

探索设计模式的魅力:开启智慧之旅,AI与机器学习驱动的微服务设计模式探索

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,坚持默默的做事。 ✨欢迎加入探索AI与机器学习驱动的微服务设计模式之旅✨ 亲爱的科技爱好者们,有没…

【独家推荐】视频下载神器:一键解决Mac/Win视频下载转换难题!

在信息爆炸的时代,视频已经成为我们获取知识和娱乐的重要途径。然而,很多精彩视频并没有提供直接的下载链接,这就给广大视频爱好者带来了不小的困扰。不过,现在有了这款专为Mac和Windows用户打造的视频下载转换器,一切…

Redux入门:使用@reduxjs/toolkit构建React应用程序状态管理

随着应用程序复杂性的增加,有效管理应用程序状态变得越来越重要。Redux是一种流行的状态管理解决方案,随着应用程序复杂性的增加,有效管理应用程序状态变得越来越重要。Redux是一种流行的状态管理解决方案,但传统的Redux设置和使用过程比较繁琐。幸运的是,Redux官方团队推出了r…

C语言实现贪吃蛇项目(2)

先来看看效果: 20240420_212115 文章目录: 3.项目实现3.0宽字符的打印3.01本地化操作setlocale函数宽字符的打印 3.1贪吃蛇结构的创建和维护3.11贪吃蛇结构的创建3.12贪吃蛇的维护 3.2初始化游戏3.21.打印欢迎界面、隐藏光标和设置窗口大小3.22.绘制地图…

记录好用的python包

记录好用的python包 PipxCentos 安装pipx确保 Pip 被安装更新 Pip安装 Pipx添加 Pipx 到 PATH临时添加到 PATH:永久添加到 PATH: 验证 Pipx 安装 Hatch安装特性 Poetry安装准备工作创建虚拟环境激活虚拟环境安装包追踪 & 更新包常用配置pycharm 远程连接poetry创建的虚拟环…

pycharm创建的项目

pycharm生成django templates删出 settings.py

数据分析_商品维度占比及变化可视化分析(Pandas和Matplotlib)

数据分析_商品维度占比及变化可视化分析(Pandas和Matplotlib) 分析维度包括: 各商品年度销量占比 各商品月度销量变化 构建测试数据 这里你可以了解到: 如何生成时间相关的数据。 如何从列表(可迭代对象)中生成随机数据。 Pandas 的 DataFrame 自…

IOS 32位调试环境搭建

一、背景 调试IOS程序经常使用gdb,目前gdb只支持32位程序调试,暂不支持IOS 64位程序调试。IOS 32位程序使用GDB调试之前,必须确保手机已越狱,否则无法安装和使用GDB调试软件。下面详细介绍GDB调试IOS 32位程序的环境搭建。 二、I…

数字时代的智慧演奏

数字化时代,工业不再是孤独的机器运转,而是演绎着一场智能与数据的华丽交响。无数智能节点的联动,数据的涌动,成为工业的新活力,同时也是创新的源泉。 工业互联网将每个机器、设备连接在一起,打破了原本独立…

从预训练损失的角度,理解语言模型的涌现能力

原文:Understanding Emergent Abilities of Language Models from the Loss Perspective 摘要 本文从预训练损失的角度重新审视语言模型的涌现能力,挑战了以往以模型大小或训练计算量为标准的观念。通过实验,作者发现预训练损失是预测下游任…

SRIO系列-时钟逻辑与复位逻辑

一、前言 上一篇讲述了SRIO协议的基本概念,传输的HELLO帧格式、事务类型等,本篇说一下SRIO IP核的时钟关系。 基本的IP设置可以参考此篇文章:【高速接口-RapidIO】Xilinx SRIO IP 核详解-CSDN博客 二、时钟关系 PHY可以在两个时钟域上运行…

C#语法知识之运算符

3、运算符 目录 3、运算符1、算数运算符思考 秒转化时间 2、字符串拼接3、条件运算符4、逻辑运算符5、位运算符6、三目运算符思考 闰年 1、算数运算符 1、赋值符号 //把右侧的值赋给左侧的变量2、算数运算符 _ * / float f 1 / 2f; %3、算数运算符的优先级 //乘除余优先级高…

【数据结构3-栈和队列】

数据结构3-栈和队列 1 栈-特殊的线性表-先进后出1.1 栈的三个案例 2 队列-与栈相反-先进先出2.1 队列的案例 3 用C实现栈的代码:4 用C实现队列的代码 1 栈-特殊的线性表-先进后出 1.1 栈的三个案例 2 队列-与栈相反-先进先出 2.1 队列的案例 3 用C实现栈的代码&…

<计算机网络自顶向下> TCP拥塞

目录 TCP拥塞控制机制 TCP拥塞感知 TCP速率控制方法 TCP拥塞控制和流量控制的联合动作 TCP拥塞控制策略 TCP吞吐量 TCP公平性 TCP拥塞控制机制 端到端的拥塞控制机制 路由器不向主机提供有关拥塞的反馈信息 路由器负担较轻 符合网络核心简单的TCP/IP架构原则 端系统根据自…

【机器学习】农田智能监控系统的实践探索

机器学习赋能现代农业:农田智能监控系统的实践探索 一、机器学习在现代农业中的重要作用二、机器学习在农田智能监控系统中的应用三、农田智能监控系统的实践意义 在科技飞速发展的今天,机器学习技术正以其强大的数据处理和模式识别能力,逐步…

Windows下Git的使用

目录 一、克隆远程仓库到本地二、git的三板斧2.1 add-将代码添加到本地仓库2.2 commit-提交代码到本地仓库2.3 push-推送本次添加操作到远程仓库2.4 gitee只有三板斧吗? 三、推送后没有出现绿点四、push到远程时报错五、git图形化界面下载链接 一、克隆远程仓库到本…

nodejs大文件上传

安装依赖 1.express 帮我们启动服务&#xff0c;并且提供接口 2.multer 读取文件&#xff0c;存储 3.cors 解决跨域 项目的目录结构&#xff1a; 前端代码&#xff1a; <input type"file" /><script>const file document.queryselector(input)// 分隔…

【漏洞复现】WordPress_Wholesale_Market admin-ajax.php 任意文件读取漏洞

0x01 产品简介 WordPress Wholesale Market是一个WordPress主题,专门设计用于创建批发市场和在线商城网站。该主题提供了许多功能和设计元素,使您能够轻松地构建一个功能强大的批发市场平台,以满足批发商和零售商的需求。 0x02 漏洞概述 WordPress Wholesale Market存在任…

(2022级)成都工业学院数据库原理及应用实验八: 数据库恢复技术

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、成品仅提供参考 3、如果成品不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 Navicat Premium 16 Mysql 8.0.36 实验要求 1、使用mysqldump实现数据库备份。 2、使用mysqldump实…