主键与聚集索引的区别

有些人可能对主键和聚集索引有所混淆,其实这两个是不同的概念,下面是一个简单的描述。不想看绕口文字者,直接看两者的对比表。尤其是最后一项的比较。

主键(PRIMARY KEY )

来自MSDN的描述:

表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。在创建或修改表时,您可以通过定义 PRIMARY KEY 约束来创建主键。

一个表只能有一个 PRIMARY KEY 约束,并且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束可保证数据的唯一性,因此经常对标识列定义这种约束。

如果为表指定了 PRIMARY KEY 约束,则 SQL Server 2005 数据库引擎 将通过为主键列创建唯一索引来强制数据的唯一性。当在查询中使用主键时,此索引还可用来对数据进行快速访问。因此,所选的主键必须遵守创建唯一索引的规则。

创建主键时,数据库引擎 会自动创建唯一的索引来强制实施 PRIMARY KEY 约束的唯一性要求。如果表中不存在聚集索引或未显式指定非聚集索引,则将创建唯一的聚集索引以强制实施 PRIMARY KEY 约束。

 

聚集索引

聚集索引基于数据行的键值在表内排序和存储这些数据行。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。

每个表几乎都对列定义聚集索引来实现下列功能:

  • 可用于经常使用的查询。
  • 提供高度唯一性。

两者的比较

下面是一个简单的比较表

 主键聚集索引
用途强制表的实体完整性对数据行的排序,方便查询用
一个表多少个一个表最多一个主键一个表最多一个聚集索引
是否允许多个字段来定义一个主键可以多个字段来定义一个索引可以多个字段来定义
   
是否允许 null 数据行出现如果要创建的数据列中数据存在null,无法建立主键。
创建表时指定的 PRIMARY KEY 约束列隐式转换为 NOT NULL。
没有限制建立聚集索引的列一定必须 not null .
也就是可以列的数据是 null
参看最后一项比较
是否要求数据必须唯一要求数据必须唯一数据即可以唯一,也可以不唯一。看你定义这个索引的 UNIQUE 设置。
(这一点需要看后面的一个比较,虽然你的数据列可能不唯一,但是系统会替你产生一个你看不到的唯一列)
   
创建的逻辑数据库在创建主键同时,会自动建立一个唯一索引。
如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,则建立主键时候,同时建立一个唯一的聚集索引
如果未使用 UNIQUE 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。
必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。

 

参考:

下面这个帖子中大力的回复:
http://topic.youkuaiyun.com/t/20021212/16/1255429.html

 

关于主键,非聚集索引,聚集索引,看看好吗?!

您好,想请教一下您以下一些问题:聚集索引对范围查询比较有用,只要找到边界值所在的位置便可以确定所查询之目标范围,但是对于单个的查询是起不到多大作用的。  
  我的很多查询是单个产品代号的在线查询,所以最好以先后时间建立聚集索引,产品代号虽然是查询条件,但是这个代号的变化范围很大,经过很多测试后代号顺序很乱,如果用它建聚集所以,如果后提交的代号较小,需要在物理位置上插到已有数据的中间,那么他后面所有数据都要向后移位,每次都挪动很多数据其不是很费资源,还不如建个非聚集索引,毕竟插入动作的频率远远高于查询动作,而以提交时间建聚集索引遵循先来先到的原则,一般不需要挪动数据的,所以这样对于插入很频繁的操作要更好一些。  
  对于每次插入前都要检查唯一性的列是不是一定要建成主键。  
  是不是每张表必须有个聚集索引索引,如果我不指定聚集索引,那么它以什么样的顺序进行物理排列呢?是不是先来先到的原则,早提交的在前面,后提交的在后面,每次插入只是追加,不用去挪动很多数据?  
  那个填充因子从0到100,范围太大,并且我一点都不知道他的意义,不知道是做什么用的,能否给我个经验值?  
  文件组也没有理解,听您的意思,如果我存放数据的逻辑盘是由多个物理硬盘构成的,可以选择文件组来进行并行处理,可以提高性能。我的数据文件是放在多个硬盘组成的磁盘阵列中的,按理因该选文件组,但是好像只有一个primary可供选择,是否选这个就行了?  
   
  是不是所有表一定得有主键,我到底有没有必要为了建立主键而去建一个毫无意义的自增列?  
   
  我对这方面懂得很少,以上是对于几位热心人回复贴的理解,不知道对不对,麻烦您给解答一下,不甚感激,谢谢!  

