【SqlServer】聚集索引与主键、非聚集索引
目录结构:
聚集索引、非聚集索引在SqlServer、MySQL、Oracle...等数据库中都有这个概念,只不过在SqlServer中叫做聚集索引和非聚集索引而已。下面笔者将会以SqlServer数据库来讲解。
1.聚集索引和非聚集索引的区别
聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物理顺序。
非聚集索引:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚集索引:索引的叶节点就是数据节点。而非聚集索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
看下图
聚集索引:

通过这张图片可以看出,数据库的数据是按照某一顺序排列好的,而叶子节点就是真实的数据节点。
非聚集索引:

通过这张非聚集索引的图片,我们也可以看出,叶子节点也是数据节点,只不过该节点并非真实的数据节点,该节点存储的是真实数据的内存地址。
下面是一张何时使用聚集索引和非聚集索引的表:

通过上面的图,相信对聚集索引和非聚集索引有了一定的概念了。接来下举个实例,假如有一张500万条数据的消息表,id是主键(13位随机数),time是数据的添加日期,现在需要查询2两年内的所有数据,这很显而易见应该给time添加聚集索引,因为查询的条件为 where time 。所以应该给time添加添加聚集索引,如果是这样的情况,笔者建议最好再给表添加一个idate字段,idate存储当前时间的毫秒数,字段的类型不建议为varchar,最好为int,若int装不下可以设置为numeric,因为int的查询效率要比varchar的效率高。
2.聚集索引和主键的区别
笔者在网上看见有人提出,主键就是加了唯一性约束的聚集索引,这句话不全对。
主键的定义:“主键指的是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。”
在SqlServer中,创建主键的列,默认添加一个聚集索引。主键不仅可以关联聚集索引,还可以关联非聚集索引。因此只能说主键和索引有关系。
但是需要明白,主键和索引的作用是不一样的,主键的作用是为了唯一标识表中的某一行,而索引的作用是为了提高查询效率。SqlServer默认给主键列添加聚集索引,这在某些情况下就显得比较浪费,在实际情况中,我们一般都会给ID设置为主键,如果ID是随机产生的,那么这个时候给ID再设置上聚集索引就有点浪费了,原因有二,第一,一般情况不会再按照ID查询区间值数据了,第二,一个表中只能有一个聚集索引,所以聚集索引比较珍贵,要尽可能的发挥聚集索引的最大值。
3.主键和(非)聚集索引的常规操作
-- 排序(聚集索引)
create clustered index inx_entry_stock_bi on entry_stock_d(entry_stock_bi)
-- 创建非聚集索引
create nonclustered index inx_entry_stock on entry_stock_d(entry_stock_bi)
-- 主键
alter table entry_stock_d add primary key nonclustered--主键且非聚集
(
entry_stock_bi,aid
)
-- 删除主键或索引
alter table table_name drop constraint name
【SqlServer】聚集索引与主键、非聚集索引的更多相关文章
- 面试|简单描述MySQL中,索引,主键,唯一索引,联合索引 的区别,对数据库的性能有什么影响(从读写两方面)
索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们 包含着对数据表里所有记录的引用指针. 普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的 ...
- 简单描述 MySQL 中,索引,主键,唯一索引,联合索引 的区别,对数据库的性能有什么影响(从读写两方面) ?
索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们 包含着对数据表里所有记录的引用指针. 普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的 ...
- mysql 主键和唯一索引的区别
主键是一种约束,唯一索引是一种索引,两者在本质上是不同的. 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键. 唯一性索引列允许空值,而主键列不允许为空值. 主键列在创建时,已经默认为非空 ...
- SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...
- SQL存储原理及聚集索引、非聚集索引、唯一索引、主键约束的关系(补)
索引类型 1. 唯一索引:唯一索引不允许两行具有相同的索引值 2. 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型.主键索引要求主键中的 ...
- SQL Server中的联合主键、聚集索引、非聚集索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...
- Are You OK?主键、聚集索引、辅助索引
每张表都一定存在主键吗? 关于这个问题,各位小伙伴们不妨先自己想一想,再往下寻找答案. 首先公布结论:对于 InnoDB 存储引擎来说,每张表都一定有个主键(Primary Key)! 让人非常遗憾的 ...
- SQL Server中的聚集索引(clustered index) 和 非聚集索引 (non-clustered index)
本文转载自 http://blog.csdn.net/ak913/article/details/8026743 面试时经常问到的问题: 1. 什么是聚合索引(clustered index) / ...
- mysql索引之主键索引
MySQL目前主要有以下几种索引类型:1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引 二.语句 CREATE TABLE table_name[col_name data type] [ ...
随机推荐
- Web.config的Release版本和Debug版本不一样的奥秘
VS编译完后,release版本的web.config(或者app.config) 为什么不一样那? 我们查看一下项目结构,会发现有两个版本的config文件存在: 打开web.Debug.con ...
- [Javascript] Check both prop exists and value is valid
Sometime you need to check one prop exists on the object and value should not be ´null´ or ´undefine ...
- IIS发布网站遇到 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary 编
编译错误: 说明:在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息:CS0016: 未能写入输出文件“c:\Windows\Microso ...
- 用一条sql取得第10到第20条的记录-Mssql数据库
因为id可能不是连续的,所以不能用取得10<id<20的记录的方法. 有三种方法可以实现: 一.搜索前20条记录,指定不包括前10条 语句: select top 20 * from tb ...
- html块元素和内联元素
html块元素和内联元素: 对于html各种标签/元素,可以从块的层面做一个分类:要么是block(块元素),要么是inline(内联元素). block元素的特点: 总是另起一行开始: 高度,行高以 ...
- ZH奶酪:基于ionic.io平台的ionic消息推送功能实现
Hybrid App越来越火,Ionic的框架也逐渐被更多的人熟知. 在mobile app中,消息推送是很必要的一个功能. 国内很多ionic应用的推送都是用的极光推送,最近研究了一下Ionic自己 ...
- 使用Chrome保存网页为mht文件
一直在使用chrome浏览器,但由于需要将部分网页保存为mht文件,却发现chrome默认不支持.chrome浏览器默认支持2种:单独的html文件,全部: 万能的chrome怎么可能保存不了mht? ...
- Lanczos Algorithm and it's Parallelization Stragegy
由于写了降维的一个系列算法分析,本来以为对这个Lanczos算法会理解一点,但是还是不知道讲了什么,最多的就是会如何调用,然后出结果,所以就翻译官网的相关内容.本篇翻译来自Dimensional Re ...
- NetCore的控制台应用中搭建WebServer的方法
一.新建NetCore控制台项目,并引入下列Nuget包: Microsoft.AspNetCore.StaticFiles.Microsoft.AspNetCore.Http.Microsoft.A ...
- Go语言中Socket通信之Tcp客户端
1.用法: (1)定义远程IP地址.使用net.ResolveTCPAddr()方法,定义一个TCP地址,做为目标连接地址. (2)调用net.DialTCP("tcp",nil, ...