@llryiop/avatar-boot-cli 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/docs/exam-question-generate-api.md +163 -0
  2. package/package.json +1 -1
  3. package/src/prompts.js +3 -3
  4. package/src/transform.js +1 -1
  5. package/templates/.claude/skills/avatar-boot-starter-feign/README.md +243 -0
  6. package/templates/.claude/skills/avatar-boot-starter-feign/SKILL.md +47 -219
  7. package/templates/.claude/skills/avatar-boot-starter-feign/references//345/212/237/350/203/275/350/257/246/350/247/243.md +65 -0
  8. package/templates/.claude/skills/avatar-boot-starter-feign/references//345/277/253/351/200/237/346/216/245/345/205/245/346/214/207/345/215/227.md +75 -0
  9. package/templates/.claude/skills/avatar-boot-starter-feign/references//351/205/215/347/275/256/345/217/202/350/200/203.md +70 -0
  10. package/templates/.claude/skills/avatar-boot-starter-job/README.md +437 -0
  11. package/templates/.claude/skills/avatar-boot-starter-job/SKILL.md +35 -414
  12. package/templates/.claude/skills/avatar-boot-starter-job/references//345/270/270/350/247/201/351/227/256/351/242/230.md +55 -0
  13. package/templates/.claude/skills/avatar-boot-starter-job/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +124 -0
  14. package/templates/.claude/skills/avatar-boot-starter-job/references//347/233/221/346/216/247/346/214/207/346/240/207.md +72 -0
  15. package/templates/.claude/skills/avatar-boot-starter-kafka/README.md +580 -0
  16. package/templates/.claude/skills/avatar-boot-starter-kafka/SKILL.md +36 -560
  17. package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/234/200/344/275/263/345/256/236/350/267/265.md +43 -0
  18. package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/240/270/345/277/203/345/212/237/350/203/275.md +117 -0
  19. package/templates/.claude/skills/avatar-boot-starter-kafka/references//351/205/215/347/275/256/345/217/202/350/200/203.md +54 -0
  20. package/templates/.claude/skills/avatar-boot-starter-mysql/README.md +572 -0
  21. package/templates/.claude/skills/avatar-boot-starter-mysql/SKILL.md +40 -550
  22. package/templates/.claude/skills/avatar-boot-starter-mysql/references//345/256/236/344/275/223/344/270/216/345/212/237/350/203/275.md +96 -0
  23. package/templates/.claude/skills/avatar-boot-starter-mysql/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/346/225/260/346/215/256/346/272/220.md +91 -0
  24. package/templates/.claude/skills/avatar-boot-starter-mysql/references//351/253/230/347/272/247/347/211/271/346/200/247/344/270/216/351/205/215/347/275/256.md +59 -0
  25. package/templates/.claude/skills/avatar-boot-starter-nacos/README.md +901 -0
  26. package/templates/.claude/skills/avatar-boot-starter-nacos/SKILL.md +40 -879
  27. package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/212/237/350/203/275/344/275/277/347/224/250.md +134 -0
  28. package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +96 -0
  29. package/templates/.claude/skills/avatar-boot-starter-nacos/references//346/225/205/351/232/234/346/216/222/346/237/245.md +64 -0
  30. package/templates/.claude/skills/avatar-boot-starter-oss/README.md +594 -0
  31. package/templates/.claude/skills/avatar-boot-starter-oss/SKILL.md +52 -570
  32. package/templates/.claude/skills/avatar-boot-starter-oss/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +77 -0
  33. package/templates/.claude/skills/avatar-boot-starter-oss/references//346/240/270/345/277/203/345/212/237/350/203/275.md +94 -0
  34. package/templates/.claude/skills/avatar-boot-starter-oss/references//350/247/204/350/214/203/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.md +61 -0
  35. package/templates/.claude/skills/avatar-boot-starter-redis/README.md +586 -0
  36. package/templates/.claude/skills/avatar-boot-starter-redis/SKILL.md +42 -566
  37. package/templates/.claude/skills/avatar-boot-starter-redis/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +78 -0
  38. package/templates/.claude/skills/avatar-boot-starter-redis/references//346/225/260/346/215/256/346/223/215/344/275/234.md +111 -0
  39. package/templates/.claude/skills/avatar-boot-starter-redis/references//351/253/230/347/272/247/345/212/237/350/203/275.md +90 -0
  40. package/templates/.claude/skills/avatar-boot-starter-rocketmq/README.md +662 -0
  41. package/templates/.claude/skills/avatar-boot-starter-rocketmq/SKILL.md +48 -640
  42. package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//346/240/270/345/277/203/345/212/237/350/203/275.md +101 -0
  43. package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/205/215/347/275/256/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.md +44 -0
  44. package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/253/230/347/272/247/347/211/271/346/200/247.md +71 -0
  45. package/templates/.claude/skills/avatar-boot-starter-web/README.md +1007 -0
  46. package/templates/.claude/skills/avatar-boot-starter-web/SKILL.md +150 -1003
  47. package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-LogInfo/346/263/250/350/247/243.md +75 -0
  48. package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/345/205/250/345/261/200/345/274/202/345/270/270/345/244/204/347/220/206.md +90 -0
  49. package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/346/214/207/346/240/207/347/233/221/346/216/247.md +74 -0
  50. package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/346/227/245/345/277/227/344/275/223/347/263/273.md +73 -0
  51. package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/350/257/267/346/261/202/344/270/212/344/270/213/346/226/207.md +77 -0
  52. package/templates/.claude/skills/avatar-boot-starter-web/references//345/277/253/351/200/237/346/216/245/345/205/245/346/214/207/345/215/227.md +52 -0
  53. package/templates/.claude/skills/avatar-boot-starter-web/references//346/263/250/346/204/217/344/272/213/351/241/271.md +68 -0
  54. package/templates/.claude/skills/avatar-boot-starter-web/references//350/207/252/345/256/232/344/271/211/346/211/251/345/261/225/346/214/207/345/215/227.md +107 -0
  55. package/templates/.claude/skills/avatar-boot-starter-web/references//351/205/215/347/275/256/345/217/202/350/200/203.md +107 -0
  56. package/templates/.claude/skills/crud-generator/SKILL.md +133 -64
  57. package/templates/.claude/skills/database-design/README.md +207 -0
  58. package/templates/.claude/skills/database-design/SKILL.md +469 -82
  59. package/templates/.claude/skills/database-design/references//345/221/275/345/220/215/350/247/204/350/214/203.md +232 -0
  60. package/templates/.claude/skills/database-design/references//345/255/227/346/256/265/347/261/273/345/236/213/350/247/204/350/214/203.md +400 -0
  61. package/templates/.claude/skills/database-design/references//347/264/242/345/274/225/350/247/204/350/214/203.md +506 -0
  62. package/templates/README.md +65 -100
  63. package/templates/avatar-scaffold-api/pom.xml +0 -5
  64. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/api/LoginFeignClient.java +2 -0
  65. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/exception/LoginErrorCode.java +25 -0
  66. package/templates/avatar-scaffold-service/pom.xml +25 -87
  67. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/feign/DemoFeign.java +4 -1
  68. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/UserLoginRepository.java +10 -0
  69. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/mapper/UserLoginMapper.java +4 -1
  70. package/templates/avatar-scaffold-service/src/main/resources/application-dev.yaml +3 -5
  71. package/templates/avatar-scaffold-service/src/main/resources/application-local.yaml +21 -21
  72. package/templates/pom.xml +9 -18
