详解数据库中的索引和视图

这篇具有很好参考价值的文章主要介绍了详解数据库中的索引和视图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

摘要:索引就是数据表中数据和相应的存储位置的列表,利用索引可以提高在表或视图中的查找数据的速度。

本文分享自华为云社区《数据库开发指南(六)索引和视图的使用技巧、方法与综合应用》,作者: bluetata 。

一、索引

1.1 什么是索引

索引就是数据表中数据和相应的存储位置的列表,利用索引可以提高在表或视图中的查找数据的速度。它类似于书籍的索引,可以帮助快速定位和检索数据。在数据库中,索引是对一个或多个列的值进行排序和存储的结构,它们包含指向实际数据位置的指针。

1.2 索引分类

数据库中索引主要分为两类:聚集索引和非聚集索引。SQL Server 还提供了唯一索引、索引视图、全文索引、XML 索引等等。聚集索引和非聚集索引是数据库引擎中索引的基本类型,是理解其他类型索引的基础。

1.2.1 聚集索引

聚集索引是值表中数据行的物理存储顺序和索引的存储顺序完全相同。聚集索引根据索引顺序物理地重新排列了用户插入到表中的数据,因此,每个表只能创建一个聚集索引。聚集索引经常创建在表中经常被搜索到的列或按顺序访问的列上。在默认情况下,主键约束自动创建聚集索引。

1.2.2 非聚集索引

非聚集索引不改变表中数据列的物理存储位置,数据与索引分开存储,通过索引指向的地址与表中的数据发生关系。

非聚集索引没有改变表中物理行的位置,索引可以在以下情况下使用非聚集索引:

  • 如果某个字段的数据唯一性比较高
  • 如果查询所得到的数据量比较少

1.2.3 聚集索引和非聚集索引的区别

这里用一个表格简单的总结一下聚集索引和非聚集索引的区别:

1.2.4 其他类型索引

除了以上索引,还有以下类型索引:

  • 唯一索引:如果希望索引键都不同,可以创建唯一索引。聚集索引和非聚集索引都可以是唯一索引。
  • 包含新列索引:索引列的最大数量是16个,索引列的字节总数的最高值是900。如果当多个列的字节总数大于900,切又想在这些劣种都包含索引是,可以使用包含新列索引
  • 视图索引:提供视图查询效率,可以视图的索引物理化,也就是说将结果集永久存储在索引中,可以创建视图索引。
  • XML索引:是与xml数据关联的索引形式,是XML二进制blob的已拆分持久表示形式
  • 全文索引:一种特殊类型的基于标记的功能性功能,用于帮助在字符串中搜索赋值的词

1.3 创建索引

1.3.1 语法

create [unique] [clustered | noclustered]
index index_name
on table_name (column_name ...)
[with fillfactor=x]

参数解释

unique 唯一索引
clustered 聚集索引
noclustered 非聚集索引
fillfactor 填充因子大小,范围在 0-100 直接,表示索引页填满的空间所占的百分比。

1.3.2 创建索引的命名规则最佳实践

在 MSSQL 中,索引的命名规则的最佳实践可以有一些常见的准则,以提高可读性和维护性。这个潜在的要求不仅试用于 SQL Server 数据库,同样在其他数据库例如 MySQL、Oracle 中都同样值得注意。

下面是个人总结的一些命名规则与建议:

  1. 命名应该具有描述性:索引的名称应该能够清晰地表达其作用和关联的列或表。使用有意义的名称可以使其他开发人员更容易理解索引的用途。
  2. 包含表名和列名:在索引名称中包含相关表名和列名(长表名可适当缩写,但要确保可以定位到表),可以使索引更具可读性,并且可以避免在不同表之间使用相同名称的索引时的冲突。
  3. 使用统一的命名约定:为了提高一致性,可以定义一套命名约定,并在整个数据库中使用。例如,可以使用特定的前缀或后缀来标识索引的类型(如 idx_ 表示非聚集索引)。
  4. 避免过长的名称:索引名称不应该过长,以免在使用索引时引起不便。尽量使用简洁但描述性的名称。
  5. 避免使用保留关键字和特殊字符:确保索引名称不与 MSSQL 的保留关键字或特殊字符冲突,以避免语法错误。

1.3.3 创建索引示例

-- 普通索引
if (exists (select * from sys.indexes where name = 'idx_stu_name'))
 drop index student.idx_stu_name
go
create index idx_stu_name
on
student(name);
-- 联合索引
if (exists (select * from sys.indexes where name = 'idx_uqe_clu_stu_name_age'))
 drop index student.idx_uqe_clu_stu_name_age