1 楼jaguarcts(xzh2000)

聚集索引对范围查询比较有用,只要找到边界值所在的位置便可以确定所查询之目标范围,但是对于单个的查询是起不到多大作用的。  
  ----应该也起作用,你可以在查询分析器查执行路径  
   
  对于每次插入前都要检查唯一性的列是不是一定要建成主键。  
  是不是每张表必须有个聚集索引索引,如果我不指定聚集索引,那么它以什么样的顺序进行物理排列呢?是不是先来先到的原则,早提交的在前面,后提交的在后面,每次插入只是追加,不用去挪动很多数据?  
  ----这个问题不一定,主要看你要达到的目的,不过作开发最好是每个表都要有主键,SQL中主键本身就是聚集索引  
   
  那个填充因子从0到100,范围太大,并且我一点都不知道他的意义,不知道是做什么用的,能否给我个经验值?  
  ----如果每个块中数据都充满了,当新的更新使比原来的数据长度大,会使索引破  
  碎,如果数据更新多,填充因子要大一些,反之。。。  
   
  文件组也没有理解,听您的意思,如果我存放数据的逻辑盘是由多个物理硬盘构成的,可以选择文件组来进行并行处理,可以提高性能。我的数据文件是放在多个硬盘组成的磁盘阵列中的,按理因该选文件组,但是好像只有一个primary可供选择,是否选这个就行了?  
  ----文件组是为了更方便管理表所用的,你可以创建很多的文件组,将文件分布在  
  不同的组,可以控制表放在某一个文件组。  
  如create   table   a_test(id   decimal(8,2))   on   [second]  
  表示a_test创建在second文件组中,而second在另一块硬盘上。   
    
    
    
  
2 楼sky_blue(蓝天2007)

"毕竟插入动作的频率远远高于查询动作"   这样用聚集索引的确负作用大。  
  "对于每次插入前都要检查唯一性的列是不是一定要建成主键。"不一定,可以建立唯一性约束  
  "我到底有没有必要为了建立主键而去建一个毫无意义的自增列"  
  个人意见还是建上好

3 楼tj_dns(愉快的登山者)

1。聚集索引对于单个的查询比没有索引要起作用;  
  2。同意建立产品代号非聚集索引;  
  3。最好将每次插入前都要检查唯一性的列建成主键;便于查错;  
  4。不是每张表必须有个聚集索引,如果不指定聚集索引,是先来先到的原则;  
  5。60%,如果建立聚集索引,且总有中间索引插入,此值就要考虑小一些,留出空间来;但值太小,索引的层次就要增加,反过来会影响速度。  
  6。在磁盘阵列中的也可以建立多个文件,但意义不很大;  
  7。不是所有表一定得有主键,要看需要,自增列也是;   
 

4 楼ToUpdate(老六)

UP

5 楼pengdali()

参考:  
  簇集索引=聚集索引:  
  聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。  
   
  聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。  
   
  非簇集索引:  
  非聚集索引与聚集索引一样有   B   树结构,但是有两个重大差别:    
   
  数据行不按非聚集索引键的顺序排序和存储。  
   
   
  非聚集索引的叶层不包含数据页。    
  相反,叶节点包含索引行。每个索引行包含非聚集键值以及一个或多个行定位器,这些行定位器指向有该键值的数据行(如果索引不唯一,则可能是多行)。  
   
  非聚集索引可以在有聚集索引的表、堆集或索引视图上定义。在   Microsoft®   SQL   Server™   2000   中,非聚集索引中的行定位器有两种形式:    
   
  如果表是堆集(没有聚集索引),行定位器就是指向行的指针。该指针用文件标识符   (ID)、页码和页上的行数生成。整个指针称为行   ID。  
   
   
  如果表没有聚集索引,或者索引在索引视图上,则行定位器就是行的聚集索引键。如果聚集索引不是唯一的索引,SQL   Server   2000   将添加在内部生成的值以使重复的键唯一。用户看不到这个值,它用于使非聚集索引内的键唯一。SQL   Server   通过使用聚集索引键搜索聚集索引来检索数据行,而聚集索引键存储在非聚集索引的叶行内。    
  由于非聚集索引将聚集索引键作为其行指针存储,因此使聚集索引键尽可能小很重要。如果表还有非聚集索引,请不要选择大的列作为聚集索引的键。  
   
   
  唯一索引:  
  唯一索引可以确保索引列不包含重复的值。在多列唯一索引的情况下,该索引可以确保索引列中每个值组合都是唯一的。  
  唯一索引既是索引也是约束。  
   
  复合索引:  
  索引项是多个的就叫组合索引,也叫复合索引。  
  复合索引使用时需要注意索引项的次序。

 

