Mysql入门3——多表操作、事务、索引

Mysql入门3——多表操作、事务、索引

一、多表设计

在项目开发中,在进行数据库表的结构设计时,会根据业务需求及业务模块之前的关系,分析并设计表的结构,由于业务之间相互关联,所以各个表之间也存在着各种关系:

  • 一对多
  • 一对一
  • 多对多

1、外键约束foreignkey

​ 外键约束是数据库管理系统中用于维护数据完整性的一种机制。它用于定义两个表之间的关系,确保一个表中的字段(外键)引用另一个表中的字段(主键)时,引用的值必须有效。这种约束有助于保持数据的一致性和完整性。(因此绑定外键会就不可单项删除)

基本概念

  1. 主键与外键
    • 主键是表中唯一标识一条记录的字段,不能重复且不能为NULL。
    • 外键是一个表中的字段,它引用另一个表的主键,建立起两者之间的关系。
  2. 维护数据完整性
    • 外键约束确保在一个表中引用的值在另一个表中存在,防止出现孤立的数据记录。
    • 例如,如果有一个订单表引用了用户表的用户ID,外键约束将确保所有订单的用户ID在用户表中是有效的。
逻辑外键(推荐使用):

​ 又叫事物外键,不使用foreignkey,使用语法(代码)上产生逻辑关联而产生的外键,与传统的外键不同,逻辑外键并不直接依赖于数据库管理系统的约束机制,而是通过应用程序逻辑或业务规则来维护。

基本概念

  1. 定义
    • 逻辑外键是一种没有被数据库管理系统强制施加的约束,它在应用层面上确保数据的一致性。
    • 逻辑外键通常是表中的一列(或多列),其值在另一个表中存在,但没有外键约束。
  2. 用途
    • 逻辑外键用于表示表之间的关系,尤其在需要灵活处理数据关系时。
    • 它允许开发者在不依赖数据库约束的情况下,维护和检查数据的完整性。

2、一对多

​ 一对多(One-to-Many)关系是多表设计中最常见的关系类型之一,指的是一个表中的一条记录可以与另一个表中的多条记录相对应。这种关系通常用于表示一个实体与多个相关实体之间的关联。

基本概念:
  1. 表的结构
    • 在一对多关系中,通常有两个表:主表从表
    • 主表中的每条记录可以在从表中找到多条对应的记录。
  2. 主键与外键
    • 主表的主键用于唯一标识每一条记录。
    • 从表中会有一个外键字段,用于引用主表的主键,以建立这两个表之间的联系。

实现在子表中添加字段(外键),来关联父表的主键

3、一对一

​ 一对一(One-to-One)关系是多表设计中的一种关系类型,指的是一个表中的一条记录与另一个表中的唯一一条记录相对应。这种关系在数据库设计中相对较少见,但在某些特定场景下非常有用。

基本概念:
  1. 表的结构
    • 在一对一关系中,通常有两个表:表A表B
    • 表A中的每条记录与表B中的一条记录相对应,反之亦然。
  2. 主键与外键
    • 一对一关系通常通过外键约束来实现,表A的主键也可以作为表B的主键,或者表B中的外键引用表A的主键。
    • 这种设计确保了每个表中的记录都是唯一的。

