MySQL基础之约束、多表查询、事务【基础完结】

news2024/11/26 8:38:26

1 SQL约束

SQL约束是用于规定表中的数据规则,如果存在违反约束的数据行为,行为会被终止。

1.1 如何创建约束

  • • 在创建表的时候进行规定(create table)
  • • 修改表的时候进行规定(alter table)

1.2 约束的分类

  • • 非空约束,not null,该列不能存储NULL值
  • • 唯一约束,unique,保证必须有唯一值
  • • 主键约束,primary key,not null和unique的组合,使用在ID上
  • • 默认约束,default,没有给列赋值时的默认值,default null
  • • 检查约束,check,保证列中的值符合指定的条件
  • • 外键约束,foreign key

1.2.1 非空约束

not null约束强制不接受null值,即在对表中数据进行插入时,该字段不能为null。

create table person(
  id int not null,
  name varchar(255) not null,
  age int not null
);


-- 删除age上的约束
alter table person modify age int null;

-- 添加age上的约束
alter table person modify age int not null;

1.2.2 唯一约束

unique唯一约束,一个表中可以有多个唯一约束。

create table person(
  id int not null unique,
  name varchar(255) not null,
  age int not null
);

-- 删除id上的唯一约束
alter table person drop index id;

-- 添加id上的唯一约束
alter table person add unique (id);

1.2.3 主键约束

primary key 主键约束

  • • 主键必须包含唯一的值
  • • 主键列不能为null
  • • 每个表中只有一个主键
  • • MySQL中一般设置自增主键
create table person(
  id int primary key auto_increment,
  name varchar(255) not null,
  age int not null
);


-- 删除主键
alter table person drop primary key;

-- 添加主键
alter table person add primary key (id);

1.2.4 检查约束

check 约束用于限制列中的值的范围

create table person(
  id int not null,
  name varchar(255) not null,
  age int not null,
  constraint chk_id check (id > 0)
);

-- 删除检查约束
alter table person drop check chk_id;

-- 添加检查约束
alter table person add constraint chk_id check (id > 0);

1.2.5 外键约束

外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。

当两张表没有外键约束时,当部门表中(父表)的数据删除后,会导致员工表(子表)的数据不完整。

--添加外键语法
create table 表名(
字段名 数据类型,
字段名 数据类型,
...
[constraint] [外键名称] foreign key [外键字段名] references 主表(主表列名)
);

alter table 表名 add constraint 外键名称 foreign key (外键字段名) references 主表(主表列名);

删除外键
alter table 表名 drop foreign key 外键名称;

2 多表查询

从多张表中查询数据

create table dept(
  id int primary key not null ,
  name varchar(64) not null
);

insert into dept values (1,'研发部'),(2,'市场部'),(3,'财务部'),(4,'销售部'),(5,'经理部'),(6,'人事部');



CREATE TABLE test.emp
(
    id int PRIMARY KEY NOT NULL AUTO_INCREMENT,
    name varchar(20) NOT NULL,
    age int NOT NULL,
    selary mediumtext NOT NULL,
    entry_date date NOT NULL,
    dept_id int NOT NULL
);

INSERT INTO test.emp (id, name, age, selary, entry_date, dept_id) VALUES (1, '王明', 29, '20000', '2023-07-25', 1);
INSERT INTO test.emp (id, name, age, selary, entry_date, dept_id) VALUES (5, '李四', 20, '10000', '2020-07-25', 1);
INSERT INTO test.emp (id, name, age, selary, entry_date, dept_id) VALUES (6, '赵四', 22, '20000', '2021-07-25', 1);
INSERT INTO test.emp (id, name, age, selary, entry_date, dept_id) VALUES (2, '李红', 20, '15900', '2022-07-25', 2);
INSERT INTO test.emp (id, name, age, selary, entry_date, dept_id) VALUES (3, '王强', 30, '13000', '2020-07-25', 3);
INSERT INTO test.emp (id, name, age, selary, entry_date, dept_id) VALUES (4, '张三', 20, '14000', '2023-07-18', 4);


-- 添加外键
alter table emp add constraint emp_dept_fk foreign key (dept_id) references dept(id);


-- 关联查询
select * from emp,dept where emp.dept_id = dept.id;

2.1 多表查询分类

