@llryiop/avatar-boot-cli 1.0.1 → 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.
- package/docs/exam-question-generate-api.md +163 -0
- package/package.json +1 -1
- package/src/prompts.js +3 -3
- package/src/transform.js +1 -1
- package/templates/.claude/skills/avatar-boot-starter-feign/README.md +243 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/SKILL.md +47 -219
- package/templates/.claude/skills/avatar-boot-starter-feign/references//345/212/237/350/203/275/350/257/246/350/247/243.md +65 -0
- 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
- package/templates/.claude/skills/avatar-boot-starter-feign/references//351/205/215/347/275/256/345/217/202/350/200/203.md +70 -0
- package/templates/.claude/skills/avatar-boot-starter-job/README.md +437 -0
- package/templates/.claude/skills/avatar-boot-starter-job/SKILL.md +35 -414
- package/templates/.claude/skills/avatar-boot-starter-job/references//345/270/270/350/247/201/351/227/256/351/242/230.md +55 -0
- 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
- package/templates/.claude/skills/avatar-boot-starter-job/references//347/233/221/346/216/247/346/214/207/346/240/207.md +72 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/README.md +580 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/SKILL.md +36 -560
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/234/200/344/275/263/345/256/236/350/267/265.md +43 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/240/270/345/277/203/345/212/237/350/203/275.md +117 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//351/205/215/347/275/256/345/217/202/350/200/203.md +54 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/README.md +572 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/SKILL.md +40 -550
- 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
- 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
- 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
- package/templates/.claude/skills/avatar-boot-starter-nacos/README.md +901 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/SKILL.md +40 -879
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/212/237/350/203/275/344/275/277/347/224/250.md +134 -0
- 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
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//346/225/205/351/232/234/346/216/222/346/237/245.md +64 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/README.md +594 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/SKILL.md +52 -570
- 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
- package/templates/.claude/skills/avatar-boot-starter-oss/references//346/240/270/345/277/203/345/212/237/350/203/275.md +94 -0
- 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
- package/templates/.claude/skills/avatar-boot-starter-redis/README.md +586 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/SKILL.md +42 -566
- 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
- package/templates/.claude/skills/avatar-boot-starter-redis/references//346/225/260/346/215/256/346/223/215/344/275/234.md +111 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/references//351/253/230/347/272/247/345/212/237/350/203/275.md +90 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/README.md +662 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/SKILL.md +48 -640
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//346/240/270/345/277/203/345/212/237/350/203/275.md +101 -0
- 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
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/253/230/347/272/247/347/211/271/346/200/247.md +71 -0
- package/templates/.claude/skills/avatar-boot-starter-web/README.md +1007 -0
- package/templates/.claude/skills/avatar-boot-starter-web/SKILL.md +150 -1003
- 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
- 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
- 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
- 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
- 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
- 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
- package/templates/.claude/skills/avatar-boot-starter-web/references//346/263/250/346/204/217/344/272/213/351/241/271.md +68 -0
- 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
- package/templates/.claude/skills/avatar-boot-starter-web/references//351/205/215/347/275/256/345/217/202/350/200/203.md +107 -0
- package/templates/.claude/skills/crud-generator/SKILL.md +133 -64
- package/templates/.claude/skills/database-design/README.md +207 -0
- package/templates/.claude/skills/database-design/SKILL.md +469 -82
- package/templates/.claude/skills/database-design/references//345/221/275/345/220/215/350/247/204/350/214/203.md +232 -0
- 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
- package/templates/.claude/skills/database-design/references//347/264/242/345/274/225/350/247/204/350/214/203.md +506 -0
- package/templates/avatar-scaffold-api/pom.xml +0 -5
- package/templates/avatar-scaffold-service/pom.xml +25 -87
- package/templates/avatar-scaffold-service/src/main/resources/application-dev.yaml +3 -5
- package/templates/avatar-scaffold-service/src/main/resources/application-local.yaml +2 -2
- 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)
|
|
@@ -31,11 +31,6 @@
|
|
|
31
31
|
<groupId>jakarta.validation</groupId>
|
|
32
32
|
<artifactId>jakarta.validation-api</artifactId>
|
|
33
33
|
</dependency>
|
|
34
|
-
<dependency>
|
|
35
|
-
<groupId>org.projectlombok</groupId>
|
|
36
|
-
<artifactId>lombok</artifactId>
|
|
37
|
-
<optional>true</optional>
|
|
38
|
-
</dependency>
|
|
39
34
|
</dependencies>
|
|
40
35
|
|
|
41
36
|
</project>
|
|
@@ -32,116 +32,54 @@
|
|
|
32
32
|
<groupId>com.iflytek.avatar.boot</groupId>
|
|
33
33
|
<artifactId>avatar-boot-starter-nacos</artifactId>
|
|
34
34
|
</dependency>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<!-- <dependency>-->
|
|
40
|
-
<!-- <groupId>com.iflytek.avatar.boot</groupId>-->
|
|
41
|
-
<!-- <artifactId>avatar-boot-starter-redis</artifactId>-->
|
|
42
|
-
<!-- </dependency>-->
|
|
35
|
+
<dependency>
|
|
36
|
+
<groupId>com.iflytek.avatar.boot</groupId>
|
|
37
|
+
<artifactId>avatar-boot-starter-mysql</artifactId>
|
|
38
|
+
</dependency>
|
|
43
39
|
</dependencies>
|
|
44
40
|
|
|
45
41
|
<build>
|
|
46
42
|
<plugins>
|
|
43
|
+
<plugin>
|
|
44
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
45
|
+
<artifactId>maven-compiler-plugin</artifactId>
|
|
46
|
+
<configuration>
|
|
47
|
+
<annotationProcessorPaths>
|
|
48
|
+
<path>
|
|
49
|
+
<groupId>org.projectlombok</groupId>
|
|
50
|
+
<artifactId>lombok</artifactId>
|
|
51
|
+
<version>1.18.36</version>
|
|
52
|
+
</path>
|
|
53
|
+
</annotationProcessorPaths>
|
|
54
|
+
</configuration>
|
|
55
|
+
</plugin>
|
|
47
56
|
<plugin>
|
|
48
57
|
<groupId>org.springframework.boot</groupId>
|
|
49
58
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
50
59
|
<version>3.5.3</version>
|
|
51
|
-
</plugin>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<plugin>
|
|
55
|
-
<groupId>org.codehaus.mojo</groupId>
|
|
56
|
-
<artifactId>appassembler-maven-plugin</artifactId>
|
|
57
|
-
<version>1.10</version>
|
|
58
|
-
<configuration>
|
|
59
|
-
<repositoryLayout>flat</repositoryLayout>
|
|
60
|
-
<!-- 在脚本的classpath开始增加配置文件路径 -->
|
|
61
|
-
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
|
|
62
|
-
<!-- 生成配置文件路径 -->
|
|
63
|
-
<configurationDirectory>conf</configurationDirectory>
|
|
64
|
-
<!-- 配置文件原路径 -->
|
|
65
|
-
<configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
|
|
66
|
-
<!-- 从原配置文件复制 -->
|
|
67
|
-
<copyConfigurationDirectory>true</copyConfigurationDirectory>
|
|
68
|
-
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
|
|
69
|
-
|
|
70
|
-
<!-- 生成哪几种平台的脚本 -->
|
|
71
|
-
<platforms>
|
|
72
|
-
<platform>unix</platform>
|
|
73
|
-
<platform>windows</platform>
|
|
74
|
-
</platforms>
|
|
75
|
-
<!-- 生成脚本的后缀 -->
|
|
76
|
-
<binFileExtensions>
|
|
77
|
-
<unix>.sh</unix>
|
|
78
|
-
<windows>.bat</windows>
|
|
79
|
-
</binFileExtensions>
|
|
80
|
-
<!-- 使用classpath通配符 -->
|
|
81
|
-
<useWildcardClassPath>true</useWildcardClassPath>
|
|
82
|
-
<!-- JVM参数 -->
|
|
83
|
-
<!-- <extraJvmArguments>-Xms512m -Xmx2048m</extraJvmArguments>-->
|
|
84
|
-
<!-- 依赖包目录 -->
|
|
85
|
-
<repositoryName>lib</repositoryName>
|
|
86
|
-
<programs>
|
|
87
|
-
<program>
|
|
88
|
-
<name>startup</name>
|
|
89
|
-
<mainClass>com.iflytek.avatar.Application</mainClass>
|
|
90
|
-
</program>
|
|
91
|
-
</programs>
|
|
92
|
-
</configuration>
|
|
93
|
-
<!-- 绑定生命周期 -->
|
|
94
60
|
<executions>
|
|
95
61
|
<execution>
|
|
96
|
-
<id>appassembler</id>
|
|
97
|
-
<phase>package</phase>
|
|
98
62
|
<goals>
|
|
99
|
-
<goal>
|
|
63
|
+
<goal>repackage</goal>
|
|
100
64
|
</goals>
|
|
101
65
|
</execution>
|
|
102
66
|
</executions>
|
|
103
|
-
</plugin>
|
|
104
|
-
<plugin>
|
|
105
|
-
<artifactId>maven-assembly-plugin</artifactId>
|
|
106
67
|
<configuration>
|
|
107
|
-
<
|
|
108
|
-
<descriptors>
|
|
109
|
-
<descriptor>packaging/assembly.xml</descriptor>
|
|
110
|
-
</descriptors>
|
|
68
|
+
<mainClass>com.iflytek.avatar.Application</mainClass>
|
|
111
69
|
</configuration>
|
|
112
|
-
<executions>
|
|
113
|
-
<execution>
|
|
114
|
-
<id>make-assembly</id>
|
|
115
|
-
<phase>package</phase>
|
|
116
|
-
<goals>
|
|
117
|
-
<goal>single</goal>
|
|
118
|
-
</goals>
|
|
119
|
-
</execution>
|
|
120
|
-
</executions>
|
|
121
70
|
</plugin>
|
|
122
|
-
|
|
123
71
|
<plugin>
|
|
124
72
|
<groupId>org.apache.maven.plugins</groupId>
|
|
125
|
-
<artifactId>maven-
|
|
126
|
-
<version>3.
|
|
127
|
-
<configuration>
|
|
128
|
-
<source>${java.version}</source>
|
|
129
|
-
<target>${java.version}</target>
|
|
130
|
-
<encoding>${project.build.sourceEncoding}</encoding>
|
|
131
|
-
</configuration>
|
|
73
|
+
<artifactId>maven-jar-plugin</artifactId>
|
|
74
|
+
<version>3.4.1</version>
|
|
132
75
|
</plugin>
|
|
133
|
-
|
|
134
|
-
<!-- 设置程序启动的Main Class -->
|
|
135
76
|
<plugin>
|
|
136
77
|
<groupId>org.apache.maven.plugins</groupId>
|
|
137
|
-
<artifactId>maven-
|
|
138
|
-
<version>3.
|
|
78
|
+
<artifactId>maven-surefire-plugin</artifactId>
|
|
79
|
+
<version>3.2.5</version>
|
|
139
80
|
<configuration>
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
<exclude>*.yml</exclude>
|
|
143
|
-
<exclude>*.properties</exclude>
|
|
144
|
-
</excludes>
|
|
81
|
+
<argLine>-Djava.security.manager=allow</argLine>
|
|
82
|
+
<useManifestOnlyJar>false</useManifestOnlyJar>
|
|
145
83
|
</configuration>
|
|
146
84
|
</plugin>
|
|
147
85
|
</plugins>
|
|
@@ -2,14 +2,14 @@ spring:
|
|
|
2
2
|
config:
|
|
3
3
|
import:
|
|
4
4
|
# 使用 optional: 前缀,Nacos 不可用时不会阻止启动
|
|
5
|
-
- optional:nacos:${spring.application.name}.yaml?group=${NACOS_GROUP:
|
|
5
|
+
- optional:nacos:${spring.application.name}.yaml?group=${NACOS_GROUP:DEFAULT_GROUP}&refreshEnabled=true
|
|
6
6
|
- optional:nacos:common-database.yaml?group=SHARED_GROUP&refreshEnabled=true
|
|
7
7
|
- optional:nacos:common-redis.yaml?group=SHARED_GROUP&refreshEnabled=true
|
|
8
8
|
|
|
9
9
|
# nacos 配置
|
|
10
10
|
cloud:
|
|
11
11
|
nacos:
|
|
12
|
-
server-addr: ${NACOS_SERVER_ADDR:172.
|
|
12
|
+
server-addr: ${NACOS_SERVER_ADDR:172.31.250.98:8848}
|
|
13
13
|
namespace: ${NACOS_NAMESPACE:dev}
|
|
14
14
|
username: ${NACOS_USERNAME:nacos}
|
|
15
15
|
password: ${NACOS_PASSWORD:Xnrpt@2026}
|
|
@@ -17,13 +17,11 @@ spring:
|
|
|
17
17
|
config:
|
|
18
18
|
enabled: true
|
|
19
19
|
file-extension: yaml
|
|
20
|
-
group: ${NACOS_GROUP:AVATAR_PLATFORM}
|
|
21
20
|
|
|
22
21
|
discovery:
|
|
23
22
|
enabled: true
|
|
24
23
|
register-enabled: true
|
|
25
24
|
ephemeral: true
|
|
26
|
-
group: ${NACOS_GROUP:AVATAR_PLATFORM}
|
|
27
25
|
metadata:
|
|
28
26
|
version: 1.0.0
|
|
29
|
-
environment:
|
|
27
|
+
environment: oma
|
|
@@ -19,8 +19,8 @@ spring:
|
|
|
19
19
|
master:
|
|
20
20
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
21
21
|
username: root
|
|
22
|
-
password:
|
|
23
|
-
url: jdbc:mysql://
|
|
22
|
+
password: Xnrpt@2026
|
|
23
|
+
url: jdbc:mysql://mysql1_23306_test.xfyousheng.com:23306/avatar_zhizuo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
|
24
24
|
type: com.alibaba.druid.pool.DruidDataSource
|
|
25
25
|
druid:
|
|
26
26
|
initial-size: 5
|