@gordon.gan/specflow 1.4.0-beta → 1.4.2-beta

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 (82) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/prompts/approval/database-guidance.md +79 -0
  4. package/prompts/approval/generate.md +600 -290
  5. package/skills/database/LICENSE +405 -0
  6. package/skills/database/ORIGIN.md +6 -0
  7. package/skills/database/README.md +30 -0
  8. package/skills/database/elasticsearch/LICENSE.txt +202 -0
  9. package/skills/database/elasticsearch/SKILL.md +199 -0
  10. package/skills/database/elasticsearch/examples/01-fulltext-search.md +215 -0
  11. package/skills/database/elasticsearch/examples/02-aggregation-report.md +206 -0
  12. package/skills/database/elasticsearch/examples/03-reindex-zero-downtime.md +200 -0
  13. package/skills/database/elasticsearch/examples/04-cluster-monitoring.md +204 -0
  14. package/skills/database/elasticsearch/references/01-query-dsl-fulltext.md +162 -0
  15. package/skills/database/elasticsearch/references/02-query-dsl-term.md +210 -0
  16. package/skills/database/elasticsearch/references/03-aggregations-metric.md +161 -0
  17. package/skills/database/elasticsearch/references/04-aggregations-bucket.md +236 -0
  18. package/skills/database/elasticsearch/references/05-mapping-types.md +134 -0
  19. package/skills/database/elasticsearch/references/06-analyzers.md +187 -0
  20. package/skills/database/elasticsearch/references/07-cluster-ops.md +225 -0
  21. package/skills/database/elasticsearch/references/08-elk-integration.md +170 -0
  22. package/skills/database/mysql/SKILL.md +195 -0
  23. package/skills/database/mysql/examples/01-connection-pool.md +75 -0
  24. package/skills/database/mysql/examples/02-slow-query-optimization.md +98 -0
  25. package/skills/database/mysql/examples/03-master-slave-setup.md +144 -0
  26. package/skills/database/mysql/examples/04-backup-strategy.md +212 -0
  27. package/skills/database/mysql/references/01-functions-string.md +103 -0
  28. package/skills/database/mysql/references/02-functions-date.md +152 -0
  29. package/skills/database/mysql/references/03-functions-aggregate-window.md +167 -0
  30. package/skills/database/mysql/references/04-functions-json.md +129 -0
  31. package/skills/database/mysql/references/05-sql-ddl-types.md +235 -0
  32. package/skills/database/mysql/references/06-index-optimization.md +232 -0
  33. package/skills/database/mysql/references/07-replication-ha.md +213 -0
  34. package/skills/database/mysql/references/08-backup-restore.md +207 -0
  35. package/skills/database/mysql/references/09-advanced-features.md +345 -0
  36. package/skills/database/oracle/LICENSE.txt +202 -0
  37. package/skills/database/oracle/SKILL.md +238 -0
  38. package/skills/database/oracle/examples/01-plsql-procedure.md +90 -0
  39. package/skills/database/oracle/examples/02-awr-analysis.md +99 -0
  40. package/skills/database/oracle/examples/03-rman-backup.md +108 -0
  41. package/skills/database/oracle/examples/04-dataguard-setup.md +146 -0
  42. package/skills/database/oracle/references/01-functions-string.md +91 -0
  43. package/skills/database/oracle/references/02-functions-date.md +71 -0
  44. package/skills/database/oracle/references/03-analytic-functions.md +103 -0
  45. package/skills/database/oracle/references/04-plsql-guide.md +303 -0
  46. package/skills/database/oracle/references/05-performance-tuning.md +164 -0
  47. package/skills/database/oracle/references/06-backup-recovery.md +115 -0
  48. package/skills/database/oracle/references/07-dataguard-rac.md +76 -0
  49. package/skills/database/oracle/references/08-security.md +170 -0
  50. package/skills/database/oracle/references/09-sql-syntax.md +152 -0
  51. package/skills/database/oracle/references/10-features.md +174 -0
  52. package/skills/database/postgresql/LICENSE.txt +202 -0
  53. package/skills/database/postgresql/SKILL.md +182 -0
  54. package/skills/database/postgresql/examples/.gitkeep +0 -0
  55. package/skills/database/postgresql/examples/01-jsonb-query.md +72 -0
  56. package/skills/database/postgresql/examples/02-cte-recursive.md +110 -0
  57. package/skills/database/postgresql/examples/03-performance-tuning.md +114 -0
  58. package/skills/database/postgresql/examples/04-streaming-replication.md +113 -0
  59. package/skills/database/postgresql/references/.gitkeep +0 -0
  60. package/skills/database/postgresql/references/01-functions-string.md +174 -0
  61. package/skills/database/postgresql/references/02-functions-datetime.md +54 -0
  62. package/skills/database/postgresql/references/03-functions-aggregate-window.md +142 -0
  63. package/skills/database/postgresql/references/04-functions-jsonb.md +117 -0
  64. package/skills/database/postgresql/references/05-fulltext-search.md +109 -0
  65. package/skills/database/postgresql/references/06-index-types.md +95 -0
  66. package/skills/database/postgresql/references/07-partition-fdw.md +133 -0
  67. package/skills/database/postgresql/references/08-replication-backup.md +215 -0
  68. package/skills/database/redis/LICENSE.txt +202 -0
  69. package/skills/database/redis/SKILL.md +922 -0
  70. package/skills/database/redis/examples/01-cache-usage.md +104 -0
  71. package/skills/database/redis/examples/02-session-storage.md +72 -0
  72. package/skills/database/redis/examples/03-leaderboard.md +63 -0
  73. package/skills/database/redis/examples/04-redis-cluster-setup.md +70 -0
  74. package/skills/database/redis/examples/05-stream-queue.md +65 -0
  75. package/skills/database/redis/references/command-quick-ref.md +180 -0
  76. package/skills/database/redis/references/commands-admin-key.md +413 -0
  77. package/skills/database/redis/references/commands-set-sorted-advanced.md +539 -0
  78. package/skills/database/redis/references/commands-string-hash-list.md +458 -0
  79. package/skills/database/redis/references/memory-optimization.md +150 -0
  80. package/skills/database/redis/references/redis-conf-production.md +139 -0
  81. package/skills/specflow-approval/SKILL.md +102 -181
  82. package/templates/approval.md +321 -221
