主键、普通索引、唯一索引和全文索引的比较

MySQL索引详解
本文深入解析MySQL中的各种索引类型,包括PRIMARY、INDEX、UNIQUE、FULLTEXT等,阐述它们的区别及适用场景。同时,详细解释了在使用LIKE查询时索引的运用规则,以及如何在实际场景中创建和使用索引。

MYSQL索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录 开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无 需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。


 mysql在使用like查询中,能不能用到索引?在什么地方使用索引呢?

 

1

2

3

在使用like的时候,如果使用‘%%’,会不会用到索引呢?

 

EXPLAIN SELECT * FROM `user` WHERE username LIKE '%ptd_%';

  

上面的结果是全表扫描,并没有使用到索引。


只使用右边一个%的查询:

1

EXPLAIN SELECT * FROM `user` WHERE username LIKE 'ptd_%';

这个使用到了索引。


 

只使用左边一个%的查询:

1

EXPLAIN SELECT * FROM `user` WHERE username LIKE '%ptd_';

  

在左边使用%时也是全表扫描,没有使用到索引。


综上,mysql在使用like查询的时候只有使用后面的%时,才会使用到索引。

 


 

 

总体分析

PRIMARY, INDEX, UNIQUE 这3种是一类

PRIMARY 主键。 就是 唯一 且 不能为空。

INDEX 索引,普通的

UNIQUE 唯一索引。 不允许有重复。

FULLTEXT 是全文索引,用于在一篇文章中,检索文本信息的。

MYSQL的索引类型:PRIMARY, INDEX,UNIQUE,FULLTEXT,SPAIAL 有什么区别?各适用于什么场合?

举个例子来说,比如你在为某商场做一个会员卡的系统。
这个系统有一个会员表
有下列字段:
会员编号 INT
会员姓名 VARCHAR(10)
会员身份证号码 VARCHAR(18)
会员电话 VARCHAR(10)
会员住址 VARCHAR(50)
会员备注信息 TEXT

那么这个 会员编号,作为主键,使用 PRIMARY
会员姓名 如果要建索引的话,那么就是普通的 INDEX
会员身份证号码 如果要建索引的话,那么可以选择 UNIQUE (唯一的,不允许重复)
会员备注信息 , 如果需要建索引的话,可以选择 FULLTEXT,全文搜索。

不过 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。
用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。


创建索引使用说明

普通索引

这是最基本的索引类型,而且它没有唯一性之类的限制。

创建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
创建表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );


唯一性索引

这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。

 

MYSQL主键:

MYSQL主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。

例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。

 

全文索引 (适合在进行模糊查询的时候使用)

MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。

使用方法:(英文示例,中文复杂;后续更新)

1

2

3

4

5

6

7

8

9

语句介绍:WHERE MATCH(COLUMN_NAME) AGAINST('KEY_WORD1,KEY_WORD2' IN BOOLEAN MODE)

索引名称:FULLTEXT

支持类型:char、varchar、text

以下依次是增、删、查全文索引示例:

alter table xxf_witkey_article ADD FULLTEXT username(art_title);

 

DROP INDEX username ON xxf_witkey_article;

 

SELECT * FROM `xxf_witkey_article` WHERE MATCH(art_title) AGAINST('kkkk');

  

单列索引与多列索引

创建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
创建表的时候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) 
);

 

 

 

转载请注明出处 https://www.cnblogs.com/xinruyi 喜欢可以点击关注我

