视图、索引介绍

目录

1、视图

1.1、什么是视图

1.2、创建视图

1.3、使用视图

1.4、修改视图

1.5、删除视图

1.6、视图的优点

2、MySQL存储结构

2.1、MySQL中的页

3、索引

3.1、索引的数据结构

3.2、B树 和 B+树

3.3、B+树在MySQL索引中的应用

3.4、索引分类


1、视图

1.1、什么是视图

视图是一个虚拟的表,它是基于一个或多个基础表或基他视图的查询的结查集

视图本身不存储数据,而是通过执行查询来动态生成数据

案例:查询用户的所有信息和考试成绩

所有有这样开发需求的程序员,都需要写这么复杂的SQL

把以上SQL定义成一个视图,用户就可以像操作普通表一样使用视图进行查询、更新和管理。

1.2、创建视图

语法:create view view_name [(column_list)] as select_statement

1. 不指定列名创建

由于定义视图时没有指定列名,这时视图中的列是由结果集决定的

为重复的列起别名就可以解决列重复的问题

2. 指定列名创建视图

指定列名之后,视图会根据指定的列名创建,查询结果集中是否重名不重要

创建完成后,可以使用指定列名排序

select * from v_student_score_v1 order by id;

1.3、使用视图

-- 查看视图
show tables;
-- 查询视图

show create view v_student_score;
-- 使用视图

select * from v_student_score;

使用真实表,在查询列表中随时可以加上其他字段,而使用视图查询,只能查到创建时指定的字段,不能再添加查询字段,所以可以使用视图隐藏不能被展示的字段

视图和真实表进行表连接查询:

select * from v_student_total_points v, student s where v.id = s.id;

1.4、修改视图

通过基本表修改数据,会影响视图

// 修改唐三藏的JAVA成绩为99分

 update score set score = 99 where student_id = 1 and course_id = 1;

// 查询视图,发现唐三藏这条记录已被修改

select * from v_student_socre;

通过视图修改数据,也会影响基本表

// 修改唐三藏的计算机⽹络成绩为99分

update v_student_socre set score = 99 where score_id = 3;

// 发现更新失败,因为创建视图时使用了order by 语句


// 更新视图

update v_student_socre_v1 set score = 99 where score_id = 3;

// 查看基础表数据发现已被修改

select * from score where student_id = 1 and course_id = 5;

结论:不论更新了视图还是基础表,相互都会被影响,查询的数据都是最新结果

以下视图不可更新:
◦ 创建视图时使用聚合函数的视图
◦ 创建视图时使用 DISTINCT
◦ 创建视图时使用 GROUP BY 以及 HAVING 子句
◦ 创建视图时使用 UNION 或 UNION ALL
◦ 查询列表中使用子查询
◦ 在FROM子句中引用不可更新视图

1.5、删除视图

语法:drop view 视图名;

1.6、视图的优点

1. 简单性:视图可以将复杂的查询封装成一个简单的查询。例如,针对一个复杂的多表连接查询,可以创建一个视图,用户只需查询视图而无需了解底层的复杂逻辑。

2. 安全性:通过视图,可以隐藏表中的敏感数据。例如,一个系统的用户表中,可以创建一个不包含密码列视图,普通用户只能访问这个视图,而不能访问原始表。

3. 逻辑数据独立性:视图提供了一种逻辑数据独立性,即使底层表结构发生变化,只需修改视图定义,而无需修改依赖视图的应用程序。使用到应用程序与数据库的解耦

4. 重命名列:视图允许用户重命名列名,以增强数据可读性。

2、MySQL存储结构

2.1、MySQL中的页

1..ibd文件中最重要的结构体就是Page(页),页是内存与磁盘交互的最小单元,默认大小为16KB每次内存与磁盘的交互至少读取一页,所以在磁盘中每个页内部的地址都是连续的,之所以这样做,是因为在使用数据的过程中,根据局部性原理,将来要使用的数据大概率与当前访问的数据在空间上是临近的,所以一次从磁盘中读取一页的数据放入内存中,当下次查询的数据还在这个页中时就可以从内存中直接读取,从而减少磁盘I/O提高性能