go
create unique clustered index idx_uqe_clu_stu_name_age
on student(name, age);
if (exists (select * from sys.indexes where name = 'idx_cid'))
 drop index student.idx_cid
go
if (exists (select * from sys.indexes where name = 'idx_cid'))
 drop index student.idx_cid
go
-- 非聚集索引
create nonclustered index idx_cid
on
student (cid)
with fillFactor = 30; --填充因子
-- 聚集索引
if (exists (select * from sys.indexes where name = 'idx_sex'))
 drop index student.idx_sex
go
create clustered index idx_sex
on
student(sex);
-- 聚集索引
if (exists (select * from sys.indexes where name = 'idx_name'))
 drop index student.idx_name
go
create unique index idx_name
on
student(name);

1.4 适合的创建索引的列

一般情况,可以选择那些对查询性能有积极影响的列进行索引创建,下面进行一定的总结:

列的选择性:选择性是指列中不同值的数量与总行数的比例。如果某列具有较高的选择性,即不同的值较多,那么为该列创建索引可能会有更好的效果。例如,在表示性别的列上创建索引可能没有太大的帮助,因为只有两个可能的值。

查询频率:观察经常用于查询条件的列。如果某个列经常用于搜索、过滤或连接操作,那么为该列创建索引可以提高查询性能。

数据表的大小:对于大型表,创建索引的影响可能更加显著。较小的表可能不需要太多的索引,因为全表扫描的开销相对较小。

数据更新频率:索引的创建和维护也会增加对数据的写操作的开销。如果某个列的数据经常发生变化,那么创建索引可能会带来一定的性能开销。

查询性能优化需求:通过分析查询执行计划,可以确定是否存在潜在的性能瓶颈,并考虑为相关的列创建索引以改善查询性能。

请注意过多的索引也可能会带来维护开销和存储成本,因此需要在权衡索引数量和性能提升之间找到平衡点。定期监控和评估索引的使用情况也是重要的,以确保索引仍然对数据库性能产生积极影响。

1.5 不适合创建索引的列

虽然在某些情况下创建索引可以提高查询性能,但并不是所有列都适合创建索引。以下是一些不适合创建索引的列的情况:

低选择性列:如果某个列的选择性很低,即该列的不同值较少,创建索引可能不会带来明显的性能提升。例如,对于性别这样只有几个可能值的列,创建索引可能不会有太大意义。

经常更新的列:如果某个列的值经常被修改,那么为该列创建索引可能会带来额外的维护成本和性能开销。每次更新操作都需要更新索引,这可能会影响写入性能。在这种情况下,需要仔细评估是否真的需要为该列创建索引。

过于频繁的查询列:某些列可能经常被查询,但它们的选择性较低,即不同的值较少。在这种情况下,尽管查询频率高,但为该列创建索引可能不会带来明显的性能提升,因为索引的使用效果有限。

大文本或大二进制列:对于存储大文本或大二进制数据的列,如长文本字段或图像字段,创建索引的效果通常较差。这是因为索引本身需要占用额外的存储空间,并且对于大型数据的索引操作可能变得非常耗时。

不常用的列:对于很少用于查询的列,创建索引可能没有太大意义。如果一个列很少用于查询条件或连接操作,那么为其创建索引可能只会增加额外的开销而不带来实际的性能提升。

需要注意的是,以上列举的情况只是一般性的指导原则,具体是否适合创建索引还取决于具体的数据库结构、查询模式和性能需求。在设计和创建索引时,应根据具体情况进行评估,并进行性能测试和优化以确保索引的有效性。

二、视图

2.1 什么是视图

视图就是一个虚拟的数据表,该数据表中的数据记录是由一条查询语句的查询结果得到的。

2.2 为什么要使用视图,而不是表(面试可能会被问到)

如果你在面试的时候被问到这个问题,建议从下面这个流程来回答一下面试官。

首先介绍一下表的作用(比如表是直接存储结构化数据,可以扩展增删改之类的),之后在介绍一下视图是什么,之后从两个切入点来讲解视图的好处以及必要性,这两个切入点是:复用性和安全性,这里来简单总结一下:

  1. 简化查询,提高复用性
    想象一下,一个人员宽表,里面有几百个字段,但是你每次只需要用到这个表中的姓名、性别、年龄这三个字段,那么你可以创建一个视图来直接使用,或者你这个人员表经常和另外一个履历表 join 组合在一起,而只取了其中的部分字段,并且频繁使用这几个字段。那么无疑创建视图是一个好做法。当然这种情况也可以说明使用视图能够简化查询。
  2. 提高安全性
  • 通过视图,可以限制用户对敏感数据的直接访问。视图可以控制用户可以看到和操作的数据的范围,提供更好的安全性和隐私保护。这里还拿刚才我讲的姓名、性别、年龄三个字段,假如年龄是一个比较敏感的字段,那么对某些数据库用户只能查询姓名和性别的话,那么就可以设置一个视图分配给这个用户。
  • 另外就是如果你要更新视图的时候,也只能更新视图所见的字段,用户对视图不可以随意的更改和删除,可以一定程度的保证数据的安全性。