<think>好的,我现在需要帮用户理解不同类型的数据库索引,包括主键索引唯一索引普通索引全文索引的区别与使用场景。用户之前已经问过关于B+Tree的问题,现在可能是在深入学习数据库索引的相关知识。我需要结合用户提供的引用内容来整理这些索引类型的定义、区别以及适用场景。首先,我需要回顾每个引用中的相关信息。引用[1]提到主键索引唯一索引普通索引全文索引的基本定义。引用[2][3]补充了索引的使用技巧组合索引的操作,特别是复合索引的最左原则。引用[4]则区分了主键索引唯一索引,指出主键索引唯一索引的一种,但增加了非空约束。接下来,我需要将这些信息组织成清晰的分类,分别说明每个索引类型的定义、特点、使用场景注意事项。例如,主键索引强调唯一且非空,用于唯一标识记录;唯一索引允许NULL值但要求唯一性,用于避免重复;普通索引用于加速查询,没有唯一性约束;全文索引适用于文本搜索,特别是在大段文字中查找关键词。 同时,要注意用户可能关心它们之间的区别,比如主键唯一索引都保证唯一性,但主键不允许NULL,而唯一索引允许。此外,组合索引的使用需要遵循最左匹配原则,这点在引用[3]中有详细说明,需要强调。 还需要考虑用户的实际应用场景,比如在什么情况下选择哪种索引更有效。例如,主键索引适用于经常作为查询条件的列,而全文索引适合文本内容的搜索。同时,引用[2]中提到的索引使用技巧,如避免在NULL列上建索引,使用短索引等,也应该在注意事项中提及。最后,生成相关问题时要围绕这些索引类型展开,可能包括它们的实现原理、如何优化组合索引、在不同数据库中的支持情况等。确保问题能够帮助用户进一步深化理解。</think>### 数据库索引类型详解 #### 一、主键索引(Primary Key Index) **定义**: 主键索引是唯一标识表中每行记录的索引,具有**唯一性****非空性**双重约束[^4]。每个表只能有一个主键索引,但主键可以由多个字段组成(复合主键)。 **特点**: - 强制要求所有主键字段的值唯一且不为空 - 物理存储顺序通常与主键索引顺序一致(InnoDB 的聚集索引特性) - 自动创建唯一索引来保证唯一性[^4] **使用场景**: - 需要唯一标识记录的列(如用户ID、订单号) - 作为外键关联的基准字段 - 高频单行查询(如 `SELECT * FROM users WHERE id=123`) **示例**: ```sql CREATE TABLE users ( id INT PRIMARY KEY, -- 主键索引 name VARCHAR(50) ); ``` --- #### 二、唯一索引(Unique Index) **定义**: 唯一索引保证索引列或列组合的值唯一,但允许包含 `NULL` 值(不同数据库对 `NULL` 的处理可能不同)[^4]。 **特点**: - 允许多个唯一索引存在于同一张表 - 唯一性约束可作用于单列或多列组合 - 索引字段可为 `NULL`,且多个 `NULL` 值视为不冲突[^2] **使用场景**: - 需要避免重复值的字段(如邮箱、手机号) - 替代主键索引用于非关键唯一标识(如身份证号) - 联合唯一约束(如 `(user_id, course_id)` 防止重复选课) **示例**: ```sql CREATE UNIQUE INDEX idx_email ON users(email); -- 唯一索引 ``` --- #### 三、普通索引(Normal Index) **定义**: 普通索引是最基础的索引类型,仅用于加速查询,无唯一性约束。 **特点**: - 可包含重复值 `NULL` - 支持单列或多列组合(复合索引需遵循**最左前缀原则**)[^3] - 索引结构独立于数据存储(非聚集索引) **使用场景**: - 高频查询但无需唯一约束的字段(如订单状态、创建时间) - 联合查询条件(如 `WHERE age>20 AND city='北京'`) - 排序优化(如 `ORDER BY create_time DESC`)[^1] **示例**: ```sql CREATE INDEX idx_city ON users(city); -- 普通索引 ``` --- #### 四、全文索引(Full-text Index) **定义**: 全文索引专为文本内容搜索设计,支持自然语言查询关键词匹配,适用于大段文本的高效检索[^1]。 **特点**: - 仅适用于 `CHAR`、`VARCHAR`、`TEXT` 等文本类型 - 支持模糊匹配词干分析(如搜索 `run` 可匹配 `running`) - 使用 `MATCH() AGAINST()` 语法进行查询[^1] **使用场景**: - 文章内容搜索(如新闻正文、产品描述) - 日志分析中的关键词检索 - 需要语言特性支持的复杂查询(如近义词匹配) **示例**: ```sql ALTER TABLE articles ADD FULLTEXT INDEX idx_content(content); -- 全文索引 SELECT * FROM articles WHERE MATCH(content) AGAINST('数据库优化'); ``` --- ### 核心区别对比 | 索引类型 | 唯一性 | 允许NULL | 数量限制 | 适用字段类型 | 典型场景 | |------------|--------|----------|----------|--------------------|------------------------| | **主键索引** | 强制 | 禁止 | 1个/表 | 任意 | 唯一标识行记录 | | **唯一索引** | 强制 | 允许 | 多个 | 任意 | 避免重复值(如邮箱) | | **普通索引** | 无 | 允许 | 多个 | 任意 | 加速高频查询条件 | | **全文索引** | 无 | 允许 | 多个 | 文本类型(如TEXT) | 大段文本内容搜索 | --- ### 使用技巧与注意事项 1. **复合索引设计** - 遵循**最左前缀原则**:索引 `(A,B,C)` 可支持 `A`、`A,B`、`A,B,C` 的查询,但不支持 `B,C`[^3] - 将高频查询字段放在左侧:`CREATE INDEX idx_age_city ON users(age, city)` 2. **索引长度优化** - 对长字符串使用前缀索引:`CREATE INDEX idx_name ON users(name(10))`[^2] - 避免对 `TEXT`/`BLOB` 等大字段建普通索引全文索引除外)[^2] 3. **查询性能影响** - 索引可能降低写入速度(需维护索引结构) - 避免在索引列上使用函数或运算:`WHERE YEAR(create_time)=2023` 无法使用索引[^2] 4. **NULL 值处理** - 包含 `NULL` 的列可能无法被索引覆盖[^2] - 主键索引字段必须定义为 `NOT NULL`[^4] --- ### 数学分析:索引效率估算 对于 $n$ 条记录的表,全表扫描时间复杂度为 $O(n)$,而使用 B+Tree 索引的查询时间复杂度为 $O(\log_m n)$($m$ 为 B+Tree 阶数)。当 $m=500$ 时,查询 $10^6$ 条数据仅需: $$ \log_{500} 10^6 \approx 3 $$ 次磁盘 I/O,性能提升显著[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值