.ibd 文件:innodb存储引擎生成的表空间文件,后缀是.ibd


局部性原理:
时间局部性(Temporal Locality):如果⼀个信息项正在被访问,那么在近期它很可能还会被再次访问。
空间局部性(Spatial Locality):将来要⽤到的信息⼤概率与正在使⽤的信息在空间地址上是临近的。

2. 每一个页中即使没有数据也会使用 16KB 的存储空间,同时与索引的B+树中的节点对应

查看页大小:show variables like 'innodb_page_size';

3. 在MySQL中有多种不同类型的页,最常用的就是用来存储数据和索引的"索引页",也叫做"数据页",但不论哪种类型的页都会包含页头(File Header)和页尾(File Trailer),页的主体信息使用数据"行"进行填充,数据页的基本结构如下图所示: 

3、索引

MySQL的索引是⼀种数据结构,它可以帮助数据库高效地查询、更新数据表中的数据。索引通过 ⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。 类似于书籍的目录,通过指向数据行的位置,可以快速定位和访问表中的数据

使用索引的目的只有一个,就是提升数据检索的效率,在应用程序的运行过程中,查询操作的频率远远高于增删改的频率。

3.1、索引的数据结构

hash

时间复杂度是0(1),查询速度非常快,但是MySQL并没有选择HASH做为索引的默认数据结构主要原因是 HASH 不支持范围查找

二叉搜索树

中序遍历是一个有序序列,所以支持范围查找,但有几个问题导致它不适合用作索引的数据结构

1. 最坏情况下时间复杂度为O(N)
2. 节点个数过多无法保证树高

  • AVL和红黑树,虽然是平衡或者近似平衡,但是毕竟是二叉结构,当节点个数过多时,无法保证树的高度
  • 在检索数据时,每次访问某个节点的子节点时都会发生一次磁盘IO,而在整个数据库系统中,IO是制约数据库性能的主要因素,减少IO次数可以有效的提升性能

N叉树

每个节点可以有超过两个的子节点,可以解决树高的问题

时间复杂度:O(logN)
在数据量相同的情况下,可以有效的控制树高,也就是说可以使用更少的IO次数找到目标节点,从而提高数据库的效率。但是MySQL认为N叉树做为索引的数据结构还不够好

3.2、B树 和 B+树

B树 和 B+树都是 N 叉搜索树

B树:上述N叉树的案例就是B树

B+树:

B+树是⼀种经常用于数据库和文件系统等场合的平衡查找树,是MySQL索引采用的数据结构

时间复杂度:O(logN)
可以有效的控制树高

B+树的特点:

1. 一个节点,可以存储N个key,N个key划分出了N个区间(而不是N+1个区间)
2. 每个节点中的key的值,都会在子节点中也存在(同时该key是子节点的最大值)
3. B+树的叶子节点,是首尾相连,类似于一个链表

4. 非叶子节点只保存索引,不存数据,真实数据都保存在叶子节点中

面试题:

1. 索引使用了什么数据结构?

答:B+树

2. 介绍一下B+树

答:B+树与B树对比,B+树的优势是:
1. 叶子节点之间有一个相互连接的引用,可以通过一个叶子节点找到它相邻的兄弟节点
MySQL索引在组织叶子节点时使用的是双向链表
2. 非叶子节点的值都包含在叶子节点中
MySQL索引 非叶子节点只保存了对子节点的引用,没有保存真实的数据,所有真实的数据都保存在叶子节点中
3. 对于B+树而言,在相同树高的情况下,查找任一元素的时间复杂度都一样,性能均衡

3.3、B+树在MySQL索引中的应用

以查找id为5的记录,完整的检索过程如下:
1. 首先判断B+树的根节点中的索引记录,此时5<7,应访问左孩子节点,找到索引页2
2. 在索引页2中判断id的大小,找到与5相等的记录,命中,加载对应的数据页