讲解完上述的两个大的关键点后,也可以适当自行发挥,比如视图你可以调整表字段的显示顺序,或者字段名字等等。这些也是优点。可以适当进行讲解。

2.3 创建视图

创建视图的时候,对命名视图大家一般也有默认的规则,一般情况可以使用 v_ 或 view_ + 表名(表缩写)的形式。

例如:v_student

--创建视图
if (exists (select * from sys.objects where name = 'v_student'))
 drop view v_student
go
create view v_student
as
select id, name, age, sex from student;

2.4 创建视图准则

创建视图需要考虑一下准则:

  1. 视图名称必须遵循标识符的规则,该名称不得与该架构的任何表的名称相同。
  2. 你可以对其他视图创建视图。允许嵌套视图,但嵌套不得超过32层。视图最多可以有1024个字段。
  3. 不能将规则和 default 定义于视图相关联。
  4. 视图的查询不能包含 compute 子句、compute by 子句或 into 关键字。
  5. 定义视图的查询不能包含 order by 子句,除非在 select 语句的选择列表中还有 top 子句。

下列情况必须指定视图中每列的名称:

  • 有列顺序需求(在某些情况下,您可能希望定义视图的结果集中列的顺序,并且这与基础表中的顺序不同。)
  • 视图中的任何列都是从算术表达式、内置函数或常量派生而来
  • 视图中有两列或多列具有相同名称(通常由于视图定义包含联接,因此来自两个或多个不同的列具有相同的名称)
  • 有指定列别名的需求。注意无论是否重命名,视图列都需继承原列的数据类型

2.5 修改视图

修改视图和修改表有点类似,可以直接使用 alter 关键字进行修改,示例如下:

alter view v_student
as
select id, name, sex from student;
alter view v_student(编号, 名称, 性别)
as
 select id, name, sex from student
go
select * from v_student;
select * from information_schema.views;

2.6 加密视图

如果你对某一个视图有保护查询逻辑、防止修改或者查询加密的需求的时候,可以使用加密视图操作。

在 SQL Server 中 使用with encryption后,可以在创建视图时对其定义的 SQL 查询进行加密。也就是说 MSSQL 会对该视图的定义中的查询语句进行加密。这意味着其他人无法直接查看或分析该视图的查询逻辑。压根就看不到这个视图内部结构了。

-- 加密视图
if (exists (select * from sys.objects where name = 'v_student_info'))
 drop view v_student_info
go
create view v_student_info
with encryption --加密
as
 select id, name, age from student
go
--view_definition is null
select * from information_schema.views 
where table_name like 'v_student';

如何解密被加密的视图,或者修改已经被加密的视图:

一般情况一个视图被加密后,你需要修改它,那么大致有3个方法:

  1. 重新创建视图(先删除已加密的视图,然后使用新的查询逻辑重新创建视图。)。
  2. 创建新视图(创建一个新的,视图名称不同,之后调用这个新的)。
  3. 暴力解密之后修改(一般需要借助第三方工具或辅助,该方式个人不推荐)

2.7 视图能否被更新 update (面试可能会被问到)

视图可以被更新吗?什么情况下可以被更新? 

如果面试官问了这两个问题,那么他还算友好的提醒了你,如果直接问了一句话“视图可以被更新吗?”,那么我感觉有被挖坑的嫌疑。

视图可以被更新,但不是所有的情况都可以。

视图更新必须遵循以下规则:

  1. 当视图的字段是通过字段表达式(Field Expression)或常数(Constant)计算得出的结果时,对该视图执行 INSERT 和 UPDATE 操作是不允许的,但可以执行 DELETE 操作。
  2. 若视图的字段是来自库函数,则此视图不允许更新;
  3. 若视图的定义中有 GROUP BY 子句或聚集函数时,则此视图不允许更新;
  4. 若视图的定义中有 DISTINCT 任选项,则此视图不允许更新;
  5. 若视图的定义中有嵌套查询,并且嵌套查询的 FROM 子句中涉及的表也是导出该视图的基表,则此视图不允许更新;
  6. 若视图是由两个以上的基表导出的,此视图不允许更新(源表单一才可以被更新);
  7. 一个不允许更新的视图上定义的视图也不允许更新;
  8. 由一个基表定义的视图,只含有基表的主键或候补键,并且视图中没有用表达式或函数定义的属性,才允许更新。

 