多表查询分类:

  1. 连接查询
    1. 内连接,相当于与查询A、B交集部分数据
    2. 外连接 左外连接,查询左表的所有数据,以及两张表交集部分数据 右外连接,查询右表的所有数据,以及两张表交集部分数据
  2. 自连接,当前表与自身的连接查询,自连接必须使用表别名
  3. 子查询

2.2 内连接

内连接查询的是两张表交集的部分


语法:
隐式内连接
select 字段列表 from 表1, 表2 where 条件;

显式内连接
select 字段列表 from 表1 inner join 表2 on 连接条件;

select * from emp,dept where emp.dept_id = dept.id;

select * from emp inner join dept on emp.dept_id = dept.id;

2.3 外连接

外连接分为:左外连接、右外连接

-- 左外连接语法:
select 字段列表 from 表1 left join 表2 on 条件;
-- 右外连接语法:
select 字段列表 from 表1 right join 表2 on 条件;

select dept.*,emp.* from emp left join dept on emp.dept_id = dept.id;

select dept.*,emp.* from emp right join dept on dept.id = emp.dept_id;

2.4 自连接

-- 语法
select 字段列表 from 表A 别名A join 表B 别名B on 条件;

select * from emp as e1 join emp as e2 on e1.id = e2.id;

2.5 联合查询

联合查询,union,union all 对于union查询,就是把多次查询结果合并起来,形成一个新的查询结果集


语法:
select 字段列表 from 表A
union [all]
select 字段列表 from 表B;

-- 查询年龄大于20,和 工资大于500的员工,注意,union all的时候对数据直接合并,会有重复的
select * from emp where age > 20
union all
select * from emp where selary > 500;


-- 去掉all之后,先合并再去重,数据就不重复了
select * from emp where age > 20
union
select * from emp where selary >500;

注意:

  • • 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致

  • • union all会将全部的数据进行合并在一起,union会对合并之后的数据去重

    22.6 子查询

    SQL语句中嵌套select语句,称为嵌套查询,又称为子查询。

2.6.1 标量子查询

标量子查询,子查询返回的是单个值

语法
select * from t1 where column1 = (select column1 from t2);
-- 标量子查询,子查询返回的是单个值
select * from emp where dept_id = (select id from dept where name = '研发部');

select * from emp where entry_date > (select entry_date from emp where name = '李红');

2.6.2 列子查询

列子查询,子查询返回的结果是一列,常用的操作符有:in、not in、any、some、all

-- 查询研发部和市场部的员工信息
-- 先查研发部和市场部的部门id
select id from dept where name ='研发部' or name = '市场部';
-- 再根据部门id查询员工信息
select * from emp where dept_id in (select id from dept where name ='研发部' or name = '市场部');

-- 使用left join关联查询员工表和部门表
select * from emp left join dept on emp.dept_id = dept.id where dept.name ='研发部' or dept.name = '市场部';


-- 查询比市场部所有人员都高的员工工资
select * from emp;

select selary from emp where dept_id = (select id from dept where name='市场部');

select * from emp where selary > all ( select selary from emp where dept_id = (select id from dept where name='市场部'));


-- 我自己能想到的查询方式
-- 1、先获取市场部最高的工资
select max(selary) from emp left join dept on emp.dept_id = dept.id where dept.name = '市场部';
-- 2、在查询大于该工资的员工信息
select * from emp left join dept on emp.dept_id = dept.id where selary > 15900;

-- 比任意市场部员工工资高的员工信息
select * from emp where selary > any ( select selary from emp where dept_id = (select id from dept where name='市场部'));

2.6.3 行子查询

行子查询,子查询返回的结果是一行(可以是多列),示例待补充

2.6.4 表子查询

表子查询,子查询返回的结果是多行多列,配合in使用

select * from emp where (name,age) in (select name,age from emp where selary >1 and dept_id = 1);

3事务简介

3.1 什么是事务

事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。

3.2 事务四大特性

  • • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • • 持久性(Durability):事务一旦提交或者回滚,它对数据库中的数据的改变是永久的。

3.3 并发事务问题

问题描述
脏读一个事务读到另一个事务还没有提交的数据
不可重复读一个事务前后读取同一个记录,但两次读取的数据不同,称为不好重复读
幻读一个事务按照条件查询数据时,没有对应的数据行,当在插入数据时,又发现这行数据已经存在,好像出现了幻影