以上的IO过程,加载索引页1-->加载索引页2-->加载数据页3(3次IO)


所有关于页的操作和访问都是在内存中进行的

理论上三层树高的B+树可以存放多少条记录:

假设一条用户数据大小为1KB,在忽略数据页中数据页自身属性空间占用的情况下,一页可以存16条数据
索引页一条数据的大小为,主键用BIGINT类型占8Byte,下一页地址6Byte,一共是14Byte,一个索引页可以保存16*1024/14=1170条索引记录
如果只有三层树高的情况,综合只保存索引的根节点和二级节点的索引页以及保存真实数据的数据页,那么一共可以保存1170*1170*16=21,902,400条记录,也就是说在两千多万条数据的表中,可以通过三次IO就完成数据的检索

3.4、索引分类

主键索引

1. 当在一个表上定义一个主键PRIMARY KEY时,会自动创建索引,索引的值是主键列的值。InnoDB使用它作为聚集索引 / 聚簇索引 / 主键索引。

2. 推荐为每个表定义一个主键。如果没有逻辑上唯一且非空的列或列集可以使用主键,则添加一个自增列。

3. 如果没有为表定义PRIMARY KEY,InnoDB使用第一个UNIQUE和NOT NULL的列作为聚集索引。(聚集索引可以标识数据行的唯一性)

普通索引

1. 最基本的索引类型,没有唯一性的限制。工作中通常为查询频繁的列创建索引为了提升查询效率

2. 可以包含一个列也可以包含多个列,包含多个列时称为复合索引或组合索引

唯一索引

1. 当在一个表上定义一个唯一键 UNQUE 时,自动创建唯一索引。

2. 与普通索引类似,但区别在于唯一索引的列不允许有重复值。

如果表中没有 PRIMARY KEY 或合适的 UNIQUE索引,InnoDB 会为新插入的行生成一个行号并用 6 字节的 ROW_ID 字段(数据行中的一个隐藏列之一)记录,ROW_ID 单调递增,并使用ROW_ID做为索引。这种索引也是聚集索引

非聚集索引

1. 聚集索引以外的索引称为非聚集索引或二级索引

2. 二级索引中的每条记录都包含该行的主键列,以及二级索引指定的列。

3. InnoDB使用这个主键值来搜索聚集索引中的行,这个过程称为回表查询

注意

1. 创建索引之后都会生成一棵索引树,创建多少索引生多少棵索引树

2. 创建索引后,生成的索引树,也是会占用磁盘空间的创建索引时,要慎重考虑一下需不需要
3. 索引树越多,对增、删,改的效率影响越大

非聚集索引的查询过程:
1. 通过索引查到叶子节点中的索引记录
2. 通过索引记录中的主键值,去主键索引树中找相应的完整记录,这个过程称为回表查询