点击关注,第一时间了解华为云新鲜技术~文章来源地址https://www.toymoban.com/news/detail-502438.html

到了这里,关于详解数据库中的索引和视图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 玩转MYSQL数据库之--视图详解

    从今天开始本系列文章就带各位小伙伴学习数据库技术。 数据库技术是Java开发中必不可少的一部分知识内容。也是非常重要的技术。本系列教程由浅入深, 全面讲解数据库体系。 非常适合零基础的小伙伴来学习。 全文大约 【1297】字 ,不说废话,只讲可以让你学到技术、

    2024年02月05日
    浏览(105)
  • MySQL中的表与视图:解密数据库世界的基石

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于PHP专栏:MySQL的100个知识点。 🎉欢迎 👍点赞✍评论⭐收

    2024年02月10日
    浏览(74)
  • 数据库优化:探索 SQL 中的索引

    推荐:使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 在一本书中搜索特定主题时,我们将首先访问索引页面(该页面位于该书的开头),并找到包含我们感兴趣的主题的页码。现在,想象一下在没有索引页的书中找到特定主题是多么不方便。为此,我们必须搜索书中

    2024年02月14日
    浏览(70)
  • 【MySQL数据库】看完还有谁学不会 MySQL 中的视图?

    在MySQL中,视图是一种虚拟表,它是由一个或多个基本表的行或列组成的。视图并不实际存储数据,而是根据定义的查询语句动态生成结果集。视图可以简化复杂的查询操作,提高查询效率,同时也可以保护数据的安全性,隐藏敏感数据。 视图是一种虚拟表,它是由一个或多

    2024年02月10日
    浏览(58)
  • 《向量数据库指南》——Milvus 中的向量索引概览和平面索引

    目录 Milvus 中的向量索引 索引概览 平面索引 在之前的教程中,我们简单介绍了单词 Embedding 示例,了解了 Embedding 的强大,以及如何在向量数据库中进行向量存储和索引。此外,我们也简单介绍了最近邻搜索算法,这个问题涉及根据所选距离度量找到距离查询向量最接近的向

    2024年02月13日
    浏览(53)
  • 4、hive的使用示例详解-事务表、视图、物化视图、DDL(数据库、表以及分区)管理详细操作

    1、apache-hive-3.1.2简介及部署(三种部署方式-内嵌模式、本地模式和远程模式)及验证详解 2、hive相关概念详解–架构、读写文件机制、数据存储 3、hive的使用示例详解-建表、数据类型详解、内部外部表、分区表、分桶表 4、hive的使用示例详解-事务表、视图、物化视图、DDL

    2024年02月09日
    浏览(51)
  • MySQL数据库中的索引(含SQL语句)

    假设有一张表,表中有100万条数据,这100万条数据在硬盘上是存储在数据页上的,一页数据大小为16k。存储100万条数据那么就需要数据页,假设其中有一条数据是“id为7900”的,那么如果要查询这条数据,其中SQL是SELECT * FROM 表名 WHERE id = 7900。在执行这条SQL语句的时候,MyS

    2024年02月02日
    浏览(80)
  • 进阶数据库系列(十二):PostgreSQL 索引技术详解

    前面介绍了 PostgreSQL 数据类型和运算符、常用函数、锁操作、执行计划、视图与触发器、存储过程相关的知识点,今天将为大家介绍 PostgreSQL 索引 相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!! 索引主要被用来提升数据库性能,不当的使

    2024年02月04日
    浏览(87)
  • android 将数据库中的 BLOB 对象动态加载为 XML,并设置到 Android Activity 的内容视图上

    以下是一个示例代码,演示如何将数据库中的 BLOB 对象动态加载为 XML,并设置到 Android Activity 的内容视图上: ```java import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; im

    2024年02月07日
    浏览(39)
  • 一文详解python中的数据库操作

    最近做毕设,需要添加个数据库,记录一下。 重点介绍数据库API接口中的连接对象和游标对象 1. 连接对象 数据库连接对象主要提供获取数据库游标对象和提交/回滚事务的方法,以及关闭数据库连接。 使用connect函数获取对象,该函数有多个参数: host 主机名 database/db 数据库

    2024年02月07日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包