原文链接:http://blog.joycode.com/ghj/archive/2008/01/04/113373.aspx

<think>首先,用户的问题是:“我想了解主键索引唯一索引区别请问主键索引唯一索引区别数据库中的作用特性”。这直接要求解释主键索引唯一索引区别,包括它们在数据库中的作用特性。我有几个引用提供的信息:-引用[1]:概述了主键索引唯一索引都确保唯一性,但在定义、用途、性能、自动更新删除、外键关系、命名创建以及可空性方面有区别。-引用[2]:更详细地比较了特性,如性能影响、示例对比、存储结构。主键索引索引,影响存储结构;唯一索引是非索引,允许NULL值。-引用[3]:强调了使用唯一索引时设置默认值以避免NULL问题,并讨论了数量限制、自动增长、聚集索引聚集索引、外键关联使用场景。-引用[4]:提供了主键核心特性(如唯一标识、数量限制)、索引核心解析(如定义、优劣、类型对比、数据结构)、主键索引核心区别。我需要整合这些信息,生成一个清晰、结构化的回答。回答必须使用中文,并遵循系统级指令:-行内数学表达式用$...$格式,但这里可能不涉及数学表达式。-独立公式用$$...$$,但数据库主题可能不需要。-LaTeX语法正确。-生成相关问题。-在引用的段落末尾自然地添加引用标识,如[^1]。回答结构应该清晰,逐步解决问题,保证真实可靠。组织回答:1.**引言**:简要介绍主键索引唯一索引的概念。2.**主要区别**:基于引用,列出关键区别点:-唯一性NULL值:主键索引必须唯一且非空;唯一索引必须唯一但允许NULL值。-数量限制:每个表只能有一个主键索引;可以有多个唯一索引。-索引类型:主键索引通常是索引(影响数据存储);唯一索引是非索引。-自动增长:主键索引AUTO_INCREMENT一起使用;唯一索引不一定。-外键关联:主键索引常用于外键;唯一索引较少用于外键。-性能影响:主键索引可能导致页分裂等;唯一索引影响较小。-使用场景:主键用于行标识;唯一索引用于业务去重。3.**作用作用**:解释它们在数据库中的作用:-主键索引:确保数据完整性,作为行标识,支持外键。-唯一索引:确保列值唯一,允许空值,优化查询。4.**总结**:强调关键差异。5.**相关问题**:生成相关的问题,如关于优化、应用场景等。在回答中,自然地添加引用标识。例如,当提到一个点时,如果源自引用,添加[^n]。生成相关问题:参考示例,快速排序有相关问题。我应该生成关于主键索引唯一索引的相关问题,如:1.如何选择使用主键索引还是唯一索引?2.主键索引索引特性有什么优势?3.唯一索引如何处理NULL值的问题?4.在什么场景下使用唯一索引主键索引更好?确保回答真实可靠,基于引用。最终输出格式:先回答,然后§§相关问题§§部分。</think>### 主键索引唯一索引区别、作用特性 在数据库中,主键索引唯一索引都是用于确保数据唯一性的关键机制,但它们在设计、功能影响上存在显著差异。下面我将逐步解释它们的核心区别、作用相关特性,确保内容清晰可靠。本文基于数据库理论(如MySQL实现)整理而成[^1][^2][^3][^4]。 #### 1. **核心区别** 主键索引唯一索引的主要差异体现在以下几个方面: - **唯一性可空性**: - 主键索引:要求索引列的值**必须唯一且非空**(NULL值不允许)。这确保了每一行数据都有唯一的标识符,例如在用户表中用`user_id`作为主键[^1][^3]。 - 唯一索引:要求索引列的值**必须唯一,但允许NULL值**(一个表可以有多个NULL值,因为NULL不被视为重复)。例如,在邮箱字段上设置唯一索引,允许未填写邮箱的用户存在[^2][^3]。 - **数量限制**: - 主键索引:每个表**只能有一个**主键索引。它是表的“核心标识符”[^1][^4]。 - 唯一索引:每个表**可以有多个**唯一索引,应用于不同列或列组合。例如,一个商品表可以在`product_code``serial_number`上分别创建唯一索引[^2][^4]。 - **索引类型存储结构**: - 主键索引:通常是**索引**(Clustered Index)。这意味着数据行的物理存储顺序主键的逻辑顺序一致(如B+树结构),查询时能直接访问数据,提高效率。但插入或更新操作可能导致页分裂(数据重组),影响性能[^2][^3][^4]。 - 唯一索引:通常是**非索引**(Non-clustered Index)。索引条目存储主键引用而非数据本身,查询时需要二次查找(回表操作),影响速度但占用空间较小,对更新操作的影响也较低[^2][^3][^4]。 - **自动增长外键关联**: - 主键索引:常**自动增长属性**(如`AUTO_INCREMENT`)结合,确保主键值连续递增。它还常用于**外键约束**,作为其他表的引用点,维护数据完整性(例如订单表引用用户表的主键)[^3][^4]。 - 唯一索引:**不支持自动增长**,仅关注值唯一性。它较少用于外键,更多用于业务逻辑的去重需求(如防止重复邮箱注册)[^1][^3]。 - **性能影响**: - 主键索引:作为索引,对**查询性能提升显著**(尤其范围查询),但可能增加插入/更新的开销(如页分裂)。在数据量大时,维护成本较高[^2][^4]。 - 唯一索引:对查询优化有效,但需二次查找;对写操作影响较小,适合高频更新的列[^2][^4]。 #### 2. **在数据库中的作用** - **主键索引的作用**: - **行标识数据完整性**:唯一标识每一行数据,确保没有重复或空值,是数据模型的基石。例如,在关系型数据库中,主键是连接表的外键基础[^3][^4]。 - **查询优化**:作为默认索引,能加速基于主键的检索(如`SELECT * FROM table WHERE id=1`),减少I/O操作[^4]。 - **自动维护**:结合自动增长,简化新数据插入,避免手动管理唯一值[^3]。 - **唯一索引的作用**: - **业务约束**:保证特定列的唯一性(如用户名、手机号),支持业务规则(如“一用户一邮箱”),但不强制非空,灵活性高[^1][^2]。 - **查询辅助**:为非主键列提供快速查找,减少全表扫描。例如,在`email`列上创建唯一索引可优化登录验证查询[^4]。 - **空间效率**:作为非索引,占用额外空间较小,适合多列约束场景[^2]。 #### 3. **关键特性总结** | 特性 | 主键索引 | 唯一索引 | |---------------------|------------------------------|------------------------------| | **唯一性** | 必须唯一且非NULL | 必须唯一但允许NULL | | **数量限制** | 每表仅一个 | 每表可多个 | | **索引类型** | 索引(数据存储有序) | 非索引存储主键引用) | | **自动增长** | 常支持(如AUTO_INCREMENT) | 不支持 | | **外键关联** | 常用作外键引用 | 较少用于外键 | | **NULL值处理** | 禁止NULL | 允许NULL(需注意唯一性问题)[^3] | | **性能影响** | 查询快,但写操作开销大 | 查询需二次查找,写操作影响小 | | **典型使用场景** | 核心行标识(如ID字段) | 业务去重(如唯一邮箱、编码) | 在实际应用中,选择主键索引还是唯一索引取决于业务需求:主键索引强调数据完整性行标识,适合主表;唯一索引更灵活,用于辅助约束[^1][^4]。需注意,唯一索引NULL值可能导致查询歧义(如`WHERE email IS NULL`返回多行),建议设置默认值避免问题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值