主键,唯一索引 聚集索引的关系

本文深入探讨了数据库索引的设计原则及其对查询性能的影响。详细解释了聚集索引与非聚集索引的区别,并讨论了主键与唯一索引的关系。此外,还提供了关于如何选择合适的索引类型和列的实用建议。

     为列创建索引实际上就是为列进行排序,以方便查询.建立一个列的索引,就相当与建立一个列的排序。

    主键是唯一的,所以创建了一个主键的同时,也就这个字段创建了一个唯一的索引,

    唯一索引实际上就是要求指定的列中所有的数据必须不同。

    主键一唯一索引的区别:

         1 一个表的主键只能有一个,而唯一索引可以建多个。
         2 主键可以作为其它表的外键。
         3 主键不可为null,唯一索引可以为null。

聚集索引:将表内的数据按照一定的规则进行排列的目录。正因为如此,一个表中的聚焦索引只有一个。对此我们要注意“主键就是聚焦索引”这是极端错误的,是对聚焦索引的一种浪费。(虽然SQLServer默认主键就是聚焦索引)使用聚焦索引的最大好处就是按照查询要求,迅速缩小查询范围,避免进行全表扫描。其次让每个数目都不相同的字段作为聚焦索引也不符合“大数目不同情况下不应建立聚集索引的原则”。

一、索引的作用

1、帮助检索数据;

2、提高联接效率;

3、节省ORDER BY、GROUP BY的时间;

4、保证数据唯一性(仅限于唯一索引)。

 

二、索引的设计

在确定要建立一个索引时,首先我们要确定它是聚集还是非聚集、单列还是多列、唯一还是非唯一、列是升序还是降序、它的存储是如何的,比如:分区、填充因子等。下面逐条来看:

1、聚集索引

(1)首先指出一个误区,主键并不一定是聚集索引,只是在SQL SERVER中,未明确指出的情况下,默认将主键定义为聚集,而ORACLE中则默认是非聚集,因为SQL SERVER中的ROWID未开放使用。

(2)聚集索引适合用于需要进行范围查找的列,因为聚集索引的叶子节点存放的是有序的数据行,查询引擎可根据WHERE中给出的范围,直接定位到两端的叶子节点,将这部分节点页的数据根据链表顺序取出即可;

(3)聚集索引尽量建立在值不会发生变更的列上,否则会带来非聚集索引的维护;

(4)尽量在建立非聚集索引之前建立聚集索引,否则会导致表上所有非聚集索引的重建;

(5)聚集索引应该避免建立在数值单调的列上,否则可能会造成IO的竞争,以及B树的不平衡,从而导致数据库系统频繁的维护B树的平衡性。聚集索引的列值最好能够在表中均匀分布。

3、唯一索引

(1)再指出一个误区,聚集索引并不一定是唯一索引,由于SQL SERVER将主键默认定义为聚集索引,事实上,索引是否唯一与是否聚集是不相关的,聚集索引可以是唯一索引,也可以是非唯一索引;

(2)将索引设置为唯一,对于等值查找是很有利的,当查到第一条符合条件的纪录时即可停止查找,返回数据,而非唯一索引则要继续查找,同样,由于需要保证唯一性,每一行数据的插入都会去检查重复性;

 

更详细的信息参见漫漫技术人生路的博客http://www.cnblogs.com/javaca88/.

 

# 主键索引唯一索引与复合索引详解 ## 1. 主键索引 (PRIMARY KEY) ### 基本特性 - **唯一性**:确保每行的主键值唯一 - **非空约束**:主键列不允许NULL值 - **聚集索引**:在InnoDB中,主键默认是聚集索引(决定数据物理存储顺序) - **表只能有一个主键**:但可以是单列或多列组合(复合主键) ### 使用场景 ```sql -- 创建单列主键 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL ); -- 创建复合主键 CREATE TABLE order_items ( order_id INT, product_id INT, quantity INT, PRIMARY KEY (order_id, product_id) -- 复合主键 ); ``` ### 特点与注意事项 - 主键通常作为其他表的外键引用 - 自增主键(AUTO_INCREMENT)有利于插入性能,但可能不适合分布式系统 - UUID作为主键可能影响索引性能(因随机性导致页分裂) ## 2. 唯一索引 (UNIQUE INDEX) ### 基本特性 - **唯一性**:确保索引列值唯一(允许NULL值,但多个NULL是否被视为相同取决于数据库实现) - **非聚集索引**:不影响数据物理存储顺序 - **表可以有多个唯一索引** ### 使用场景 ```sql -- 创建单列唯一索引 CREATE TABLE employees ( id INT PRIMARY KEY, email VARCHAR(100) UNIQUE, -- 列级约束 phone VARCHAR(20) ); -- 显式创建唯一索引 CREATE UNIQUE INDEX idx_emp_phone ON employees(phone); -- 复合唯一索引 CREATE TABLE room_allocations ( room_id INT, date DATE, user_id INT, UNIQUE (room_id, date) -- 同一房间同一天只能分配一次 ); ``` ### 特点与注意事项 - 与主键不同,唯一索引允许NULL值(在MySQL中,NULL被视为特殊值,不违反唯一性) - 常用于业务唯一约束(如用户名、邮箱、手机号等) - 性能与普通索引相当,但插入/更新时需要额外唯一性检查 ## 3. 复合索引 (Composite Index) ### 基本特性 - **多列组合**:索引包含多个列(最多16列,具体取决于DBMS) - **最左前缀原则**:查询条件必须包含索引最左边的列才能使用索引 - **排序优化**:可以优化多列排序(ORDER BY) ### 使用场景 ```sql -- 创建复合索引 CREATE TABLE sales ( id INT PRIMARY KEY, region VARCHAR(50), sale_date DATE, amount DECIMAL(10,2), INDEX idx_region_date (region, sale_date) -- 复合索引 ); -- 有效使用索引的查询 SELECT * FROM sales WHERE region = 'East' AND sale_date > '2023-01-01'; -- 使用索引 SELECT * FROM sales WHERE region = 'West'; -- 使用索引(最左列) SELECT * FROM sales WHERE sale_date = '2023-05-01'; -- 不使用索引(违反最左前缀) ``` ### 设计原则 1. **列顺序**:高选择性(区分度高)的列放前面 2. **覆盖索引**:包含查询所需的所有列,避免回表 3. **查询模式**:根据实际查询条件设计索引顺序 4. **列大小**:较小的数据类型放前面(减少索引大小) ## 比较与选择策略 | 特性 | 主键索引 | 唯一索引 | 复合索引 | |------------|------------------|------------------|------------------| | **唯一性** | 强制唯一 | 强制唯一 | 不强制唯一 | | **NULL值** | 不允许 | 允许(视DBMS而定) | 允许 | | **数量** | 每表1个 | 每表多个 | 每表多个 | | **主要用途** | 行唯一标识 | 业务唯一约束 | 优化多条件查询 |
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值