@gordon.gan/specflow 1.3.3-beta → 1.4.1

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 (85) hide show
  1. package/README.md +6 -2
  2. package/dist/integrations/shared/capability-evidence.js +37 -1
  3. package/dist/integrations/shared/command-catalog.js +1 -0
  4. package/dist/integrations/shared/parity-manifest.js +6 -0
  5. package/package.json +1 -1
  6. package/prompts/approval/database-guidance.md +79 -0
  7. package/prompts/approval/generate.md +1191 -0
  8. package/skills/database/LICENSE +405 -0
  9. package/skills/database/ORIGIN.md +6 -0
  10. package/skills/database/README.md +30 -0
  11. package/skills/database/elasticsearch/LICENSE.txt +202 -0
  12. package/skills/database/elasticsearch/SKILL.md +199 -0
  13. package/skills/database/elasticsearch/examples/01-fulltext-search.md +215 -0
  14. package/skills/database/elasticsearch/examples/02-aggregation-report.md +206 -0
  15. package/skills/database/elasticsearch/examples/03-reindex-zero-downtime.md +200 -0
  16. package/skills/database/elasticsearch/examples/04-cluster-monitoring.md +204 -0
  17. package/skills/database/elasticsearch/references/01-query-dsl-fulltext.md +162 -0
  18. package/skills/database/elasticsearch/references/02-query-dsl-term.md +210 -0
  19. package/skills/database/elasticsearch/references/03-aggregations-metric.md +161 -0
  20. package/skills/database/elasticsearch/references/04-aggregations-bucket.md +236 -0
  21. package/skills/database/elasticsearch/references/05-mapping-types.md +134 -0
  22. package/skills/database/elasticsearch/references/06-analyzers.md +187 -0
  23. package/skills/database/elasticsearch/references/07-cluster-ops.md +225 -0
  24. package/skills/database/elasticsearch/references/08-elk-integration.md +170 -0
  25. package/skills/database/mysql/SKILL.md +195 -0
  26. package/skills/database/mysql/examples/01-connection-pool.md +75 -0
  27. package/skills/database/mysql/examples/02-slow-query-optimization.md +98 -0
  28. package/skills/database/mysql/examples/03-master-slave-setup.md +144 -0
  29. package/skills/database/mysql/examples/04-backup-strategy.md +212 -0
  30. package/skills/database/mysql/references/01-functions-string.md +103 -0
  31. package/skills/database/mysql/references/02-functions-date.md +152 -0
  32. package/skills/database/mysql/references/03-functions-aggregate-window.md +167 -0
  33. package/skills/database/mysql/references/04-functions-json.md +129 -0
  34. package/skills/database/mysql/references/05-sql-ddl-types.md +235 -0
  35. package/skills/database/mysql/references/06-index-optimization.md +232 -0
  36. package/skills/database/mysql/references/07-replication-ha.md +213 -0
  37. package/skills/database/mysql/references/08-backup-restore.md +207 -0
  38. package/skills/database/mysql/references/09-advanced-features.md +345 -0
  39. package/skills/database/oracle/LICENSE.txt +202 -0
  40. package/skills/database/oracle/SKILL.md +238 -0
  41. package/skills/database/oracle/examples/01-plsql-procedure.md +90 -0
  42. package/skills/database/oracle/examples/02-awr-analysis.md +99 -0
  43. package/skills/database/oracle/examples/03-rman-backup.md +108 -0
  44. package/skills/database/oracle/examples/04-dataguard-setup.md +146 -0
  45. package/skills/database/oracle/references/01-functions-string.md +91 -0
  46. package/skills/database/oracle/references/02-functions-date.md +71 -0
  47. package/skills/database/oracle/references/03-analytic-functions.md +103 -0
  48. package/skills/database/oracle/references/04-plsql-guide.md +303 -0
  49. package/skills/database/oracle/references/05-performance-tuning.md +164 -0
  50. package/skills/database/oracle/references/06-backup-recovery.md +115 -0
  51. package/skills/database/oracle/references/07-dataguard-rac.md +76 -0
  52. package/skills/database/oracle/references/08-security.md +170 -0
  53. package/skills/database/oracle/references/09-sql-syntax.md +152 -0
  54. package/skills/database/oracle/references/10-features.md +174 -0
  55. package/skills/database/postgresql/LICENSE.txt +202 -0
  56. package/skills/database/postgresql/SKILL.md +182 -0
  57. package/skills/database/postgresql/examples/.gitkeep +0 -0
  58. package/skills/database/postgresql/examples/01-jsonb-query.md +72 -0
  59. package/skills/database/postgresql/examples/02-cte-recursive.md +110 -0
  60. package/skills/database/postgresql/examples/03-performance-tuning.md +114 -0
  61. package/skills/database/postgresql/examples/04-streaming-replication.md +113 -0
  62. package/skills/database/postgresql/references/.gitkeep +0 -0
  63. package/skills/database/postgresql/references/01-functions-string.md +174 -0
  64. package/skills/database/postgresql/references/02-functions-datetime.md +54 -0
  65. package/skills/database/postgresql/references/03-functions-aggregate-window.md +142 -0
  66. package/skills/database/postgresql/references/04-functions-jsonb.md +117 -0
  67. package/skills/database/postgresql/references/05-fulltext-search.md +109 -0
  68. package/skills/database/postgresql/references/06-index-types.md +95 -0
  69. package/skills/database/postgresql/references/07-partition-fdw.md +133 -0
  70. package/skills/database/postgresql/references/08-replication-backup.md +215 -0
  71. package/skills/database/redis/LICENSE.txt +202 -0
  72. package/skills/database/redis/SKILL.md +922 -0
  73. package/skills/database/redis/examples/01-cache-usage.md +104 -0
  74. package/skills/database/redis/examples/02-session-storage.md +72 -0
  75. package/skills/database/redis/examples/03-leaderboard.md +63 -0
  76. package/skills/database/redis/examples/04-redis-cluster-setup.md +70 -0
  77. package/skills/database/redis/examples/05-stream-queue.md +65 -0
  78. package/skills/database/redis/references/command-quick-ref.md +180 -0
  79. package/skills/database/redis/references/commands-admin-key.md +413 -0
  80. package/skills/database/redis/references/commands-set-sorted-advanced.md +539 -0
  81. package/skills/database/redis/references/commands-string-hash-list.md +458 -0
  82. package/skills/database/redis/references/memory-optimization.md +150 -0
  83. package/skills/database/redis/references/redis-conf-production.md +139 -0
  84. package/skills/specflow-approval/SKILL.md +427 -0
  85. package/templates/approval.md +464 -0