实现在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(unique

4、多对多

​ 多对多(Many-to-Many)关系是数据库设计中常见的一种关系类型,指的是一个表中的一条记录可以与另一个表中的多条记录相对应,同时另一个表中的一条记录也可以与第一个表中的多条记录相对应。为了实现多对多关系,通常需要使用一个中间表(或称为关联表)来管理这两个表之间的关系。

基本概念:
  1. 表的结构
    • 假设有两个主要表:表A表B
    • 由于表A中的记录可以与表B中的多条记录关联,因此需要一个中间表(表C)来存储这种关系。
  2. 中间表
    • 中间表通常包含两个外键,分别引用表A和表B的主键。
    • 每个外键的组合在中间表中形成一条唯一的记录,表示表A和表B之间的关联。

实现建立第三张中间表,中间表至少包括两个外键,分别关联两方主键


二、多表查询

​ 多表查询是指在数据库中同时涉及多个表的数据查询操作。这种查询通常需要使用**联结(JOIN)**操作来结合来自不同表的数据,以便获取更全面的信息。多表查询在处理复杂的数据关系时非常有用,因此在关系数据库中广泛应用。

  • 内连接:相当于查询表的交集部分
  • 外连接
    • 左外连接:查询左表所有数据(包括两张表交集部分数据)
    • 右外连接:查询右表所有数据(包括两张表交集部分数据)
  • 子查询

以下是测试的表格数据源代码:

-- 创建员工表
create table tb_emp
(
    id          int auto_increment comment '主键ID'
        primary key,
    Username    varchar(20)                  not null comment '用户名',
    password    varchar(32) default '123456' null comment '密码',
    name        varchar(10)                  not null comment '姓名',
    gender      tinyint unsigned             not null comment '性别 1-男 2-女',
    image       varchar(300)                 null comment '图像的url',
    job         tinyint unsigned             null comment '职位: 1-班主任 2-讲师 3-学工主管 4-教研主管',
    entrydata   date                         null comment '入职日期',
    dept_id int unsigned comment '入职部门',
    create_time datetime                     not null comment '创建时间',
    update_time datetime                     not null comment '修改时间',
    constraint tb_emp_pk_2
        unique (Username)
)
    comment '员工表';

-- 创建部门表
create table tb_dept (
        id int unsigned primary key auto_increment comment 'ID',
        name varchar(10) not null unique comment '部门名称',
        create_time datetime not null comment '创建时间',
        update_time datetime not null comment '修改时间'
) comment '部门表';

insert into tb_dept (id, name, create_time, update_time) values
    (1, '学工部',now(),now()), (2, '教研部' , now(),now()), (3, '咨询部',now(),now()),
    (4, '就业部',now() ,now()), (5,'人事部',now() , now() ) ;

insert into tb_emp (id, Username, password, name, gender, image, job, entrydata, dept_id, create_time, update_time) values
        (1, 'jinyong', '123456', '金庸',1, '1.jpg',4, '2000-01-01' ,2, now(), now()),
        (2, ' zhangwuji', '123456', '张无忌',1, '2.jpg',2, '2015-01-01',2, now(), now()),
        (3, 'yangxiao', '123456', '杨逍',1, '3.jpg' ,2, '2008-05-01' ,2, now(), now()),
        (4, 'weiyixiao', '123456','韦-“笑',1, '4.jpg' ,2, '2007-01-01' ,2, now(), now()),
        (5, ' changyuchun', '123456', '常遇春',1, '5.jpg',2, '2012-12-05' ,2, now() , now()),
        (6, 'xiaozhao','123456', '小昭' ,2, '6.jpg',3, '2013-09-05' ,1, now() , now()),
        (7, 'jixiaofu', '123456', '纪晓芙' ,2, '7.jpg',1, '2005-08-01' ,1, now(), now()),
        (8, ' zhouzhiruo', '123456', '周芷若',2, '8.jpg' ,1, '2014-11-09',1, now(), now()),
        (9, 'dingminjun', '123456','丁敏君',2, '9.jpg' ,1, '2011-03-11',1, now(), now()),
        (10, ' zhaomin', '123456', '赵敏' ,2, '10.jpg' ,1, '2013-09-05' ,1, now(), now()),
        (11, 'luzhangke', '123456', '鹿杖客',1, '11.jpg',1, '2007-02-01 ', 1, now(), now()),
        (12, 'hebiweng', '123456', '鹤笔翁',1, '12.jpg',1, '2008-08-18',1, now(), now()),
        (13, ' fangdongbai', '123456','方东白',1, '13.jpg',2, '2012-11-01',2, now(), now()),
        (14, ' zhangsanfeng', '123456', '张三丰',1, '14.jpg' ,2, '2002-08-01' ,2, now() , now()),
        (15, 'yulianzhou', '123456', '俞莲舟',1, '15.jpg' ,2, '2011-05-01',2, now() , now()),
        (16, ' songyuanqiao', '123456', '宋远桥',1, '16.jpg' ,2, '2010-01-01' ,2, now() , now()),
        (17, ' chenyouliang', '123456', '陈友谅',1, '17.jpg', NULL, '2015-03-21' , NULL, now() , now());

1、笛卡尔积

​ 笛卡尔积(Cartesian Product)是数据库中两个表之间的一种操作,指的是将两个表中的每一条记录与另一个表中的每一条记录进行组合,形成一个新的结果集。笛卡尔积的结果集包含所有可能的记录组合,因此它的行数等于两个表行数的乘积

2、内连接

语法:
  • 隐式内连接:select 字段列表 from 表1, 表2 where 条件……;
  • 显式内连接:select 字段列表 from 表1 [inner] join 表2 on 连接条件……;

可以通过连接的条件可以来消除无效的笛卡尔积

示例

-- 多表查询
-- 内连接
-- A.查询员工的姓名, 及所属的部门名称(隐式内连接实现)
select tb_emp.name, tb_dept.name from tb_emp, tb_dept where tb_dept.id = tb_emp.dept_id;

-- B.查询员工的姓名, 及所属的部门名称(显式内连接实现)
select tb_emp.name 姓名, tb_dept.name 所属部门 from tb_emp inner join tb_dept on tb_dept.id = tb_emp.dept_id;

3、外连接

语法:
  • 左外连接:select 字段列表 from 表1 left [outer] join 表2 on 连接条件……;
  • 右外连接:select 字段列表 from 表1 right [outer] join 表2 连接条件……;

左外连接会完全包含左表数据(表1),右外连接会完全包含右表数据(表2)

示例

-- 外连接
-- A. 查询员工表 所有 员工的姓名, 和对应的部门名称(左外连接)
select tb_emp.name 姓名, tb_dept.name 所属部门 from tb_emp left join tb_dept on tb_dept.id = tb_emp.dept_id;
-- 此时会将没有选择部门的员工也打印出来

-- B. 查询部门表 所有 部门的名称, 和对应的员工名称(右外连接)
select tb_emp.name 姓名, tb_dept.name 所属部门 from tb_emp right join tb_dept on tb_dept.id = tb_emp.dept_id;
-- 此时会打印出没有人选择的部门,即全部部门

4、子查询

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

语法:

select * from t1 where column1 = (select column1 from t2 ……);

子查询外部的语句可以是insert/ update/ select的任何一个,最常见的是select

分类:
  • 标量子查询:子查询返回的结果为单个值
  • 列子查询:子查询返回的结果为一列(可以是多行)
  • 行子查询:子查询返回的结果为一行(可以是多列)
  • 表子查询:子查询返回的结果为多行多列
4.1标量子查询
  • 子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式
  • 常用的操作符:=、 <>、 >、 >=、 <、 <=

示例

-- 子查询
-- 标量子查询
-- A. 查询“教研部”所有员工信息
-- a. 查询 教研部 的部门 ID
select id from tb_dept where name = '教研部';
-- b. 查询该部门ID下的员工信息
select * from tb_emp where dept_id = (select id from tb_dept where name = '教研部');

-- B. 查询在“方东白”入职之后的员工信息
-- a. 查询 方东白 的入职日期
select entrydata from tb_emp where name = '方东白';
-- b. 查询 该日期后 入职的员工信息
select * from tb_emp where entrydata > (select entrydata from tb_emp where name = '方东白');
4.2列子查询
  • 子查询返回的结果是一列(可以是多行)
  • 常用的操作符:in、 not in等

示例

-- 列子查询(可以是多行)
-- A. 查询“教研部”和“咨询部” 的所有员工信息
-- a. 查询“教研部”和“咨询部”的部门ID
select id from tb_dept where name = '教研部' || name = '咨询部';
-- b. 根据部门ID,查询该部门下的员工信息
select * from tb_emp where dept_id in (select id from tb_dept where name = '教研部' || name = '咨询部');
4.3行子查询
  • 子查询返回的结果是一行(可以是多列)
  • 常用的操作符:=、 <>、 in、 not in

示例

-- 行子查询(可以是多列)
-- A. 查询与“韦一笑”的入职日期 及 职位都相同的员工信息
-- a. 查询“韦一笑”的入职日期 及 职位
select entrydata , job from tb_emp where name = '韦-“笑';
-- b. 查询与其入职日期相同的 及 职位都相同的员工信息
select * from tb_emp where entrydata = (select entrydata from tb_emp where name = '韦-“笑') and job = (select job from tb_emp where name = '韦-“笑');
select * from tb_emp where (entrydata, job) = (select entrydata , job from tb_emp where name = '韦-“笑');
4.4表子查询
  • 子查询返回的结果是多行多列,常作为临时表
  • 常用的操作符:in

示例

-- 表子查询
-- A. 查询入职日期是“2006-01-01”之后的员工信息, 及其部门名称
-- a. 查询入职日期是“2006-01-01”之后的员工信息
select * from tb_emp where entrydata > '2006-01-01';
-- b. 查询这部分员工信息及其所属部门的名称
select e.*, b.name from (select * from tb_emp where entrydata > '2006-01-01') e, tb_dept b where e.dept_id = b.id;

三、事务

​ 事务(Transaction)是数据库管理系统中的一个重要概念,是一组操作的集合,用于确保一组操作的完整性和一致性。事务是一系列被视为单个逻辑单位的操作,这些操作要么全部成功执行,要么全部不执行。事务的主要目的是保证数据的完整性,避免数据不一致的情况。

事务的基本特性(ACID

事务具有四个基本特性,统称为ACID特性:

  1. 原子性(Atomicity
    • 事务中的所有操作要么全部完成,要么全部不执行。如果事务中的某个操作失败,之前的所有操作也会被撤销,数据库恢复到事务开始前的状态。
  2. 一致性(Consistency
    • 事务必须使数据库从一个一致性状态转变为另一个一致性状态。在事务执行之前和之后,数据库的约束条件必须被满足。
  3. 隔离性(Isolation
    • 事务的执行不应受到其他事务的影响。多个事务并发执行时,每个事务都应像是独立的,互不干扰。隔离级别的设置决定了事务之间的可见性和干扰程度。
  4. 持久性(Durability
    • 一旦事务提交,其对数据库所做的更改是永久性的,即使系统崩溃或出现故障,已提交的事务也不会丢失。

事务的操作:

-- 事务 --
-- 开启事务 - start transaction  或者  begin  --(类似于一个操作的备份)
start transaction;

-- 删除部门
delete from tb_dept where id = 2;

-- 删除部门下的员工
delete from tb_emp where dept_id = 2;

-- 提交事务 -- 当所有的事务都成功运行了,再提交,且操作不可逆
commit;

-- 回滚事务 -- 如果有运行失败的事务,可以通过回滚事务,恢复原来的数据
rollback;

四、索引

​ 索引是数据库管理系统中用于提高数据查询性能的重要数据结构。它类似于书籍的目录,可以帮助快速定位到所需的数据,而无需扫描整个表。索引通过创建一个额外的数据结构来加速查找操作,从而提高查询效率。

4.1索引的结构:

Mysql数据库中默认的索引结构是B+tree

B+tree:

​ B+树是一种自平衡的树数据结构,广泛用于数据库和文件系统中,以高效地管理和存储大量数据。它是B树的一种变体,具有一些特定的特性,使其在某些应用中更加高效。

B+树的基本概念

  1. 树的结构
    • B+树是多路平衡查找树,节点可以有多个子节点。每个节点包含多个键值和指向子节点的指针。
    • 所有的叶子节点在同一层级,这使得树的高度保持较小,有利于快速查找。
  2. 键的存储
    • 在B+树中,所有的数据记录只存储在叶子节点中,而内部节点只存储键值和指向子节点的指针。这种设计使得内节点更加高效,有助于减少树的高度。
  3. 顺序访问
    • 叶子节点通过指针相互连接,允许顺序访问。这使得B+树在范围查询和排序操作中表现出色。

在这里插入图片描述

特点

  • 每一个节点,可以存储多个key(有n个key,就有n个指针)
  • 所有的数据都存储在叶子节点,非叶子节点仅用于索引数据
  • 叶子节点形成了一颗双向链表,便于数据的顺序及区间范围查询

4.2语法:

  • 创建索引:create [unique] index 索引名 on 表名(字段名, ……);
  • 查看索引:show index from 表名;
  • 删除索引:drop index 索引名 on 表名;

注意事项

  • 主键字段,再建表时,会自动创建主键的索引,且主键索引在所有索引中性能是最高的
  • 添加唯一约束时,数据库实际上会添加唯一索引

示例

-- 索引
-- 创建 : 为tb_emp表的name字段建立一个索引
create index tb_emp_name on tb_emp(name);

-- 查询 : 查询tb_emp表的索引信息
show index from tb_emp;

-- 删除 : 删除tb_emp表中name字段的索引
drop index tb_emp_name on tb_emp;

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

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

相关文章

基于SSM的智慧篮球馆预约系统

前言 近些年&#xff0c;随着中国经济发展&#xff0c;人民的生活质量逐渐提高&#xff0c;对网络的依赖性越来越高&#xff0c;通过网络处理的事务越来越多。随着智慧篮球馆预约的常态化&#xff0c;如果依然采用传统的管理方式&#xff0c;将会为工作人员带来庞大的工作量&a…

css设置滚动条样式

效果图&#xff1a; // 滚动条样式 div::-webkit-scrollbar {width: 4px; } /* 滚动条滑块&#xff08;里面小方块&#xff09; */ div::-webkit-scrollbar-thumb {border-radius: 10px;-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);opacity: 0.2;background-color…

【面试经典150】day 8

#1024程序员节 | 征文# 作为一个未来的程序员&#xff0c;现在我要继续刷题了。 力扣时刻。 目录 1.接雨水 2.罗马数字转整数 3.最后一个单词的长度 4.最长公共前缀 5.反转字符串中的单词 1.接雨水 好好好好好好&#xff0c;一开始就接雨水。我记得接了n次了。。。 痛苦战…

【读书笔记·VLSI电路设计方法解密】问题25:为什么时钟如此重要

时钟是一种在高电平和低电平之间振荡的电信号。它通常是一个具有预定周期(频率)的方波,如图3.6所示。在同步数字电路中,时钟信号协调芯片上所有电路元件的动作。电路在时钟信号的上升沿、下降沿或两者的边缘处变为活动状态以实现同步。时钟信号相关问题是任何VLSI芯片设计中…

ASP.NET Core 8.0 中使用 Hangfire 调度 API

在这篇博文中&#xff0c;我们将引导您完成将 Hangfire 集成到 ASP.NET Core NET Core 项目中以安排 API 每天运行的步骤。Hangfire 是一个功能强大的库&#xff0c;可简化 .NET 应用程序中的后台作业处理&#xff0c;使其成为调度任务的绝佳选择。继续阅读以了解如何设置 Hang…

HarmonyOS NEXT初级案例:网络数据请求

使用HTTP访问网络 “HTTP协议”的全称:超文本传输协议(Hyper Text Transfer Protocol)。 一、添加网络管理权限 在“module.json5”文件中添加网络访问权限配置: "module": {"requestPermissions": [{"name":"ohos.permission.INTER…

【leetcode】动态规划

19. 918 环形子数组的最大和 题目&#xff1a; 给定一个长度为 n 的环形整数数组 nums &#xff0c;返回 nums 的非空 子数组 的最大可能和 。 环形数组 意味着数组的末端将会与开头相连呈环状。形式上&#xff0c; nums[i] 的下一个元素是 nums[(i 1) % n] &#xff0c; nums…

《2024中国泛娱乐出海洞察报告》解析,垂直且多元化方向发展!

随着以“社交”为代表的全球泛娱乐市场规模不断扩大以及用户需求不断细化&#xff0c;中国泛娱乐出海产品正朝着更加垂直化、多元化的方向发展。基于此&#xff0c;《2024中国泛娱乐出海洞察报告》深入剖析了中国泛娱乐行业出海进程以及各细分赛道出海现状及核心特征。针对中国…

Python游戏开发超详细第二课/一个小游戏等制作过程(入门级篇共2节)

直播内容&#xff0c;这里都用大多用照片代替了哈&#xff0c;因为在写一遍很累&#xff0c;哥哥姐姐理解一下抱歉抱歉 一个是我懒的写一遍&#xff0c;但是刚学的兄弟姐妹可不许学我偷懒哈 二防止有人偷懒&#xff0c;直接复制粘贴代码&#xff0c;所以为了方便帮助你们学习&a…

【AIGC】ChatGPT应用之道:如何打破`专家`幻象,提升AI协作质量

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;ChatGPT的实际能力用户对ChatGPT的常见误解超越误解&#xff0c;合理设定期望总结 &#x1f4af;超越“专家”幻想设定合理的期望总结 &#x1f4af;提升人工智能协作质量…

寻找大自然的颜色

走在停停&#xff0c;停停走走&#xff0c;恍惚间一天过去了&#xff0c;转瞬间一年过去了&#xff0c;身边的一切在变化又不在变化&#xff0c;生活是自己的又不是自己的。 今天是个特殊的日子&#xff0c;其实前几天对我而言就算特殊的日子了&#xff0c;一个心里暗暗等待着却…

python之数据结构与算法(数据结构篇)-- 集合

一、集合的概念 所谓的编程中的”集合“&#xff0c;其实和高中数学中集合是一样的的。比如&#xff1a;羊村和狼堡看作一个集合&#xff0c;而狼堡中的"灰太狼"、"红太狼"、"小灰灰"则可看作狼堡中的元素&#xff0c;同理&#xff0c;羊村中的…

通过火山云API来实现:流式大模型语音对话

这里我们需要在火山云语音控制台开通大模型的流式语音对话、获取豆包模型的apiKey&#xff0c;开通语音合成项目。 这里使用的豆包模型是Doubao-lite&#xff0c;延迟会更低一些配置说明 这里一共有四个文件&#xff0c;分别是主要的fastAPI、LLM、STT、文件 TTS中需要配置 ap…

洛谷 U411986 数的范围(二分模板)

题意&#xff1a;在一个有序序列里面找某个值的初始出现下标和最后出现下标&#xff0c;如果该值不存在&#xff0c;输出-1 -1。 整数二分模板题&#xff0c;该题主要用来练习如何写两种情况下的二分函数的代码模板。 1&#xff09;upper_bound函数&#xff1a;用来寻找边界点A…

鸿蒙是必经之路

少了大嘴的发布会&#xff0c;老实讲有点让人昏昏入睡。关于技术本身的东西&#xff0c;放在后面。 我想想来加把油~ 鸿蒙发布后褒贬不一&#xff0c;其中很多人不太看好鸿蒙&#xff0c;一方面是开源性、一方面是南向北向的利益问题。 不说技术的领先点&#xff0c;我只扯扯…

香橙派5(RK3588)使用npu加速yolov5推理的部署过程

香橙派5使用npu加速yolov5推理的部署过程 硬件环境 部署过程 模型训练(x86主机) 在带nvidia显卡(最好)的主机上进行yolo的配置与训练, 获取最终的best.pt模型文件, 详见另一篇文档 模型转换(x86主机) 下载airockchip提供的yolov5(从pt到onnx) 一定要下这个版本的yolov5, …

【力扣 + 牛客 | SQL题 | 每日三题】大厂笔试真题W1,W4

1. 力扣603&#xff1a;连续空余的座位 1.1 题目&#xff1a; 表: Cinema ------------------- | Column Name | Type | ------------------- | seat_id | int | | free | bool | ------------------- Seat_id 是该表的自动递增主键列。 在 PostgreSQL 中&#…

练习LabVIEW第十九题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第十九题&#xff1a; 创建一个程序把另外一个VI的前面板显示在Picture控件中 开始编写&#xff1a; 在前面板放置一个二…

C语言教程——数组(2)

目录 系列文章目录 前言 4、数组作为函数参数 4.1冒泡函数的错误设计 4.2数组名是什么&#xff1f; 总结 前言 我们知道一维数组是连续存放的&#xff0c;随着数组下标的增长&#xff0c;地址是由低到高依次存放的&#xff0c;二维数组&#xff0c;也是在内存里面是连续存放的…