--- title: "20-索引" created: 2025-11-25 tags: - 项目筑基 --- # 索引 ## 概念 数据库是要面向应用的 这样才能发挥它的作用 而面向应用软件就自然会涉及人机交互——需要视图(比如登入界面) 索引:对数据库表中一个或多个字段的值进行排序而创建的一种分散存储结构。 数据不可能连续的存储(有后加) 在库内是分散的 而索引就是把这些数据先排一个序 比如字典 里面的汉字按页存放 然后就有一个目录(按拼音 按偏旁……) 对于一本字典来说 查找某个汉字有两种方式 第一种一页一页挨着找 直到找到为止 这叫全字典扫描 效率很低 第二种先通过目录(索引)去定位一个大概的位置 然后直接定位到这个位置做局域性扫描,缩小扫描范围 快速查找 建立索引的目的有以下几点: (1) 加速数据检索 (2) 加速连接、ORDER BY和GROUP BY等操作 (3) 查询优化器依赖于索引起作用(对查询有优化左右 更快) (4) 强制实行的唯一性(比如为什么要身份证 标识ID\IP) Index Pages 目录、索引 sql sever中的数据是按页来存放的(一页4KB) 索引是sql sever中编排数据的内部方法 为sql sever提供一种方法来编排查询数据 索引页:数据库中存储索引的数据页 (类似于字典的目录页)(放的其实是指针) ![[image-c33f8c1c.png]] 根据功能分类 唯一性索引 主键索引 聚集索引 根据组织方式分类 聚集索引(一个表对象只能有一个聚集索引) 非聚集索引(可以有多个) ## 唯一性索引 在表中建立唯一性索引时,组成该索引的字段或字段组合在表中具有唯一值,也就是说,对于表中的任何两行记录来说,索引键的值都是各不相同。 唯一性索引要求组成该索引的字段或字段组合不能在多行记录中具有NULL值。 ## 主键索引 表中通常有一个字段或一些字段的组合,其值用来唯一标识表中的每一行记录,该字段或字段组合称为表的主键。主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空 ## 聚集索引 在聚集索引中,表中各记录的物理顺序与键值的逻辑(索引)顺序相同。只有在表中建立了一个聚集索引后,数据才会按照索引键值指定的顺序存储到表中。由于一个表中的数据只能按照一种顺序来存储,所以在一个表中只能建立一个聚集索引。 ## 非聚集索引 非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个 从创建、查看、删除三个角度分析 ## 创建索引 CREATE 索引类型 INDEX 索引名字 ON 表名(列名) ![[image-c57bd463.png]] ![[image-4309adf8.png]] 成功创建一个唯一性索引 显示非聚集?这是什么意思? 再看一下 我并没有添加另外两个索引 它们是从哪来的? 而且为什么主键就是聚集索引?为什么其他约束就不是 ——回到创建学院表时 ![[image-06d693c2.png]] 在创建学院表的时候 我设定了一个主键约束和一个唯一性约束 而它们自然变成了索引,并存放记录着 可知 索引并不全要后期加上 一开始添加的约束也会成为索引 思考一下为什么主键约束就是聚集索引?所谓聚集索引就是说记录的物理顺序和逻辑顺序要相同 换言之就是设置了主键约束 数据存放时就会有一种特定的顺序去让数据进行存放 实验一下: ![[image-582dace9.png]] ![[image-ea9016ba.png]] ![[image-8036ffb0.png]] 控制变量 创建只有唯一性约束的学院1 只有主键约束的学院2 啥都没有的学院3 ![[image-0f69552a.png]] ![[image-0015392e.png]] ![[image-88333905.png]] 分别插入相同的一组无顺序的数据 ![[image-98bdcdd4.png]] ![[image-1bc6e236.png]] ![[image-30ed2c2a.png]] ![[image-df948b92.png]] 如图 只有设置了主键的学院2 会把数据排序再存储 这是其他约束无法做到的 可知 主键约束是天然的聚集索引 创建唯一性索引 CREATE UNIQUE IDEX ……ON …… 也可以合起来:唯一性的聚集索引 CREATE UNIQUE CLUSTERED INDEX …… ON …… ![[image-926c76ee.png]] 验证聚集索引只能有一个(数据只能按一个顺序排放) ![[image-7b427cea.png]] ![[image-a42b406e.png]] 非聚集索引倒没限制,可以一直加 ![[image-ca821b7b.png]] ![[image-7f2f9f45.png]] 创建聚集索引 CREATE CLUSTERED INDEX …… ON…… 创建主键索引(其实就是创或者加主键约束) ## 查看索引 使用sp\_helpindex ### 复习一下sp sp查看系统存储过程 sp\_databases sp\_tables sp\_renamedb sp\_help sp\_rename sp\_helpindex --更改数据库名字 ALTER DATABASE 管理系统 MODIFY NAME=索引与视图 --或者 EXEC sp\_renamedb '管理系统','索引与视图' --查询表的结构 EXEC sp\_help 学院 --更改表内列名 EXEC sp\_rename'学院.学院电话','电话' SELECT \* FROM 学院 --更改约束名字 EXEC sp\_rename'PK\_\_学院\_\_5A868CA641A780E6','PK\_学院编号' --更改索引名字 --不行 没有相应语法 --但其实改了约束名字 相应的索引名字它自己就会改 ### sp\_helpindex ![[image-16958b43.png]] ## 删除索引 DROP INDEX 索引名ON 表名 对于创表时自动产生的索引 不能使用DROP INDEX语句去删除 它只能在对象资源管理器中使用右键删除 若实在要用T-SQl删 那就删约束 ![[image-e710de42.png]] 我眼中的索引 优点: 加快访问速度 加强行的唯一性 缺点: 带索引的表在数据库中需要更多的存储空间 操纵数据的命令需要更长的处理时间,因为它们需要对索引进行更新 --- ⬅️ [[19-事务与并发|19-事务与并发]] 🏠 [[00-数据库|00-数据库]] ➡️ [[21-视图|21-视图]]