@@ -0,0 +1,167 @@
1
+ # 聚合函数与窗口函数 (Aggregate & Window Functions)
2
+
3
+ ## 聚合函数 (Aggregate Functions)
4
+
5
+ ### 简介
6
+
7
+ 聚合函数对一组行进行计算并返回单个值,常与 `GROUP BY` 子句配合使用,用于统计汇总和报表生成。
8
+
9
+ ### 常用聚合函数
10
+
11
+ | 函数 | 说明 | 使用示例 | 注意 |
12
+ |------|------|---------|------|
13
+ | `COUNT(*)` | 行数计数(含 NULL) | `COUNT(*)` | 性能最好 |
14
+ | `COUNT(expr)` | 非 NULL 值计数 | `COUNT(column_name)` | 排除 NULL |
15
+ | `COUNT(DISTINCT expr)` | 去重计数 | `COUNT(DISTINCT user_id)` | UV 统计 |
16
+ | `SUM(expr)` | 求和 | `SUM(amount)` | 忽略 NULL |
17
+ | `AVG(expr)` | 平均值 | `AVG(score)` | SUM/COUNT 实现 |
18
+ | `MAX(expr)` | 最大值 | `MAX(price)` | 字符串按字典序 |
19
+ | `MIN(expr)` | 最小值 | `MIN(price)` | 字符串按字典序 |
20
+ | `GROUP_CONCAT(expr)` | 组内拼接 | `GROUP_CONCAT(name SEPARATOR ',')` | 长度限制 1024 |
21
+
22
+ ### 业务场景
23
+
24
+ #### 订单日报统计
25
+
26
+ ```sql
27
+ SELECT
28
+ COUNT(*) AS total_orders,
29
+ COUNT(DISTINCT user_id) AS unique_users,
30
+ SUM(amount) AS total_revenue,
31
+ AVG(amount) AS avg_order_amount,
32
+ MAX(amount) AS max_order,
33
+ MIN(amount) AS min_order
34
+ FROM `order`
35
+ WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
36
+ ```
37
+
38
+ #### GROUP_CONCAT 行转列
39
+
40
+ ```sql
41
+ SELECT
42
+ u.name,
43
+ GROUP_CONCAT(o.order_no ORDER BY o.created_at SEPARATOR ', ') AS orders
44
+ FROM user u
45
+ LEFT JOIN `order` o ON u.id = o.user_id
46
+ GROUP BY u.id;
47
+ ```
48
+
49
+ #### CASE WHEN 条件聚合 (Pivot)
50
+
51
+ ```sql
52
+ SELECT
53
+ SUM(CASE WHEN amount < 100 THEN 1 ELSE 0 END) AS low_orders,
54
+ SUM(CASE WHEN amount BETWEEN 100 AND 1000 THEN 1 ELSE 0 END) AS mid_orders,
55
+ SUM(CASE WHEN amount > 1000 THEN 1 ELSE 0 END) AS high_orders
56
+ FROM `order`;
57
+ ```
58
+
59
+ ## 窗口函数 (Window Functions, MySQL 8.0+)
60
+
61
+ ### 简介
62
+
63
+ 窗口函数在不折叠行的情况下对结果集进行聚合和排名计算。与 `GROUP BY` 不同,窗口函数保留所有原始行,为每行添加计算结果。
64
+
65
+ **语法**:
66
+
67
+ ```sql
68
+ function_name() OVER (
69
+ [PARTITION BY col1, col2, ...] -- 分组(可选)
70
+ [ORDER BY col ASC|DESC] -- 排序(可选)
71
+ [frame_clause] -- 窗口帧(可选)
72
+ )
73
+ ```
74
+
75
+ ### 排名函数
76
+
77
+ | 函数 | 说明 | 行为特点 | 业务场景 |
78
+ |------|------|---------|---------|
79
+ | `ROW_NUMBER()` | 行号 | 每行唯一连续编号,无并列 | TOP-N 查询、分页去重 |
80
+ | `RANK()` | 排名 | 并列跳号(如 1,1,3) | 竞赛排名 |
81
+ | `DENSE_RANK()` | 密集排名 | 并列不跳号(如 1,1,2) | 销售排名分组 |
82
+ | `NTILE(n)` | 分桶 | 均分为 n 组 | 四分位分析、数据分桶 |
83
+
84
+ #### 示例:每部门薪资 TOP 3
85
+
86
+ ```sql
87
+ SELECT dept_id, name, salary
88
+ FROM (
89
+ SELECT dept_id, name, salary,
90
+ ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn
91
+ FROM employee
92
+ ) t
93
+ WHERE rn <= 3;
94
+ ```
95
+
96
+ #### 示例:考试成绩排名
97
+
98
+ ```sql
99
+ SELECT name, score,
100
+ RANK() OVER (ORDER BY score DESC) AS rnk,
101
+ DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rnk
102
+ FROM exam_score;
103
+ ```
104
+
105
+ ### 偏移函数
106
+
107
+ | 函数 | 说明 | 业务场景 |
108
+ |------|------|---------|
109
+ | `LAG(col, offset, default)` | 向前取第 N 行 | 环比、同比 |
110
+ | `LEAD(col, offset, default)` | 向后取第 N 行 | 下期预测 |
111
+ | `FIRST_VALUE(col)` | 窗口内第一个值 | 基准对比 |
112
+ | `LAST_VALUE(col)` | 窗口内最后一个值 | 期末值 |
113
+ | `NTH_VALUE(col, n)` | 窗口内第 N 个值 | 指定位置值 |
114
+
115
+ #### 示例:日环比增长
116
+
117
+ ```sql
118
+ SELECT created_at, amount,
119
+ LAG(amount, 1, 0) OVER (ORDER BY created_at) AS prev_amount,
120
+ amount - LAG(amount, 1, 0) OVER (ORDER BY created_at) AS diff,
121
+ ROUND((amount - LAG(amount, 1, 0) OVER (ORDER BY created_at)) /
122
+ LAG(amount, 1, 0) OVER (ORDER BY created_at) * 100, 2) AS growth_pct
123
+ FROM daily_sales;
124
+ ```
125
+
126
+ ### 聚合窗口函数(累计计算)
127
+
128
+ 聚合函数(SUM、AVG、COUNT 等)加上 `OVER()` 子句后可作为窗口函数使用。
129
+
130
+ #### 示例:月度累计销售额
131
+
132
+ ```sql
133
+ SELECT date, amount,
134
+ SUM(amount) OVER (ORDER BY date) AS cumulative_sum,
135
+ AVG(amount) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_avg_7d
136
+ FROM daily_sales;
137
+ ```
138
+
139
+ #### 示例:部门内薪资对比
140
+
141
+ ```sql
142
+ SELECT dept_id, name, salary,
143
+ AVG(salary) OVER (PARTITION BY dept_id) AS dept_avg_salary,
144
+ salary - AVG(salary) OVER (PARTITION BY dept_id) AS diff_from_avg,
145
+ ROUND(salary / AVG(salary) OVER (PARTITION BY dept_id) * 100, 2) AS pct_of_avg
146
+ FROM employee;
147
+ ```
148
+
149
+ ### 窗口帧 (Frame Clause)
150
+
151
+ 帧定义了窗口函数的计算范围:
152
+
153
+ | 帧语法 | 说明 |
154
+ |--------|------|
155
+ | `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW` | 从开始到当前行(默认) |
156
+ | `ROWS BETWEEN 6 PRECEDING AND CURRENT ROW` | 前 6 行到当前行(移动平均) |
157
+ | `ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING` | 当前行到结束 |
158
+ | `ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING` | 前后各 3 行 |
159
+ | `RANGE BETWEEN ...` | 按值范围而非行数 |
160
+ | `ROWS UNBOUNDED PRECEDING` | 从开始到当前行(简写) |
161
+
162
+ ## 注意事项
163
+
164
+ - `COUNT(*)` 和 `COUNT(col)` 不同:前者包含 NULL 行,后者排除
165
+ - `GROUP_CONCAT` 结果受 `group_concat_max_len` 限制(默认 1024),可 `SET SESSION group_concat_max_len = 10000;`
166
+ - 窗口函数只能在 `SELECT` 和 `ORDER BY` 中使用,不能在 `WHERE`、`GROUP BY`、`HAVING` 中使用
167
+ - `LAST_VALUE` 的默认帧是 `RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`,需要在 ORDER BY 后显式指定帧才能得到正确结果
@@ -0,0 +1,129 @@
1
+ # JSON 函数 (JSON Functions, MySQL 5.7+)
2
+
3
+ ## 简介
4
+
5
+ MySQL 5.7+ 原生支持 JSON 数据类型和一系列 JSON 操作函数。JSON 类型比字符串存储更高效(自动校验格式、内部二进制存储),支持通过虚拟列建立索引。
6
+
7
+ ## 函数速查
8
+
9
+ ### 查询与提取
10
+
11
+ | 函数 | 说明 | 版本 | 示例 |
12
+ |------|------|------|------|
13
+ | `JSON_EXTRACT(doc, path)` | 提取 JSON 值 | 5.7+ | `JSON_EXTRACT(attrs, '$.color')` |
14
+ | `col->'$.path'` | JSON_EXTRACT 简写 | 5.7+ | `attrs->'$.color'` |
15
+ | `col->>'$.path'` | 去引号版 | 8.0+ | `attrs->>'$.color'` |
16
+ | `JSON_CONTAINS(doc, val, path)` | 是否包含指定值 | 5.7+ | `JSON_CONTAINS(attrs, '"red"', '$.color')` |
17
+ | `JSON_CONTAINS_PATH(doc, one_or_all, path...)` | 路径是否存在 | 5.7+ | `JSON_CONTAINS_PATH(attrs, 'one', '$.color')` |
18
+ | `JSON_KEYS(doc, path)` | 返回所有键 | 5.7+ | `JSON_KEYS(attrs)` |
19
+ | `JSON_LENGTH(doc, path)` | 数组/对象长度 | 5.7+ | `JSON_LENGTH(attrs, '$.tags')` |
20
+ | `JSON_DEPTH(doc)` | JSON 文档深度 | 5.7+ | `JSON_DEPTH(attrs)` |
21
+ | `JSON_VALID(doc)` | 验证 JSON 合法性 | 5.7+ | `JSON_VALID('{"a":1}')` |
22
+ | `JSON_SEARCH(doc, one_or_all, str)` | 搜索值路径 | 5.7+ | `JSON_SEARCH(attrs, 'one', 'red')` |
23
+ | `JSON_TABLE(doc, path COLUMNS(...))` | JSON 转行(表函数) | 8.0+ | 见下 |
24
+
25
+ ### JSON 路径语法
26
+
27
+ | 路径表达式 | 说明 |
28
+ |-----------|------|
29
+ | `$` | 根节点 |
30
+ | `$.key` | 对象键 |
31
+ | `$.nested.key` | 嵌套键 |
32
+ | `$[0]` | 数组第一个元素 |
33
+ | `$[*]` | 所有数组元素 |
34
+ | `$.key[*].sub` | 数组中所有元素的子键 |
35
+
36
+ ### 构造与修改
37
+
38
+ | 函数 | 说明 | 示例 |
39
+ |------|------|------|
40
+ | `JSON_OBJECT(k, v, ...)` | 构造 JSON 对象 | `JSON_OBJECT('id', 1, 'name', 'test')` |
41
+ | `JSON_ARRAY(v1, v2, ...)` | 构造 JSON 数组 | `JSON_ARRAY(1, 2, 3)` |
42
+ | `JSON_QUOTE(str)` | 字符串转 JSON 值 | `JSON_QUOTE('hello "world"')` |
43
+ | `JSON_UNQUOTE(val)` | 去除 JSON 引号 | `JSON_UNQUOTE('"hello"')` |
44
+ | `JSON_SET(doc, path, val)` | 设置/覆盖值 | `JSON_SET(attrs, '$.price', 5999)` |
45
+ | `JSON_INSERT(doc, path, val)` | 插入(不覆盖已有) | `JSON_INSERT(attrs, '$.discount', 0.8)` |
46
+ | `JSON_REPLACE(doc, path, val)` | 替换(仅在路径存在时) | `JSON_REPLACE(attrs, '$.price', 4999)` |
47
+ | `JSON_REMOVE(doc, path)` | 删除键 | `JSON_REMOVE(attrs, '$.discount')` |
48
+ | `JSON_ARRAY_APPEND(doc, path, val)` | 数组追加 | `JSON_ARRAY_APPEND(attrs, '$.tags', 'sale')` |
49
+ | `JSON_ARRAY_INSERT(doc, path, val)` | 数组插入 | `JSON_ARRAY_INSERT(attrs, '$.tags[0]', 'hot')` |
50
+ | `JSON_MERGE_PATCH(doc, patch)` | 合并(覆盖式) | `JSON_MERGE_PATCH(attrs, '{"color":"blue"}')` |
51
+ | `JSON_MERGE_PRESERVE(doc, patch)` | 合并(保留式) | `JSON_MERGE_PRESERVE(attrs, '{"color":"blue"}')` |
52
+
53
+ ### 聚合函数
54
+
55
+ | 函数 | 说明 | 示例 |
56
+ |------|------|------|
57
+ | `JSON_ARRAYAGG(col)` | 列转 JSON 数组 | `JSON_ARRAYAGG(product_name)` |
58
+ | `JSON_OBJECTAGG(k, v)` | 列转 JSON 对象 | `JSON_OBJECTAGG(id, name)` |
59
+
60
+ ## 业务场景
61
+
62
+ ### 场景 1: 从商品 JSON 字段提取属性
63
+
64
+ ```sql
65
+ SELECT id, name,
66
+ attrs->>'$.color' AS color,
67
+ attrs->'$.specs' AS specs
68
+ FROM product;
69
+ ```
70
+
71
+ ### 场景 2: 更新嵌套 JSON 字段
72
+
73
+ ```sql
74
+ UPDATE product
75
+ SET attrs = JSON_SET(attrs, '$.specs.storage', '256GB', '$.price', 5999)
76
+ WHERE id = 1;
77
+ ```
78
+
79
+ ### 场景 3: 记录操作日志(JSON 动态字段)
80
+
81
+ ```sql
82
+ INSERT INTO audit_log (action, detail) VALUES ('update_product',
83
+ JSON_OBJECT(
84
+ 'product_id', 1,
85
+ 'old_price', 99,
86
+ 'new_price', 129,
87
+ 'operator', 'admin',
88
+ 'timestamp', NOW()
89
+ ));
90
+ ```
91
+
92
+ ### 场景 4: JSON_TABLE 展开为关系表 (MySQL 8.0+)
93
+
94
+ ```sql
95
+ SELECT jt.*
96
+ FROM product,
97
+ JSON_TABLE(attrs, '$' COLUMNS (
98
+ color VARCHAR(20) PATH '$.color',
99
+ ram VARCHAR(10) PATH '$.specs.ram',
100
+ storage VARCHAR(10) PATH '$.specs.storage'
101
+ )) AS jt
102
+ WHERE color = 'black';
103
+ ```
104
+
105
+ ### 场景 5: 通过虚拟列建立 JSON 索引
106
+
107
+ MySQL 不支持直接对 JSON 列建索引。通过虚拟列 + 普通索引实现:
108
+
109
+ ```sql
110
+ -- 添加虚拟列
111
+ ALTER TABLE product ADD COLUMN color_virtual VARCHAR(20)
112
+ GENERATED ALWAYS AS (attrs->>'$.color');
113
+
114
+ -- 为虚拟列建索引
115
+ CREATE INDEX idx_product_color ON product(color_virtual);
116
+
117
+ -- 查询自动使用索引
118
+ SELECT * FROM product WHERE color_virtual = 'red';
119
+ ```
120
+
121
+ ## 注意事项
122
+
123
+ - JSON 列不存储重复键(保留最后一个值)
124
+ - JSON 列自动格式校验,非法格式会报错
125
+ - JSON 的二进制格式(BSON)允许快速键值查找,无需解析全文
126
+ - JSON 列不能有 DEFAULT 值(MySQL 限制)
127
+ - JSON 列不能直接索引,必须通过虚拟列间接索引
128
+ - 在 WHERE 中直接使用 `attrs->>'$.key'` 不会使用索引,需走虚拟列
129
+ - MySQL 8.0.13+ 支持 `JSON_TYPE()` 等更多 JSON 工具函数
@@ -0,0 +1,235 @@
1
+ # DDL 与数据类型详解
2
+
3
+ ## 简介
4
+
5
+ DDL(Data Definition Language)用于定义和管理数据库对象(库、表、索引、约束等)。正确选择数据类型和约束对性能和数据完整性至关重要。
6
+
7
+ ## 数据库操作
8
+
9
+ ```sql
10
+ -- 创建数据库
11
+ CREATE DATABASE IF NOT EXISTS shop
12
+ DEFAULT CHARACTER SET utf8mb4
13
+ DEFAULT COLLATE utf8mb4_unicode_ci;
14
+
15
+ -- 修改数据库
16
+ ALTER DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
17
+
18
+ -- 删除数据库
19
+ DROP DATABASE IF EXISTS shop;
20
+
21
+ -- 查看数据库列表
22
+ SHOW DATABASES;
23
+
24
+ -- 切换数据库
25
+ USE shop;
26
+
27
+ -- 查看当前数据库
28
+ SELECT DATABASE();
29
+ ```
30
+
31
+ ### 字符集选择建议
32
+
33
+ | 字符集 | 说明 | 推荐度 |
34
+ |--------|------|--------|
35
+ | `utf8mb4` | 支持 4 字节 emoji,推荐 | ★★★★★ |
36
+ | `utf8mb3` (utf8) | 不支持 emoji,已过时 | ★☆☆☆☆ |
37
+ | `utf8mb4_unicode_ci` | Unicode 通用排序 | ★★★★★ |
38
+ | `utf8mb4_general_ci` | 较宽松排序,稍快但不准确 | ★★★☆☆ |
39
+ | `utf8mb4_bin` | 二进制比较,区分大小写 | ★★★☆☆ |
40
+ | `utf8mb4_0900_ai_ci` | MySQL 8.0 默认,基于 UCA 9.0.0 | ★★★★★ |
41
+
42
+ **原则**:生产环境统一使用 `utf8mb4` + `utf8mb4_unicode_ci`,避免字符集混用导致乱码和索引失效。
43
+
44
+ ## 数据类型
45
+
46
+ ### 整数类型
47
+
48
+ | 类型 | 存储 | 有符号范围 | 无符号范围 | 推荐用途 |
49
+ |------|------|-----------|-----------|---------|
50
+ | `TINYINT` | 1B | -128 ~ 127 | 0 ~ 255 | 状态/性别/年龄 |
51
+ | `SMALLINT` | 2B | -32,768 ~ 32,767 | 0 ~ 65,535 | 库存/排名 |
52
+ | `MEDIUMINT` | 3B | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | 中型计数器 |
53
+ | `INT` | 4B | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | 常用主键 |
54
+ | `BIGINT` | 8B | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 | 雪花ID/流水号 |
55
+
56
+ **主键建议**:预期行数超过 40 亿时用 `BIGINT`,否则用 `INT`。MySQL 8.0.17+ 不推荐 `UNSIGNED`,建议用 `CHECK` 约束代替。
57
+
58
+ ```sql
59
+ -- ❌ 旧做法
60
+ age TINYINT UNSIGNED NOT NULL
61
+
62
+ -- ✅ MySQL 8.0.17+ 推荐
63
+ age TINYINT NOT NULL CHECK (age >= 0)
64
+ ```
65
+
66
+ ### 浮点数与定点数
67
+
68
+ | 类型 | 存储 | 精度 | 用途 |
69
+ |------|------|------|------|
70
+ | `FLOAT` | 4B | 约 7 位 | 科学计算(不用于金额) |
71
+ | `DOUBLE` | 8B | 约 15 位 | 科学计算 |
72
+ | `DECIMAL(M,D)` | M+2B 变长 | 精确 | **金额必选** |
73
+
74
+ ```sql
75
+ -- 金额字段
76
+ price DECIMAL(10, 2) NOT NULL DEFAULT 0.00 -- 最大 99999999.99
77
+ rate DECIMAL(5, 4) -- 利率 0.0001 ~ 9.9999
78
+ ```
79
+
80
+ ### 字符串类型
81
+
82
+ | 类型 | 最大长度 | 存储 | 用途 |
83
+ |------|---------|------|------|
84
+ | `CHAR(N)` | 255 | 定长,不足补空格 | 固定长度:手机号(11)、编码 |
85
+ | `VARCHAR(N)` | 65535 | 变长+1-2B前缀 | 用户名、邮箱、标题 |
86
+ | `TINYTEXT` | 255B | 行外 | 短备注 |
87
+ | `TEXT` | 64KB | 行外 | 文章内容、评论 |
88
+ | `MEDIUMTEXT` | 16MB | 行外 | 日志、长文本 |
89
+ | `LONGTEXT` | 4GB | 行外 | 大文档 |
90
+
91
+ **VARCHAR 长度选择**:
92
+ - `VARCHAR(255)` 和 `VARCHAR(50)` 在行内存储消耗相同(只看实际长度)
93
+ - 但临时表排序时按定义长度分配内存,不宜无意义设大
94
+ - 合理范围:50-200
95
+
96
+ **TEXT 注意事项**:
97
+ - TEXT 列不能有 DEFAULT 值
98
+ - TEXT 列不能用于内存临时表(ORDER BY 含 TEXT 会使用磁盘临时表)
99
+ - TEXT 列的索引必须指定前缀长度:`CREATE INDEX idx_content ON article (content(100));`
100
+
101
+ ### 枚举类型
102
+
103
+ | 类型 | 存储 | 说明 |
104
+ |------|------|------|
105
+ | `ENUM('v1','v2',...)` | 1-2B | 单选枚举,内部按整数存储 |
106
+ | `SET('v1','v2',...)` | 1-8B | 多选位图 |
107
+
108
+ **ENUM 注意事项**:
109
+ - 修改 ENUM 定义需全表重建(ALTER TABLE MODIFY)
110
+ - 内部按索引排序(定义顺序),非字母序
111
+ - 推荐用 `TINYINT` + 代码映射,更灵活且迁移友好
112
+
113
+ ```sql
114
+ -- 推荐做法
115
+ status TINYINT NOT NULL DEFAULT 0 COMMENT '0:pending 1:paid 2:shipped'
116
+
117
+ -- 不推荐
118
+ status ENUM('pending', 'paid', 'shipped') NOT NULL DEFAULT 'pending'
119
+ ```
120
+
121
+ ### JSON 类型 (MySQL 5.7+)
122
+
123
+ ```sql
124
+ -- 建表使用 JSON
125
+ attrs JSON DEFAULT NULL COMMENT '商品扩展属性'
126
+
127
+ -- 插入 JSON 数据
128
+ INSERT INTO product VALUES (1, '手机', '{"color": "black", "specs": {"ram": "8GB"}}');
129
+
130
+ -- 查询 JSON 值
131
+ SELECT attrs->>'$.color' AS color FROM product;
132
+ ```
133
+
134
+ 详情参见 references/04-functions-json.md。
135
+
136
+ ### 空间数据类型
137
+
138
+ | 类型 | 说明 | 业务场景 |
139
+ |------|------|---------|
140
+ | `POINT` | 点(经纬度) | 位置坐标 |
141
+ | `LINESTRING` | 线 | 路线 |
142
+ | `POLYGON` | 多边形 | 区域 |
143
+
144
+ ```sql
145
+ -- 创建空间表
146
+ CREATE TABLE location (
147
+ id INT PRIMARY KEY,
148
+ name VARCHAR(100),
149
+ coord POINT NOT NULL SRID 4326 -- WGS84 坐标系
150
+ );
151
+
152
+ -- 插入空间数据
153
+ INSERT INTO location VALUES (1, '北京天安门', ST_GeomFromText('POINT(116.397 39.908)', 4326));
154
+
155
+ -- 查询距离(米)
156
+ SELECT name, ST_Distance_Sphere(coord, ST_GeomFromText('POINT(116.4 39.9)', 4326)) AS distance_m
157
+ FROM location;
158
+
159
+ -- 空间索引
160
+ ALTER TABLE location ADD SPATIAL INDEX idx_coord (coord);
161
+ ```
162
+
163
+ ## 约束 (Constraints)
164
+
165
+ | 约束 | 说明 | 注意 |
166
+ |------|------|------|
167
+ | `PRIMARY KEY` | 唯一标识每行,自动非空 | 建议 BIGINT AUTO_INCREMENT 或有序 UUID |
168
+ | `UNIQUE` | 唯一值,允许多个 NULL | 联合唯一: `UNIQUE KEY uk_c1_c2 (c1, c2)` |
169
+ | `FOREIGN KEY` | 引用完整性、级联操作 | InnoDB 专用,影响写入性能 |
170
+ | `CHECK` | 值范围检查 | 8.0.16+ 才实际执行 |
171
+ | `NOT NULL` | 不允许 NULL | 能用就用,提高查询效率 |
172
+ | `DEFAULT` | 默认值 | 8.0.13+ 支持表达式 |
173
+ | `AUTO_INCREMENT` | 自增序列 | 仅整数主键 |
174
+
175
+ ### 完整建表示例
176
+
177
+ ```sql
178
+ CREATE TABLE IF NOT EXISTS `order` (
179
+ id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '订单ID',
180
+ order_no VARCHAR(32) NOT NULL COMMENT '订单号',
181
+ user_id INT UNSIGNED NOT NULL COMMENT '用户ID',
182
+ amount DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '金额',
183
+ status TINYINT NOT NULL DEFAULT 0 COMMENT '状态:0待支付1已支付2已取消',
184
+ quantity INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '数量',
185
+ email VARCHAR(100) DEFAULT NULL COMMENT '通知邮箱',
186
+ created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
187
+ updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
188
+ deleted_at DATETIME DEFAULT NULL COMMENT '软删除时间',
189
+
190
+ PRIMARY KEY (id),
191
+ UNIQUE KEY uk_order_no (order_no),
192
+ KEY idx_user_id (user_id),
193
+ KEY idx_status_created (status, created_at),
194
+ KEY idx_deleted_at (deleted_at),
195
+ CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE,
196
+ CONSTRAINT chk_amount CHECK (amount >= 0),
197
+ CONSTRAINT chk_status CHECK (status IN (0, 1, 2))
198
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表';
199
+ ```
200
+
201
+ ## ALTER TABLE — 表结构变更
202
+
203
+ ```sql
204
+ -- 添加列
205
+ ALTER TABLE user ADD COLUMN avatar VARCHAR(500) DEFAULT NULL AFTER nickname;
206
+
207
+ -- 修改列类型
208
+ ALTER TABLE user MODIFY COLUMN email VARCHAR(200) NOT NULL;
209
+
210
+ -- 重命名列
211
+ ALTER TABLE user CHANGE COLUMN email new_email VARCHAR(200) NOT NULL;
212
+
213
+ -- 重命名表
214
+ RENAME TABLE old_name TO new_name;
215
+
216
+ -- 添加索引
217
+ ALTER TABLE user ADD INDEX idx_email (email);
218
+ ALTER TABLE user ADD UNIQUE KEY uk_email (email);
219
+
220
+ -- 删除索引
221
+ ALTER TABLE user DROP INDEX idx_email;
222
+
223
+ -- 在线 DDL (MySQL 5.6+)
224
+ ALTER TABLE user ADD COLUMN age INT, ALGORITHM=INPLACE, LOCK=NONE;
225
+ ```
226
+
227
+ **生产环境大表改结构**使用 `pt-online-schema-change`(Percona Toolkit) 或 `gh-ost`,避免锁表。
228
+
229
+ ## DROP / TRUNCATE / DELETE 对比
230
+
231
+ | 操作 | 速度 | 可回滚 | 重置自增值 | 触发 ON DELETE | 释放空间 |
232
+ |------|------|--------|-----------|---------------|---------|
233
+ | `DELETE` | 慢(逐行) | ✅ | ❌ | ✅ | 不释放 |
234
+ | `TRUNCATE` | 快(DROP+CREATE) | ❌ | ✅ | ❌ | 释放 |
235
+ | `DROP` | 快 | ❌ | N/A | ❌ | 全部释放 |