select * from student where name = '张三';(回表查询

3. 通过索引查询的列,包含在索引中,不需要回表查询了,这种的现象叫做索引覆盖

假设 name 和 sn 这两列为组合索引:

select sn from student where name = '张三';(索引覆盖

^

问题:当前的组合索引中通过学号来查姓名索引生不生效(走不走索引)?

select name from student where sn = '100002';

答:不生效。创建索引时,name列在sn列之前,那么使用的时候也要先使用name再使用sn如果只使用sn列,那么索引就会失效,如果非要使用sn列查,可以为sn单独创建一个索引。

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

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

相关文章

QT6(46)5.2 QStringListModel 和 QListView :列表的模型与视图的界面搭建与源代码实现

&#xff08;154&#xff09;理论讲解 &#xff1a; 例题程序的界面搭建 &#xff1a; &#xff08;155&#xff09;以下开始完善代码 &#xff0c;先准备要给 model 的源数据&#xff0c;一些字符串 &#xff1a; 给出该头文件&#xff0c;以全面展示其内容&#xff1a; #i…

C++设计模式(GOF-23)——03 C++观察者模式(Observer / Event、发布-订阅模式、事件模式)

文章目录 一、观察者模式概述二、传统代码 vs 观察者模式对比1. 传统实现&#xff08;紧耦合&#xff09;2. 观察者模式实现&#xff08;松耦合&#xff09; 三、Mermaid 类图说明四、核心设计要点1. 接口分层设计2. 通知机制实现3. 扩展性验证 五、应用场景与注意事项适用场景…

海外 AI 部署:中国出海企业如何选择稳定、安全的云 GPU 基础设施?

2025年&#xff0c;中国 AI 企业在模型训练、产品落地和创新应用上不断刷新人们的认知。DeepSeek-R1、Qwen3 等国产大模型密集亮相&#xff0c;国内大模型产业热潮持续升温。与此同时&#xff0c;一个现实的问题也在被越来越多企业关注&#xff1a;模型虽然训练得起&#xff0c…

AI绘画工具实测:Stable Diffusion本地部署指

对于想要深度体验AI绘画的创作者来说&#xff0c;本地部署Stable Diffusion能带来更自由的创作空间。本文将详细介绍Windows系统下的部署流程&#xff0c;帮助你在个人电脑上搭建专业的AI绘画环境。 硬件准备与基础环境配置 部署前需确认电脑配置&#xff1a;建议NVIDIA显卡&…

macOS - 快速上手使用 YOLO

文章目录 一、关于 yolo二、安装三、命令行使用官方示例yolo cfgyolo predict 四、Python 调用results 数据 一、关于 yolo YOLO(YOLO&#xff08;You Only Look Once&#xff09;是一种流行的物体检测和图像分割模型&#xff0c;由华盛顿大学的约瑟夫-雷德蒙&#xff08;Jose…

<script setup> 语法糖

下面&#xff0c;我们来系统的梳理关于 Vue 3 <script setup> 语法糖 的基本知识点&#xff1a; 一、<script setup> 核心概念 1.1 什么是 <script setup>&#xff1f; <script setup> 是 Vue 3 中 Composition API 的编译时语法糖&#xff0c;它通过…

MYSQL-InnoDB逻辑存储结构 详解

InnoDB逻辑存储结构 段—区—页—行 表空间&#xff1a; 默认情况下InnoDB有一个共享表空间ibdata1&#xff0c;所有数据放入这个表空间&#xff0c;如果开启了innodb_file_per_table&#xff08;默认ON&#xff09;&#xff0c;每张表都可以放到一个单独的表空间&#xff0…

[特殊字符] Python 批量合并 Word 表格中重复单元格教程(收货记录案例实战)

在日常办公中&#xff0c;Word 表格中常出现重复的“供应商名称”或“物料编码”&#xff0c;会导致表格冗余且视觉混乱。这时候&#xff0c;用 Python 自动合并重复单元格可以大幅提升表格专业度和可读性。本篇给大家演示如何用 python-docx 实现该功能。 ✅ 功能概览 自动读取…

从零构建Node.js服务托管前端项目

下面是一个完整的指南&#xff0c;教你如何从零开始构建一个Node.js服务来托管前端项目&#xff0c;并代理API请求到其他服务器。 1. 项目初始化 # 创建项目目录 mkdir node-proxy-server cd node-proxy-server# 初始化npm项目 npm init -y# 安装必要依赖 npm install expres…

Lynx vs React Native vs Flutter 全面对比:三大跨端框架实测分析

一文看懂三大热门跨端技术的历史渊源、架构机制、开发体验、包体积对比与性能评估。 我陪你用实测数据带你理性选型&#xff0c;不踩坑&#xff0c;不盲信。 1. 框架简介&#xff1a;它们是谁&#xff1f;来自哪里&#xff1f;干嘛用&#xff1f; 框架名称所属公司发布时间初衷…

CKESC的ROCK 180A-H 无人机电调:100V 高压冗余设计与安全保护解析

一、核心技术参数与性能指标 电压范围&#xff1a;支持 12~26S 锂电&#xff08;适配 110V 高压系统&#xff09;电流特性&#xff1a; 持续工作电流&#xff1a;90A&#xff08;特定散热条件&#xff09;瞬时耐流&#xff08;1 秒&#xff09;&#xff1a;220A&#xff0c;3 …

优化 ArcPy 脚本性能

使用并行处理 如果硬件条件允许&#xff0c;可以使用 Python 的并行处理模块&#xff08;如 multiprocessing&#xff09;来同时处理多个小任务。这样可以充分利用多核处理器的优势&#xff0c;提高脚本的执行效率。 import multiprocessing def process_raster(raster):arcpy…

Windows下CMake通过鸿蒙SDK交叉编译三方库

前言 华为鸿蒙官方的文章CMake构建工程配置HarmonyOS编译工具链 中介绍了在Linux平台下如何使用CMake来配置鸿蒙的交叉编译环境&#xff0c;编译输出在Harmony中使用的第三方so库以及测试demo。 本文主要是在Windows下实现同样的操作。由于平台差异的原因&#xff0c;有些细节…

从C学C++(6)——构造函数和析构函数

从C学C(6)——构造函数和析构函数 若无特殊说明&#xff0c;本博客所执行的C标准均为C11. 构造函数与析构函数 构造函数定义 构造函数是特殊的成员函数&#xff0c;当创建类类型的新对象&#xff0c;系统自动会调用构造函数构造函数是为了保证对象的每个数据成员都被正确初…

清理 Windows C 盘该注意什么

C 盘空间不足会严重影响系统性能。 清理 C 盘文件时&#xff0c;首要原则是安全。错误地删除系统文件会导致 Windows 无法启动。下面我将按照 从最安全、最推荐到需要谨慎操作的顺序&#xff0c;为你详细列出可以清理的文件和文件夹&#xff0c;并提供操作方法。 第一梯队&…

Python Selenium 滚动到特定元素

文章目录 Python Selenium 滚动到特定元素⚙️ **1. 使用 scrollIntoView() 方法&#xff08;最推荐&#xff09;**&#x1f5b1;️ **2. 结合 ActionChains 移动鼠标&#xff08;模拟用户行为&#xff09;**&#x1f9e9; **3. 使用坐标计算滚动&#xff08;精确控制像素&…

你写的 Express 接口 404,可能是被“动态路由”吃掉了

本文首发在我的个人博客&#xff1a;你写的 Express 接口 404&#xff0c;可能是被“动态路由”吃掉了 前情提要 最近参与公司的一个项目前端 React&#xff0c;后端用的 Express。目前我就做一些功能的新增或者修改。 对于 Express &#xff0c;本人没有公司项目实战经验&…

【Java面试】你是怎么控制缓存的更新?

&#x1f504; 一、数据实时同步失效&#xff08;强一致性&#xff09; 原理&#xff1a;数据库变更后立即失效或更新缓存&#xff0c;保证数据强一致。 实现方式&#xff1a; Cache Aside&#xff08;旁路缓存&#xff09;&#xff1a; 读流程&#xff1a;读缓存 → 未命中则…

react-嵌套路由 二级路由

什么是嵌套路由&#xff1f; 在一级路由中又内嵌了其他路由&#xff0c;这种关系就叫做嵌套路由&#xff0c;嵌套至一级路由内的路由又称作二级路由 嵌套路由配置 实现步骤 配置二级路由 children嵌套 import Login from "../page/Login/index"; import Home from …

【CMake基础入门教程】第八课:构建并导出可复用的 CMake 库(支持 find_package() 查找)

很好&#xff01;我们进入 第八课&#xff1a;构建并导出可复用的 CMake 库&#xff08;支持 find_package() 查找&#xff09;。 &#x1f3af; 本课目标 你将掌握&#xff1a; 如何构建一个库并通过 install() 导出其配置&#xff1b; 如何让别人在项目中使用 find_package…