@@ -0,0 +1,164 @@
1
+ # 性能调优 — AWR / ASH / ADDM / DBMS_XPLAN
2
+
3
+ ## EXPLAIN PLAN / DBMS_XPLAN
4
+
5
+ ```sql
6
+ -- 生成执行计划
7
+ EXPLAIN PLAN FOR
8
+ SELECT d.department_name, e.last_name, e.salary
9
+ FROM departments d JOIN employees e ON d.department_id = e.department_id
10
+ WHERE e.salary > 10000;
11
+
12
+ -- 查看执行计划
13
+ SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
14
+
15
+ -- 查看实际执行计划(带统计信息)
16
+ SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id => 'abc123', format => 'ALLSTATS LAST'));
17
+
18
+ -- 格式化选项
19
+ SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'BASIC')); -- 基本
20
+ SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'TYPICAL')); -- 典型(默认)
21
+ SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'ALL')); -- 全部
22
+ SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'ADVANCED')); -- 高级(含提示)
23
+
24
+ -- 查找高消耗 SQL
25
+ SELECT sql_id, ROUND(elapsed_time/1000,2) AS elapsed_ms,
26
+ cpu_time, buffer_gets, executions,
27
+ SUBSTR(sql_text, 1, 200) AS sql_text_short
28
+ FROM v$sql
29
+ WHERE elapsed_time > 0 AND executions > 0
30
+ ORDER BY elapsed_time DESC FETCH FIRST 10 ROWS ONLY;
31
+ ```
32
+
33
+ ## AWR(Automatic Workload Repository)
34
+
35
+ ```sql
36
+ -- 生成 AWR 报告(HTML 格式)
37
+ SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML(
38
+ l_dbid => (SELECT dbid FROM v$database),
39
+ l_inst_num => 1,
40
+ l_bid => 100, -- 起始快照 ID
41
+ l_eid => 110, -- 结束快照 ID
42
+ l_options => 0
43
+ ));
44
+
45
+ -- 创建 AWR 快照
46
+ EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();
47
+
48
+ -- 修改 AWR 保留策略(默认 8 天)
49
+ EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(retention => 14400); -- 10天
50
+ EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(interval => 60); -- 间隔 60 分钟
51
+ ```
52
+
53
+ ## ASH(Active Session History)
54
+
55
+ ```sql
56
+ -- 最近 10 分钟的 Top 等待事件
57
+ SELECT event, COUNT(*) AS cnt,
58
+ ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) AS pct
59
+ FROM v$active_session_history
60
+ WHERE sample_time > SYSTIMESTAMP - INTERVAL '10' MINUTE
61
+ GROUP BY event ORDER BY cnt DESC;
62
+
63
+ -- Top SQL(基于 ASH)
64
+ SELECT sql_id, COUNT(*) AS hits,
65
+ ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) AS pct
66
+ FROM v$active_session_history
67
+ WHERE sample_time > SYSTIMESTAMP - INTERVAL '10' MINUTE AND sql_id IS NOT NULL
68
+ GROUP BY sql_id ORDER BY hits DESC FETCH FIRST 5 ROWS ONLY;
69
+ ```
70
+
71
+ ## ADDM(Automatic Database Diagnostic Monitor)
72
+
73
+ ```sql
74
+ DECLARE
75
+ v_task_name VARCHAR2(30);
76
+ BEGIN
77
+ v_task_name := 'MY_ADDM_TASK';
78
+ DBMS_ADDM.ANALYZE_DB(
79
+ task_name => v_task_name,
80
+ begin_snapshot => 100,
81
+ end_snapshot => 110
82
+ );
83
+ END;
84
+ /
85
+ ```
86
+
87
+ ## SQL Tuning Advisor
88
+
89
+ ```sql
90
+ DECLARE
91
+ v_task_name VARCHAR2(30);
92
+ BEGIN
93
+ v_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
94
+ sql_id => 'abc123xyz4567',
95
+ scope => DBMS_SQLTUNE.SCOPE_COMPREHENSIVE,
96
+ time_limit => 300,
97
+ task_name => 'tune_sql_abc123'
98
+ );
99
+ DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => v_task_name);
100
+ END;
101
+ /
102
+
103
+ -- 查看调优建议
104
+ SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK(task_name => 'tune_sql_abc123') FROM DUAL;
105
+
106
+ -- 接受 SQL Profile
107
+ EXEC DBMS_SQLTUNE.ACCEPT_SQL_PROFILE(task_name => 'tune_sql_abc123');
108
+ ```
109
+
110
+ ## DBMS_STATS — 统计信息
111
+
112
+ ```sql
113
+ -- 收集表级统计信息
114
+ EXEC DBMS_STATS.GATHER_TABLE_STATS(
115
+ ownname => 'HR', tabname => 'EMPLOYEES',
116
+ estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
117
+ cascade => TRUE, degree => DBMS_STATS.AUTO_DEGREE,
118
+ method_opt => 'FOR ALL COLUMNS SIZE AUTO'
119
+ );
120
+
121
+ -- 收集模式级统计信息
122
+ EXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'HR', options => 'GATHER AUTO');
123
+
124
+ -- 锁定/解锁统计信息
125
+ EXEC DBMS_STATS.LOCK_TABLE_STATS('HR', 'EMPLOYEES');
126
+ EXEC DBMS_STATS.UNLOCK_TABLE_STATS('HR', 'EMPLOYEES');
127
+
128
+ -- 恢复历史统计信息
129
+ EXEC DBMS_STATS.RESTORE_TABLE_STATS('HR', 'EMPLOYEES', SYSTIMESTAMP - 7);
130
+
131
+ -- 查看统计信息
132
+ SELECT table_name, num_rows, blocks, avg_row_len, last_analyzed
133
+ FROM dba_tab_statistics WHERE owner = 'HR' AND table_name = 'EMPLOYEES';
134
+ ```
135
+
136
+ ## SPM(SQL Plan Management)
137
+
138
+ ```sql
139
+ -- 加载执行计划到 SPM
140
+ DECLARE v_plans_loaded PLS_INTEGER;
141
+ BEGIN
142
+ v_plans_loaded := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id => 'abc123xyz4567');
143
+ END;
144
+ /
145
+
146
+ -- 查看 SPM 基线
147
+ SELECT sql_handle, plan_name, enabled, accepted, fixed FROM dba_sql_plan_baselines;
148
+
149
+ -- 演变计划
150
+ SELECT DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(sql_handle => 'SQL_handle_here', verify => 'YES') FROM DUAL;
151
+
152
+ -- 固定计划
153
+ DECLARE v_fixed PLS_INTEGER;
154
+ BEGIN
155
+ v_fixed := DBMS_SPM.ALTER_SQL_PLAN_BASELINE(
156
+ sql_handle => 'SQL_handle_here', plan_name => 'SQL_PLAN_xxxxx',
157
+ attribute_name => 'FIXED', attribute_value => 'YES');
158
+ END;
159
+ /
160
+
161
+ -- SPM 配置
162
+ ALTER SYSTEM SET optimizer_capture_sql_plan_baselines = FALSE;
163
+ ALTER SYSTEM SET optimizer_use_sql_plan_baselines = TRUE;
164
+ ```
@@ -0,0 +1,115 @@
1
+ # 备份与恢复 — RMAN / EXPDP / IMPDP / 归档
2
+
3
+ ## RMAN 备份
4
+
5
+ ```sql
6
+ -- 连接 RMAN
7
+ -- rman target /
8
+
9
+ -- 全库备份(含归档日志)
10
+ RMAN> BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;
11
+
12
+ -- 增量备份 Level 0(基础)
13
+ RMAN> BACKUP INCREMENTAL LEVEL 0 DATABASE PLUS ARCHIVELOG;
14
+
15
+ -- 增量备份 Level 1(差异)
16
+ RMAN> BACKUP INCREMENTAL LEVEL 1 DATABASE;
17
+
18
+ -- 表空间备份
19
+ RMAN> BACKUP TABLESPACE tbs_app_data;
20
+
21
+ -- 数据文件备份
22
+ RMAN> BACKUP DATAFILE '/u01/oradata/orcl/app_data01.dbf';
23
+
24
+ -- 控制文件/归档日志备份
25
+ RMAN> BACKUP CURRENT CONTROLFILE;
26
+ RMAN> BACKUP ARCHIVELOG ALL DELETE INPUT;
27
+ ```
28
+
29
+ ## RMAN 恢复
30
+
31
+ ```sql
32
+ -- 全库恢复
33
+ RMAN> STARTUP MOUNT;
34
+ RMAN> RESTORE DATABASE;
35
+ RMAN> RECOVER DATABASE;
36
+ RMAN> ALTER DATABASE OPEN;
37
+
38
+ -- 时间点恢复(不完全恢复)
39
+ RMAN> STARTUP MOUNT;
40
+ RMAN> RESTORE DATABASE UNTIL TIME "TO_DATE('2024-08-15 14:00:00','YYYY-MM-DD HH24:MI:SS')";
41
+ RMAN> RECOVER DATABASE UNTIL TIME "...";
42
+ RMAN> ALTER DATABASE OPEN RESETLOGS;
43
+
44
+ -- 表空间恢复
45
+ RMAN> SQL "ALTER TABLESPACE tbs_app_data OFFLINE IMMEDIATE";
46
+ RMAN> RESTORE TABLESPACE tbs_app_data;
47
+ RMAN> RECOVER TABLESPACE tbs_app_data;
48
+ RMAN> SQL "ALTER TABLESPACE tbs_app_data ONLINE";
49
+
50
+ -- 验证备份
51
+ RMAN> RESTORE DATABASE VALIDATE;
52
+
53
+ -- 备份策略配置
54
+ RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
55
+ RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
56
+ RMAN> CONFIGURE BACKUP OPTIMIZATION ON;
57
+ ```
58
+
59
+ ## 逻辑备份(EXPDP / IMPDP)
60
+
61
+ ```sql
62
+ -- 导出全库
63
+ -- expdp system/password DIRECTORY=dp_dir DUMPFILE=full_export.dmp FULL=Y
64
+
65
+ -- 导出指定模式
66
+ -- expdp system/password DIRECTORY=dp_dir DUMPFILE=hr_export.dmp SCHEMAS=HR
67
+
68
+ -- 导出指定表
69
+ -- expdp hr/password DIRECTORY=dp_dir DUMPFILE=emp_export.dmp TABLES=employees,departments
70
+
71
+ -- 条件导出
72
+ -- expdp hr/password DIRECTORY=dp_dir DUMPFILE=emp_dept50.dmp TABLES=employees QUERY='employees:"WHERE department_id = 50"'
73
+
74
+ -- 并行导出
75
+ -- expdp hr/password DIRECTORY=dp_dir DUMPFILE=hr_%U.dmp SCHEMAS=HR PARALLEL=4
76
+
77
+ -- 全库导入
78
+ -- impdp system/password DIRECTORY=dp_dir DUMPFILE=full_export.dmp FULL=Y
79
+
80
+ -- 导入并重映射表空间/模式
81
+ -- impdp system/password DIRECTORY=dp_dir DUMPFILE=hr_export.dmp REMAP_SCHEMAS=HR:HR_NEW REMAP_TABLESPACE=USERS:TBS_APP_DATA
82
+
83
+ -- 跳过已存在对象
84
+ -- impdp hr/password DIRECTORY=dp_dir DUMPFILE=hr_export.dmp TABLE_EXISTS_ACTION=SKIP
85
+ -- TABLE_EXISTS_ACTION: SKIP / APPEND / TRUNCATE / REPLACE
86
+ ```
87
+
88
+ ## 归档日志模式
89
+
90
+ ```sql
91
+ -- 查看当前日志模式
92
+ SELECT log_mode FROM v$database;
93
+
94
+ -- 启用归档日志模式
95
+ SHUTDOWN IMMEDIATE;
96
+ STARTUP MOUNT;
97
+ ALTER DATABASE ARCHIVELOG;
98
+ ALTER DATABASE OPEN;
99
+
100
+ -- 禁用归档日志模式
101
+ SHUTDOWN IMMEDIATE;
102
+ STARTUP MOUNT;
103
+ ALTER DATABASE NOARCHIVELOG;
104
+ ALTER DATABASE OPEN;
105
+
106
+ -- 归档日志管理
107
+ ALTER SYSTEM SET log_archive_dest_1='LOCATION=/u01/archivelog/orcl' SCOPE=BOTH;
108
+ ALTER SYSTEM SET log_archive_format='orcl_%t_%s_%r.arc' SCOPE=SPFILE;
109
+ ALTER SYSTEM SWITCH LOGFILE;
110
+
111
+ -- 查看归档日志
112
+ SELECT * FROM v$archived_log ORDER BY sequence#;
113
+ SELECT * FROM v$recovery_file_dest;
114
+ ALTER SYSTEM SET db_recovery_file_dest_size = 200G;
115
+ ```
@@ -0,0 +1,76 @@
1
+ # Data Guard / RAC
2
+
3
+ ## Data Guard 物理备库
4
+
5
+ ### 主库配置
6
+
7
+ ```sql
8
+ ALTER DATABASE FORCE LOGGING;
9
+ ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(PRIMARY,STANDBY)' SCOPE=BOTH;
10
+ ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/u01/archivelog/orcl VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PRIMARY' SCOPE=BOTH;
11
+ ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby_host:1521/orcl LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=STANDBY' SCOPE=BOTH;
12
+ ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE SCOPE=BOTH;
13
+ ALTER SYSTEM SET FAL_CLIENT='PRIMARY' SCOPE=BOTH;
14
+ ALTER SYSTEM SET FAL_SERVER='STANDBY' SCOPE=BOTH;
15
+ ALTER SYSTEM SET DB_FILE_NAME_CONVERT='/u01/oradata/orcl/','/u02/oradata/orcl/' SCOPE=SPFILE;
16
+ ALTER SYSTEM SET LOG_FILE_NAME_CONVERT='/u01/oradata/orcl/','/u02/oradata/orcl/' SCOPE=SPFILE;
17
+ ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO SCOPE=BOTH;
18
+ ```
19
+
20
+ ### 创建物理备库
21
+
22
+ ```sql
23
+ -- 使用 RMAN DUPLICATE
24
+ -- DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE;
25
+
26
+ -- 备库启用实时应用
27
+ ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
28
+ ```
29
+
30
+ ### 角色切换
31
+
32
+ ```sql
33
+ -- Switchover(计划内切换,不丢数据)
34
+ -- 主库:
35
+ ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY;
36
+ SHUTDOWN IMMEDIATE; STARTUP MOUNT;
37
+ -- 备库:
38
+ ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
39
+ ALTER DATABASE OPEN;
40
+
41
+ -- Failover(故障切换)
42
+ ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
43
+ ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
44
+ ALTER DATABASE OPEN;
45
+
46
+ -- Active Data Guard(备库只读打开)
47
+ ALTER DATABASE OPEN READ ONLY;
48
+ ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
49
+ ```
50
+
51
+ ## RAC(Real Application Clusters)
52
+
53
+ ```sql
54
+ -- 查看 RAC 实例
55
+ SELECT instance_name, instance_number, host_name, status FROM gv$instance;
56
+
57
+ -- 查看 RAC 节点
58
+ SELECT * FROM gv$active_services;
59
+
60
+ -- 查看 ASM 磁盘组
61
+ SELECT * FROM gv$asm_diskgroup;
62
+
63
+ -- 全局等待事件
64
+ SELECT inst_id, event, COUNT(*) AS cnt, ROUND(AVG(wait_time_micro)) AS avg_wait_us
65
+ FROM gv$session WHERE wait_class != 'Idle'
66
+ GROUP BY inst_id, event ORDER BY cnt DESC;
67
+
68
+ -- RAC 序列配置(避免争用)
69
+ CREATE SEQUENCE seq_order_no START WITH 1 CACHE 1000 NOORDER;
70
+
71
+ -- RAC 关键初始化参数
72
+ -- cluster_database = TRUE
73
+ -- instance_number = 1
74
+ -- thread = 1
75
+ -- undo_tablespace = UNDOTBS1
76
+ ```
@@ -0,0 +1,170 @@
1
+ # 安全与权限 — 用户 / FGA / VPD / TDE / 数据脱敏
2
+
3
+ ## 用户 / 角色 / 权限
4
+
5
+ ```sql
6
+ -- 创建用户
7
+ CREATE USER app_user IDENTIFIED BY "StrongPassword123!"
8
+ DEFAULT TABLESPACE tbs_app_data
9
+ TEMPORARY TABLESPACE TEMP
10
+ QUOTA UNLIMITED ON tbs_app_data;
11
+
12
+ -- 创建角色
13
+ CREATE ROLE app_read_role;
14
+ CREATE ROLE app_write_role;
15
+
16
+ -- 系统权限
17
+ GRANT CREATE SESSION TO app_user;
18
+ GRANT CREATE TABLE, CREATE PROCEDURE, CREATE VIEW, CREATE SEQUENCE TO app_user;
19
+
20
+ -- 对象权限
21
+ GRANT SELECT, INSERT, UPDATE, DELETE ON hr.employees TO app_write_role;
22
+ GRANT SELECT ON hr.employees TO app_read_role;
23
+ GRANT EXECUTE ON hr.emp_mgmt TO app_admin_role;
24
+
25
+ -- 角色授予用户
26
+ GRANT app_read_role TO app_user;
27
+
28
+ -- 撤销
29
+ REVOKE DELETE ON hr.employees FROM app_write_role;
30
+
31
+ -- 查看用户权限
32
+ SELECT * FROM dba_sys_privs WHERE grantee = 'APP_USER';
33
+ SELECT * FROM dba_tab_privs WHERE grantee = 'APP_USER';
34
+ SELECT * FROM dba_role_privs WHERE grantee = 'APP_USER';
35
+
36
+ -- 配置文件(Profile)
37
+ CREATE PROFILE app_profile LIMIT
38
+ SESSIONS_PER_USER 5
39
+ IDLE_TIME 30
40
+ CONNECT_TIME 480
41
+ FAILED_LOGIN_ATTEMPTS 5
42
+ PASSWORD_LOCK_TIME 1
43
+ PASSWORD_LIFE_TIME 90
44
+ PASSWORD_GRACE_TIME 7;
45
+
46
+ -- 用户管理
47
+ ALTER USER app_user ACCOUNT LOCK;
48
+ ALTER USER app_user ACCOUNT UNLOCK;
49
+ ALTER USER app_user PASSWORD EXPIRE;
50
+ ```
51
+
52
+ ## FGA(Fine-Grained Auditing)— 细粒度审计
53
+
54
+ ```sql
55
+ -- 创建 FGA 策略(审计高工资访问)
56
+ BEGIN
57
+ DBMS_FGA.ADD_POLICY(
58
+ object_schema => 'HR',
59
+ object_name => 'EMPLOYEES',
60
+ policy_name => 'AUDIT_SALARY_ACCESS',
61
+ audit_condition => 'salary > 10000',
62
+ audit_column => 'SALARY, COMMISSION_PCT',
63
+ enable => TRUE,
64
+ statement_types => 'SELECT, UPDATE',
65
+ audit_trail => DBMS_FGA.XML + DBMS_FGA.EXTENDED
66
+ );
67
+ END;
68
+ /
69
+
70
+ -- 查看 FGA 审计日志
71
+ SELECT timestamp, db_user, object_schema, object_name, sql_text
72
+ FROM dba_fga_audit_trail WHERE object_name = 'EMPLOYEES'
73
+ ORDER BY timestamp DESC;
74
+
75
+ -- 管理 FGA 策略
76
+ BEGIN
77
+ DBMS_FGA.DISABLE_POLICY('HR', 'EMPLOYEES', 'AUDIT_SALARY_ACCESS');
78
+ DBMS_FGA.ENABLE_POLICY('HR', 'EMPLOYEES', 'AUDIT_SALARY_ACCESS');
79
+ DBMS_FGA.DROP_POLICY('HR', 'EMPLOYEES', 'AUDIT_SALARY_ACCESS');
80
+ END;
81
+ /
82
+ ```
83
+
84
+ ## VPD(Virtual Private Database)— 虚拟私有数据库
85
+
86
+ ```sql
87
+ -- 1. 创建策略函数
88
+ CREATE OR REPLACE FUNCTION dept_access_policy(
89
+ p_schema VARCHAR2, p_object VARCHAR2
90
+ ) RETURN VARCHAR2 AS
91
+ v_dept_id NUMBER;
92
+ BEGIN
93
+ IF SYS_CONTEXT('USERENV', 'ISDBA') = 'TRUE' THEN
94
+ RETURN '1=1';
95
+ END IF;
96
+ v_dept_id := SYS_CONTEXT('USER_CTX', 'DEPARTMENT_ID');
97
+ IF v_dept_id IS NOT NULL THEN
98
+ RETURN 'department_id = ' || v_dept_id;
99
+ ELSE
100
+ RETURN '1=0';
101
+ END IF;
102
+ END;
103
+ /
104
+
105
+ -- 2. 应用策略到表
106
+ BEGIN
107
+ DBMS_RLS.ADD_POLICY(
108
+ object_schema => 'HR',
109
+ object_name => 'EMPLOYEES',
110
+ policy_name => 'DEPT_ACCESS_POLICY',
111
+ function_schema => 'HR',
112
+ policy_function => 'dept_access_policy',
113
+ statement_types => 'SELECT, INSERT, UPDATE, DELETE',
114
+ update_check => TRUE,
115
+ enable => TRUE
116
+ );
117
+ END;
118
+ /
119
+
120
+ -- 查看 VPD 策略
121
+ SELECT * FROM dba_policies WHERE object_name = 'EMPLOYEES';
122
+
123
+ -- 移除
124
+ EXEC DBMS_RLS.DROP_POLICY('HR', 'EMPLOYEES', 'DEPT_ACCESS_POLICY');
125
+ ```
126
+
127
+ ## TDE(Transparent Data Encryption)— 透明数据加密
128
+
129
+ ```sql
130
+ -- 打开钱包
131
+ ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "wallet_password";
132
+ ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY "wallet_password" WITH BACKUP;
133
+
134
+ -- 创建加密表空间
135
+ CREATE TABLESPACE tbs_encrypted
136
+ DATAFILE '/u01/oradata/orcl/encrypted01.dbf' SIZE 5G
137
+ ENCRYPTION USING 'AES256'
138
+ DEFAULT STORAGE(ENCRYPT);
139
+
140
+ -- 列级加密
141
+ CREATE TABLE credit_cards (
142
+ card_id NUMBER(10) PRIMARY KEY,
143
+ customer_id NUMBER(10),
144
+ card_number VARCHAR2(16) ENCRYPT USING 'AES256',
145
+ cvv VARCHAR2(4) ENCRYPT,
146
+ expiry_date DATE
147
+ );
148
+ ```
149
+
150
+ ## 数据脱敏(Data Redaction)
151
+
152
+ ```sql
153
+ -- 创建 Redaction Policy
154
+ BEGIN
155
+ DBMS_REDACT.ADD_POLICY(
156
+ object_schema => 'HR',
157
+ object_name => 'CREDIT_CARDS',
158
+ policy_name => 'REDACT_CC_NUM',
159
+ column_name => 'CARD_NUMBER',
160
+ function_type => DBMS_REDACT.PARTIAL,
161
+ function_parameters => 'VVVVVVVVVVVVVVVV,VVVV-XXXX-XXXX-VVVV,*,1,4',
162
+ expression => 'SYS_CONTEXT(''USERENV'', ''SESSION_USER'') != ''APP_ADMIN'''
163
+ );
164
+ END;
165
+ /
166
+
167
+ -- 查看脱敏策略
168
+ SELECT * FROM redaction_policies;
169
+ SELECT * FROM redaction_columns;
170
+ ```
@@ -0,0 +1,152 @@
1
+ # SQL 语法详解(Oracle 特有语法)
2
+
3
+ ## 数据类型
4
+
5
+ | 数据类型 | 说明 | 最大长度 | 业务场景 |
6
+ |---------|------|---------|---------|
7
+ | **VARCHAR2(n)** | 可变长字符串 | 4000B(12c+ 32767) | 用户名、邮箱 |
8
+ | **NVARCHAR2(n)** | Unicode 可变长字符串 | 4000 字符 | 多语言文本 |
9
+ | **CLOB** | 字符大对象 | (4GB-1)*block_size | 文章、JSON |
10
+ | **NUMBER(p,s)** | 数值 | 38 位十进制 | 金额、数量 |
11
+ | **BINARY_FLOAT** | 32位浮点 | ~7位有效数字 | 科学计算 |
12
+ | **BINARY_DOUBLE** | 64位浮点 | ~15位有效数字 | 高精度计算 |
13
+ | **DATE** | 日期时间(精确到秒) | 4712BC~9999AD | 订单时间 |
14
+ | **TIMESTAMP** | 日期时间(精确到纳秒) | 同 DATE + 小数秒 | 高精度时间戳 |
15
+ | **INTERVAL** | 时间间隔 | - | 耗时统计 |
16
+ | **RAW(n)** | 二进制数据 | 2000 字节 | GUID、散列值 |
17
+
18
+ ## DDL
19
+
20
+ ```sql
21
+ -- CREATE TABLE 约束
22
+ CREATE TABLE users (
23
+ user_id NUMBER(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
24
+ username VARCHAR2(50) NOT NULL,
25
+ email VARCHAR2(100) NOT NULL UNIQUE,
26
+ status VARCHAR2(10) DEFAULT 'ACTIVE',
27
+ CONSTRAINT ck_users_status CHECK (status IN ('ACTIVE','INACTIVE','LOCKED'))
28
+ );
29
+
30
+ -- 虚拟列
31
+ CREATE TABLE products (
32
+ product_id NUMBER(10) PRIMARY KEY,
33
+ unit_price NUMBER(10,2),
34
+ quantity NUMBER(10),
35
+ total_value NUMBER(10,2) GENERATED ALWAYS AS (unit_price * quantity) VIRTUAL
36
+ );
37
+
38
+ -- 序列
39
+ CREATE SEQUENCE seq_orders START WITH 10000 INCREMENT BY 1 CACHE 100 NOORDER;
40
+
41
+ -- 同义词
42
+ CREATE SYNONYM emp FOR hr.employees;
43
+ CREATE PUBLIC SYNONYM dept FOR hr.departments;
44
+ ```
45
+
46
+ ## DML
47
+
48
+ ```sql
49
+ -- MERGE(UPSERT)
50
+ MERGE INTO products p USING staging_products s ON (p.product_id = s.product_id)
51
+ WHEN MATCHED THEN UPDATE SET p.price = s.price, p.updated_at = SYSDATE
52
+ WHEN NOT MATCHED THEN INSERT (product_id, product_name, price) VALUES (s.product_id, s.product_name, s.price);
53
+
54
+ -- INSERT ALL(多表插入)
55
+ INSERT ALL
56
+ WHEN salary > 10000 THEN INTO emp_active (employee_id, salary)
57
+ WHEN salary <= 10000 THEN INTO emp_archive (employee_id, salary)
58
+ SELECT employee_id, salary FROM employees;
59
+
60
+ -- CONNECT BY(层次查询)
61
+ SELECT employee_id, last_name, LEVEL,
62
+ SYS_CONNECT_BY_PATH(last_name, ' -> ') AS path
63
+ FROM employees
64
+ START WITH manager_id IS NULL
65
+ CONNECT BY PRIOR employee_id = manager_id
66
+ ORDER SIBLINGS BY last_name;
67
+
68
+ -- 生成日期序列
69
+ SELECT DATE '2024-01-01' + LEVEL - 1 AS day FROM DUAL
70
+ CONNECT BY LEVEL <= 31;
71
+
72
+ -- FLASHBACK QUERY
73
+ SELECT * FROM employees AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '15' MINUTE);
74
+ SELECT * FROM employees AS OF SCN 1234567;
75
+ ```
76
+
77
+ ## SELECT 特有语法
78
+
79
+ ```sql
80
+ -- WITH(CTE)
81
+ WITH dept_salary AS (
82
+ SELECT department_id, SUM(salary) AS total_salary FROM employees GROUP BY department_id
83
+ )
84
+ SELECT * FROM dept_salary ORDER BY total_salary DESC;
85
+
86
+ -- 递归 CTE
87
+ WITH org_tree(employee_id, manager_id, last_name, lvl) AS (
88
+ SELECT employee_id, manager_id, last_name, 1 FROM employees WHERE manager_id IS NULL
89
+ UNION ALL
90
+ SELECT e.employee_id, e.manager_id, e.last_name, t.lvl + 1
91
+ FROM employees e JOIN org_tree t ON e.manager_id = t.employee_id
92
+ )
93
+ SELECT * FROM org_tree;
94
+
95
+ -- PIVOT(行转列)
96
+ SELECT * FROM (
97
+ SELECT department_id, EXTRACT(MONTH FROM hire_date) AS hire_month FROM employees
98
+ ) PIVOT (
99
+ COUNT(*) FOR hire_month IN (1 AS JAN, 2 AS FEB, 3 AS MAR)
100
+ );
101
+
102
+ -- LISTAGG(列转字符串)
103
+ SELECT department_id,
104
+ LISTAGG(last_name, ', ') WITHIN GROUP (ORDER BY hire_date) AS emp_list
105
+ FROM employees GROUP BY department_id;
106
+ -- 19c+ 支持超长处理
107
+ LISTAGG(last_name, ', ' ON OVERFLOW TRUNCATE '...' WITH COUNT)
108
+
109
+ -- MODEL 子句
110
+ SELECT region, product, year, sales FROM sales_data
111
+ MODEL PARTITION BY (region) DIMENSION BY (product, year) MEASURES (sales)
112
+ RULES ( sales['TOTAL',2024] = sales['TOTAL',2023] * 1.1 );
113
+
114
+ -- MATCH_RECOGNIZE(12c+ 模式匹配)
115
+ SELECT * FROM stock_prices
116
+ MATCH_RECOGNIZE (
117
+ PARTITION BY symbol ORDER BY trade_date
118
+ MEASURES FIRST(price) AS start_price, LAST(price) AS end_price
119
+ ONE ROW PER MATCH PATTERN (up{3,})
120
+ DEFINE up AS price > PREV(price)
121
+ );
122
+ ```
123
+
124
+ ## 伪列
125
+
126
+ | 伪列 | 说明 | 使用场景 |
127
+ |------|------|---------|
128
+ | **ROWNUM** | 行号(先筛选后排序) | Top-N、分页 |
129
+ | **ROWID** | 物理行地址 | 最快行定位 |
130
+ | **LEVEL** | 层次查询层级 | CONNECT BY |
131
+ | **CONNECT_BY_ISCYCLE** | 循环检测 | 层次查询 |
132
+ | **CONNECT_BY_ISLEAF** | 叶子节点 | 层次查询 |
133
+ | **ORA_ROWSCN** | 行最后修改 SCN | 数据变更检测 |
134
+
135
+ ```sql
136
+ -- ROWNUM 正确用法
137
+ SELECT * FROM (SELECT * FROM employees ORDER BY salary DESC) WHERE ROWNUM <= 10;
138
+ -- 12c+ 推荐
139
+ SELECT * FROM employees ORDER BY salary DESC FETCH FIRST 10 ROWS ONLY;
140
+
141
+ -- ROWID 最快行定位
142
+ SELECT * FROM employees WHERE ROWID = 'AAAR3qAAEAAAACvAAA';
143
+ ```
144
+
145
+ ## 集合操作
146
+
147
+ ```sql
148
+ -- UNION / UNION ALL / INTERSECT / MINUS
149
+ SELECT department_id FROM departments
150
+ MINUS
151
+ SELECT DISTINCT department_id FROM employees; -- 没有员工的部门
152
+ ```