@@ -0,0 +1,506 @@
1
+ # MySQL 索引规范
2
+
3
+ ## 一、索引设计原则
4
+
5
+ ### 1. 最左前缀原则
6
+
7
+ 联合索引按 `等值查询列 → 范围查询列 → 排序列` 顺序排列
8
+
9
+ ```sql
10
+ -- ✅ 正确:等值查询在前,范围查询在后
11
+ KEY `idx_order_status_created` (`status`, `created_at`)
12
+
13
+ -- 查询可以使用索引
14
+ WHERE status = 1 AND created_at > '2026-01-01'
15
+
16
+ -- ❌ 错误:范围查询在前
17
+ KEY `idx_order_created_status` (`created_at`, `status`)
18
+
19
+ -- 查询只能使用 created_at,status 无法使用索引
20
+ WHERE status = 1 AND created_at > '2026-01-01'
21
+ ```
22
+
23
+ ### 2. 覆盖索引优先
24
+
25
+ 高频查询尽量通过覆盖索引避免回表
26
+
27
+ ```sql
28
+ -- 查询:SELECT id, role_code, role_name FROM role WHERE role_code = 'ADMIN'
29
+
30
+ -- ✅ 覆盖索引(包含查询所需的所有字段)
31
+ KEY `idx_role_code_name` (`role_code`, `role_name`)
32
+
33
+ -- ❌ 普通索引(需要回表查询 role_name)
34
+ KEY `idx_role_code` (`role_code`)
35
+ ```
36
+
37
+ ### 3. 区分度优先
38
+
39
+ 优先对区分度高的列建索引
40
+
41
+ **区分度计算**:`区分度 = 不重复值数 / 总行数`
42
+
43
+ ```sql
44
+ -- 检查字段区分度
45
+ SELECT
46
+ COUNT(DISTINCT role_code) / COUNT(*) AS code_selectivity,
47
+ COUNT(DISTINCT is_enabled) / COUNT(*) AS enabled_selectivity
48
+ FROM zz_plt_role;
49
+
50
+ -- 结果示例:
51
+ -- code_selectivity: 0.95 (高区分度,适合建索引)
52
+ -- enabled_selectivity: 0.02 (低区分度,不适合建索引)
53
+ ```
54
+
55
+ ### 4. 控制数量
56
+
57
+ - 单表索引不超过 **5 个**
58
+ - 联合索引字段不超过 **3 个**
59
+
60
+ ---
61
+
62
+ ## 二、必须建索引的场景
63
+
64
+ ### 1. 主键(自动创建)
65
+
66
+ ```sql
67
+ PRIMARY KEY (`id`)
68
+ ```
69
+
70
+ ### 2. 唯一约束字段
71
+
72
+ ```sql
73
+ -- 编码字段
74
+ UNIQUE KEY `uk_zz_plt_role_code` (`role_code`)
75
+
76
+ -- 邮箱字段
77
+ UNIQUE KEY `uk_zz_plt_user_email` (`email`)
78
+ ```
79
+
80
+ ### 3. 频繁出现在 WHERE 中的字段
81
+
82
+ ```sql
83
+ -- 状态字段
84
+ KEY `idx_zz_plt_order_status` (`status`)
85
+
86
+ -- 类型字段
87
+ KEY `idx_zz_plt_avatar_type` (`avatar_type`)
88
+ ```
89
+
90
+ ### 4. 频繁出现在 JOIN ON 中的字段
91
+
92
+ ```sql
93
+ -- 外键字段
94
+ KEY `idx_zz_plt_order_user_id` (`user_id`)
95
+ KEY `idx_zz_plt_order_product_id` (`product_id`)
96
+ ```
97
+
98
+ ### 5. 频繁出现在 ORDER BY 中的字段
99
+
100
+ ```sql
101
+ -- 排序字段
102
+ KEY `idx_zz_plt_role_sort_order` (`sort_order`)
103
+
104
+ -- 创建时间(常用于排序)
105
+ KEY `idx_zz_plt_article_created` (`created_at`)
106
+ ```
107
+
108
+ ---
109
+
110
+ ## 三、禁止建索引的场景
111
+
112
+ ### 1. 区分度极低的字段
113
+
114
+ ```sql
115
+ -- ❌ 错误:is_deleted 只有 0 和 1 两个值
116
+ KEY `idx_zz_plt_role_deleted` (`is_deleted`)
117
+
118
+ -- ❌ 错误:gender 只有几个值
119
+ KEY `idx_zz_plt_user_gender` (`gender`)
120
+
121
+ -- ✅ 正确:可以作为联合索引的一部分
122
+ KEY `idx_zz_plt_role_status` (`status`, `is_deleted`)
123
+ ```
124
+
125
+ ### 2. 频繁更新的字段
126
+
127
+ ```sql
128
+ -- ❌ 错误:访问次数频繁更新,写放大严重
129
+ KEY `idx_zz_plt_article_view_count` (`view_count`)
130
+
131
+ -- ✅ 正确:如果必须查询,考虑使用其他方案(如缓存)
132
+ ```
133
+
134
+ ### 3. 超长字符串字段
135
+
136
+ ```sql
137
+ -- ❌ 错误:全文索引在长文本上效率低
138
+ KEY `idx_zz_plt_article_content` (`content`)
139
+
140
+ -- ✅ 正确:使用前缀索引或全文索引
141
+ KEY `idx_zz_plt_article_title` (`title`(50)) -- 前缀索引
142
+ FULLTEXT KEY `ft_zz_plt_article_content` (`content`) -- 全文索引
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 四、索引命名规范
148
+
149
+ | 类型 | 格式 | 示例 |
150
+ |------|------|------|
151
+ | 主键 | `pk_{表名}` | `pk_zz_plt_role` |
152
+ | 唯一索引 | `uk_{表名}_{字段}` | `uk_zz_plt_role_code` |
153
+ | 普通索引 | `idx_{表名}_{字段}` | `idx_zz_plt_role_name` |
154
+ | 联合索引 | `idx_{表名}_{字段1}_{字段2}` | `idx_zz_plt_role_status_enabled` |
155
+ | 全文索引 | `ft_{表名}_{字段}` | `ft_zz_plt_article_title` |
156
+
157
+ ### 注意事项
158
+
159
+ - 主键索引由 MySQL 自动创建,无需在 CREATE TABLE 中显式声明
160
+ - 索引名称要简洁明了,能清晰表达索引的用途
161
+ - 联合索引名称按字段顺序命名
162
+
163
+ ---
164
+
165
+ ## 五、常用索引模板
166
+
167
+ ### 1. 唯一索引(编码字段)
168
+
169
+ ```sql
170
+ UNIQUE KEY `uk_{表名}_code` (`{entity}_code`)
171
+
172
+ -- 示例
173
+ UNIQUE KEY `uk_zz_plt_role_code` (`role_code`)
174
+ ```
175
+
176
+ ### 2. 普通索引(名称字段)
177
+
178
+ ```sql
179
+ KEY `idx_{表名}_name` (`{entity}_name`)
180
+
181
+ -- 示例
182
+ KEY `idx_zz_plt_role_name` (`role_name`)
183
+ ```
184
+
185
+ ### 3. 联合索引(租户+删除标记)
186
+
187
+ ```sql
188
+ KEY `idx_{表名}_tenant` (`tenant_id`, `is_deleted`)
189
+
190
+ -- 示例
191
+ KEY `idx_zz_plt_role_tenant` (`tenant_id`, `is_deleted`)
192
+ ```
193
+
194
+ ### 4. 联合索引(状态+启用+删除)
195
+
196
+ ```sql
197
+ KEY `idx_{表名}_status` (`status`, `is_enabled`, `is_deleted`)
198
+
199
+ -- 示例
200
+ KEY `idx_zz_plt_order_status` (`status`, `is_enabled`, `is_deleted`)
201
+ ```
202
+
203
+ ### 5. 联合索引(类型+启用+删除)
204
+
205
+ ```sql
206
+ KEY `idx_{表名}_type` (`type`, `is_enabled`, `is_deleted`)
207
+
208
+ -- 示例
209
+ KEY `idx_zz_plt_avatar_type` (`avatar_type`, `is_enabled`, `is_deleted`)
210
+ ```
211
+
212
+ ### 6. 外键索引
213
+
214
+ ```sql
215
+ KEY `idx_{表名}_{外键字段}` (`{entity}_id`)
216
+
217
+ -- 示例
218
+ KEY `idx_zz_plt_order_user_id` (`user_id`)
219
+ KEY `idx_zz_plt_order_product_id` (`product_id`)
220
+ ```
221
+
222
+ ### 7. 时间索引
223
+
224
+ ```sql
225
+ KEY `idx_{表名}_created` (`created_at`)
226
+
227
+ -- 示例
228
+ KEY `idx_zz_plt_article_created` (`created_at`)
229
+ ```
230
+
231
+ ---
232
+
233
+ ## 六、联合索引设计
234
+
235
+ ### 最左前缀原则
236
+
237
+ 联合索引 `(a, b, c)` 可以支持以下查询:
238
+
239
+ ```sql
240
+ -- ✅ 可以使用索引
241
+ WHERE a = 1
242
+ WHERE a = 1 AND b = 2
243
+ WHERE a = 1 AND b = 2 AND c = 3
244
+ WHERE a = 1 AND c = 3 -- 只能使用 a
245
+
246
+ -- ❌ 无法使用索引
247
+ WHERE b = 2
248
+ WHERE c = 3
249
+ WHERE b = 2 AND c = 3
250
+ ```
251
+
252
+ ### 字段顺序选择
253
+
254
+ 1. **等值查询字段在前**
255
+ 2. **范围查询字段在后**
256
+ 3. **排序字段最后**
257
+
258
+ ```sql
259
+ -- ✅ 正确顺序
260
+ KEY `idx_order_status_created` (`status`, `created_at`)
261
+
262
+ -- 查询:WHERE status = 1 AND created_at > '2026-01-01' ORDER BY created_at
263
+ -- 可以完全使用索引
264
+
265
+ -- ❌ 错误顺序
266
+ KEY `idx_order_created_status` (`created_at`, `status`)
267
+
268
+ -- 查询:WHERE status = 1 AND created_at > '2026-01-01'
269
+ -- 只能使用 created_at,status 无法使用索引
270
+ ```
271
+
272
+ ### 覆盖索引设计
273
+
274
+ ```sql
275
+ -- 查询:SELECT id, user_id, status, amount FROM orders WHERE user_id = 1 AND status = 1
276
+
277
+ -- ✅ 覆盖索引(包含所有查询字段)
278
+ KEY `idx_order_user_status_amount` (`user_id`, `status`, `amount`)
279
+
280
+ -- 无需回表,直接从索引获取所有数据
281
+ ```
282
+
283
+ ---
284
+
285
+ ## 七、关联表索引设计
286
+
287
+ 关联表(中间表)必须包含:
288
+
289
+ 1. **联合唯一索引**(防止重复关联)
290
+ 2. **外键字段的普通索引**(提升查询性能)
291
+
292
+ ```sql
293
+ CREATE TABLE `zz_plt_avatar_role_rel` (
294
+ `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
295
+ `avatar_id` BIGINT UNSIGNED NOT NULL COMMENT '虚拟人ID',
296
+ `role_id` BIGINT UNSIGNED NOT NULL COMMENT '角色ID',
297
+ `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
298
+ `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-未删除,1-已删除',
299
+ PRIMARY KEY (`id`),
300
+ -- 联合唯一索引(防止重复关联)
301
+ UNIQUE KEY `uk_zz_plt_avatar_role_rel` (`avatar_id`, `role_id`),
302
+ -- 外键索引(提升反向查询性能)
303
+ KEY `idx_zz_plt_avatar_role_rel_role` (`role_id`)
304
+ ) ENGINE=InnoDB;
305
+ ```
306
+
307
+ ### 为什么需要两个索引?
308
+
309
+ ```sql
310
+ -- 查询 1:根据 avatar_id 查询关联的 role_id
311
+ SELECT role_id FROM zz_plt_avatar_role_rel WHERE avatar_id = 1;
312
+ -- 使用联合唯一索引 uk_zz_plt_avatar_role_rel
313
+
314
+ -- 查询 2:根据 role_id 查询关联的 avatar_id
315
+ SELECT avatar_id FROM zz_plt_avatar_role_rel WHERE role_id = 1;
316
+ -- 使用普通索引 idx_zz_plt_avatar_role_rel_role
317
+ ```
318
+
319
+ ---
320
+
321
+ ## 八、索引使用检查
322
+
323
+ ### 1. 查看索引使用情况
324
+
325
+ ```sql
326
+ -- 查看执行计划
327
+ EXPLAIN SELECT * FROM zz_plt_role WHERE role_code = 'ADMIN';
328
+
329
+ -- 关键字段:
330
+ -- type: 索引类型(const > eq_ref > ref > range > index > ALL)
331
+ -- key: 实际使用的索引
332
+ -- rows: 扫描的行数
333
+ ```
334
+
335
+ ### 2. 检查未使用的索引
336
+
337
+ ```sql
338
+ -- 检查未使用的索引(定期执行)
339
+ SELECT
340
+ object_schema AS `database`,
341
+ object_name AS `table`,
342
+ index_name AS `index`,
343
+ count_read AS `read_count`
344
+ FROM performance_schema.table_io_waits_summary_by_index_usage
345
+ WHERE index_name IS NOT NULL
346
+ AND count_read = 0
347
+ AND object_schema = 'your_database'
348
+ ORDER BY object_schema, object_name;
349
+ ```
350
+
351
+ ### 3. 检查重复索引
352
+
353
+ ```sql
354
+ -- 检查重复索引
355
+ SELECT
356
+ a.table_schema,
357
+ a.table_name,
358
+ a.index_name AS index1,
359
+ b.index_name AS index2,
360
+ a.column_name
361
+ FROM information_schema.statistics a
362
+ JOIN information_schema.statistics b
363
+ ON a.table_schema = b.table_schema
364
+ AND a.table_name = b.table_name
365
+ AND a.column_name = b.column_name
366
+ AND a.seq_in_index = b.seq_in_index
367
+ AND a.index_name != b.index_name
368
+ WHERE a.table_schema = 'your_database'
369
+ ORDER BY a.table_name, a.index_name;
370
+ ```
371
+
372
+ ---
373
+
374
+ ## 九、索引优化建议
375
+
376
+ ### 1. 避免索引失效
377
+
378
+ ```sql
379
+ -- ❌ 在索引列上使用函数
380
+ WHERE DATE(created_at) = '2026-03-19'
381
+
382
+ -- ✅ 改写查询
383
+ WHERE created_at >= '2026-03-19 00:00:00' AND created_at < '2026-03-20 00:00:00'
384
+
385
+ -- ❌ 隐式类型转换
386
+ WHERE user_id = '12345' -- user_id 是 BIGINT
387
+
388
+ -- ✅ 使用正确类型
389
+ WHERE user_id = 12345
390
+
391
+ -- ❌ 前缀模糊查询
392
+ WHERE role_name LIKE '%管理%'
393
+
394
+ -- ✅ 使用全文索引或 Elasticsearch
395
+ FULLTEXT KEY `ft_role_name` (`role_name`)
396
+ ```
397
+
398
+ ### 2. 合理使用前缀索引
399
+
400
+ ```sql
401
+ -- 长字符串字段使用前缀索引
402
+ KEY `idx_article_title` (`title`(50))
403
+
404
+ -- 检查前缀长度的区分度
405
+ SELECT
406
+ COUNT(DISTINCT LEFT(title, 10)) / COUNT(*) AS len_10,
407
+ COUNT(DISTINCT LEFT(title, 20)) / COUNT(*) AS len_20,
408
+ COUNT(DISTINCT LEFT(title, 50)) / COUNT(*) AS len_50,
409
+ COUNT(DISTINCT title) / COUNT(*) AS full_len
410
+ FROM zz_plt_article;
411
+ ```
412
+
413
+ ### 3. 定期维护索引
414
+
415
+ ```sql
416
+ -- 分析表(更新索引统计信息)
417
+ ANALYZE TABLE zz_plt_role;
418
+
419
+ -- 优化表(重建索引)
420
+ OPTIMIZE TABLE zz_plt_role;
421
+ ```
422
+
423
+ ---
424
+
425
+ ## 十、索引设计检查清单
426
+
427
+ 创建索引前,请检查以下项目:
428
+
429
+ - [ ] 索引名称是否符合命名规范
430
+ - [ ] 是否避免在低区分度字段上建索引
431
+ - [ ] 联合索引字段顺序是否合理(等值 → 范围 → 排序)
432
+ - [ ] 是否考虑了覆盖索引优化
433
+ - [ ] 单表索引数量是否超过 5 个
434
+ - [ ] 联合索引字段数量是否超过 3 个
435
+ - [ ] 是否有重复或冗余的索引
436
+ - [ ] 关联表是否包含必要的索引
437
+
438
+ ---
439
+
440
+ ## 十一、常见错误示例
441
+
442
+ ### 错误 1:在低区分度字段上建索引
443
+
444
+ ```sql
445
+ -- ❌ 错误
446
+ KEY `idx_role_deleted` (`is_deleted`) -- 只有 0 和 1 两个值
447
+
448
+ -- ✅ 正确:作为联合索引的一部分
449
+ KEY `idx_role_status` (`status`, `is_deleted`)
450
+ ```
451
+
452
+ ### 错误 2:联合索引字段顺序错误
453
+
454
+ ```sql
455
+ -- ❌ 错误:范围查询在前
456
+ KEY `idx_order_created_status` (`created_at`, `status`)
457
+
458
+ -- ✅ 正确:等值查询在前
459
+ KEY `idx_order_status_created` (`status`, `created_at`)
460
+ ```
461
+
462
+ ### 错误 3:索引过多
463
+
464
+ ```sql
465
+ -- ❌ 错误:单表索引过多(7 个)
466
+ KEY `idx_role_code` (`role_code`)
467
+ KEY `idx_role_name` (`role_name`)
468
+ KEY `idx_role_status` (`status`)
469
+ KEY `idx_role_type` (`type`)
470
+ KEY `idx_role_created` (`created_at`)
471
+ KEY `idx_role_updated` (`updated_at`)
472
+ KEY `idx_role_deleted` (`is_deleted`)
473
+
474
+ -- ✅ 正确:合并为联合索引
475
+ UNIQUE KEY `uk_role_code` (`role_code`)
476
+ KEY `idx_role_name` (`role_name`)
477
+ KEY `idx_role_status` (`status`, `type`, `is_deleted`)
478
+ KEY `idx_role_created` (`created_at`)
479
+ ```
480
+
481
+ ### 错误 4:缺少关联表索引
482
+
483
+ ```sql
484
+ -- ❌ 错误:只有联合唯一索引
485
+ CREATE TABLE `zz_plt_avatar_role_rel` (
486
+ `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
487
+ `avatar_id` BIGINT UNSIGNED NOT NULL,
488
+ `role_id` BIGINT UNSIGNED NOT NULL,
489
+ PRIMARY KEY (`id`),
490
+ UNIQUE KEY `uk_avatar_role` (`avatar_id`, `role_id`)
491
+ );
492
+
493
+ -- ✅ 正确:增加反向查询索引
494
+ CREATE TABLE `zz_plt_avatar_role_rel` (
495
+ `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
496
+ `avatar_id` BIGINT UNSIGNED NOT NULL,
497
+ `role_id` BIGINT UNSIGNED NOT NULL,
498
+ PRIMARY KEY (`id`),
499
+ UNIQUE KEY `uk_avatar_role` (`avatar_id`, `role_id`),
500
+ KEY `idx_avatar_role_rel_role` (`role_id`) -- 反向查询索引
501
+ );
502
+ ```
503
+
504
+ ---
505
+
506
+ **参考文档**:[MySQL 数据库规范](../../../database/mysql-specification.md)