3.4 事务隔离级别

隔离级别脏读不可重复读幻读
read uncommitted✔️✔️✔️
read committedX✔️✔️
repeatable read(默认)XX✔️
serializableXXX

serializable可以理解为用锁来解决并发问题。注意:事务隔离级别越高,数据越安全,但是性能越低。 但是性能越低。

3.5 简单使用

-- 设置当前session的事务隔离级别`set session transaction isolation level repeatable read;  
  
-- 开启事务  
start transaction;  
  
-- 对数据库的相关操作  
update ...  
  
-- 提交  
commit;  
  
-- 回滚  
rollback;

关注我,我们一起学习

微信公众号二维码.jpg

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

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

相关文章

设计师的宝库:5个供应免费素材的设计网站

今天给大家推荐五个设计素材网站,设计师看到就要码住,码住就是灵感。 即时设计 即时设计是一个可在线使用的设计资源网站,在网页中打开「即时设计」的官网,登录账号后即可使用即时设计提供的设计资源。 即时设计 - 可实时协作的…

史上最全Windows安全工具汇总

史上最全Windows安全工具锦集来源于网络整理,安全性自测。 下载方式:史上最全Windows安全工具汇总

为了理直气壮怼回去,写了一个日志切面输出接口出入参数

1.背景 我们在日常排查问题过程中知道,入参传错是导致接口调用失败的常见原因之一。特别是提供给第三方调用的回调接口和openAPI接口,由于无法保证第三方开发人员的水平,经常问题不断,反反复复找你问为啥掉不通,甚至吐…

多人游戏小程序源码系统 带完整的搭建教程

现如今,人们对于娱乐和社交的需求也在不断提高。多人游戏作为一种能够满足人们社交需求的游戏类型,越来越受到用户的欢迎。同时,小程序作为一种轻量级的应用程序,在微信等平台上得到了广泛的应用和推广。因此,开发多人…

【LeetCode力扣】287.寻找重复数(中等)

1、题目介绍 原题链接&#xff1a;287. 寻找重复数 - 力扣&#xff08;LeetCode&#xff09; 示例 1&#xff1a; 输入&#xff1a;nums [1,3,4,2,2] 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [3,1,3,4,2] 输出&#xff1a;3提示&#xff1a; 1 < n &l…

hbase代码报错(以及解决方法)

》》》直接上代码 package HBase_Apiimport org.apache.hadoop.conf.Configuration import org.apache.hadoop.hbase.{HBaseConfiguration, TableName} import org.apache.hadoop.hbase.client.{Connection, ConnectionFactory, Get, Put} import org.apache.hadoop.hbase.ut…

烟台海森大数据——数据驱动材料研发,本土化为安全护航

随着大数据时代的来临&#xff0c;人们的生产和生活&#xff0c;各方面都在发生着深刻的变化。作为与国计民生息息相关的材料行业&#xff0c;也在数据时代迎来了新的机遇与挑战。 新材料是我国重点推进的战略性新兴产业之一&#xff0c;对于支撑整个战略性新兴产业发展&#…

海康Visionmaster-全局脚本:通过全局脚本加载本地图像的方法

通过 VM 的全局脚本加载本地图像的步骤如下所示&#xff1a; 1、打开全局脚本&#xff0c;选择需要的示例 2、在运行函数中插入如下代码 1. public int Process() 2. { 3. //m_operateHandle 二次开发 SDK 操作句柄 4. if (m_operateHandle IntPtr.Zero) 5. { return ImvsSd…

Solidity在函数里面返回中文报错原因

错误 from solidity: ParserError: Invalid character in string. If you are trying to use Unicode characters, use a unicode"…" string literal. –> contracts/text.sol:90:24: | 90 | return (1,true,“你好”); 原因与解决方法 在Solidity中&#xff0c;…

unittest 统计测试执行case总数,成功数量,失败数量,输出至文件,生成一个简易的html报告带饼图

这是一个Python的单元测试框架的示例代码&#xff0c;主要用于执行测试用例并生成测试报告。其中&#xff0c;通过unittest模块创建主测试类MainTestCase&#xff0c;并加载其他文件中的测试用例&#xff0c;统计用例的执行结果并将结果写入文件&#xff0c;最后生成一个简单的…

应用开发平台集成表单设计器系列之1——技术预研与技术选型

背景 表单的可视化配置&#xff0c;是低代码开发平台的重要组成部分。平台已实现的低代码配置部分&#xff0c;可以配置生成前端vue页面&#xff0c;对于属性较少的实体&#xff0c;如系统基础数据的管理、配置数据的维护&#xff0c;采用标准化的模板模式来生成&#xff0c;配…

腾讯云24元香港服务器有用过的吗?性能如何?

香港云服务器可以选择腾讯云香港地域的轻量应用服务器&#xff0c;轻量2核2G配置、20M峰值带宽、40G SSD系统盘&#xff0c;优惠价格24元一个月&#xff0c;Linux系统是288元一年&#xff0c;Windows系统是360元一年&#xff0c;腾讯云百科txybk.com分享腾讯云香港轻量应用服务…

墨者学院 Ruby On Rails漏洞复现第一题(CVE-2018-3760)

打开 web 页面&#xff1a; 发现是Ruby&#xff0c;在Ruby 3.7.1和更低版本中&#xff0c;存在由辅助解码引起的路径遍历漏洞。攻击者可以使用%252e%252e/访问根目录并读取或执行目标服务器上的任何文件。可以先检测一下是否有此漏洞&#xff1a; /assets/file:%2f%2f/etc/pas…

Cassandra介绍(一)

1.1. 概念 Apache Cassandra 是高度可扩展的&#xff0c;高性能的分布式 NoSQL 数据库。 Cassandra 旨在处理许 多商品服务器上的大量数据&#xff0c;提供高可用性而无需担心单点故障。 Cassandra 具有能够处理大量数据的分布式架构。 数据放置在具有多个复制因子的不同机器…

学习c++的第十三天

目录 文件和流 打开文件 关闭文件 写入文件 读取文件 读取 & 写入实例 文件位置指针 异常处理 扩展知识 抛出异常 标准的异常 定义新的异常 文件和流 到目前为止&#xff0c;我们已经使用了 iostream 标准库&#xff0c;它提供了 cin 和 cout 方法分别用于从标…

一文搞懂优先队列及相关算法

大家好&#xff0c;我是 方圆。优先队列在 Java 中的定义是 PriorityQueue&#xff0c;它基于 二叉堆 数据结构实现&#xff0c;其中的元素并不是全部有序&#xff0c;但它能够支持高效地 获取或删除最值元素。 二叉堆是一种特定条件的 完全二叉树&#xff0c;树的根节点为堆顶…

vivo 网络端口安全建设技术实践

作者&#xff1a;vivo 互联网安全团队 - Peng Qiankun 随着互联网业务的快速发展&#xff0c;网络攻击的频率和威胁性也在不断增加&#xff0c;端口是应用通信中的门户&#xff0c;它是数据进出应用的必经之路&#xff0c;因此端口安全也逐渐成为了企业内网的重要防线之一&…

公司团建小游戏开发小程序游戏互动小游戏

在现代工作环境中&#xff0c;团队合作和员工士气是取得成功的关键因素。为了增强团队合作、提升员工士气&#xff0c;并促进员工之间的互动&#xff0c;公司团建小游戏成为了一种备受欢迎的方式。本文将探讨如何开发公司团建小游戏&#xff0c;以达到这些目标。 1. 游戏概念 …

2023下半年软考信息系统项目管理师上午真题及答案

1.( B )不属于项目建议书的核心内容。 A.项目的必要性 B.初步可行性研究 C.项目的市场预测 D.项目建设必需的条件 解析&#xff1a; 2.在监控项目工作过程中&#xff0c;当遇到变更请求时&#xff0c;为使项目工作绩效重新与项目管理计划致&#xff0c;而进行的有目的的活动…

【双指针+简化去重操作】Leetcode 15 三数之和

【双指针简化操作】Leetcode 15 三数之和 解法1 解法1 新建一个嵌套列表&#xff1a;List<List<Integer>> result new List<>(); 初始化一个ArrayList并直接赋值&#xff1a;ArrayList<Integer> result new ArrayList<>(Arrays.asList(1, 2…