universal-dev-standards 5.0.0-rc.8 → 5.0.0
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/bin/uds.js +5 -3
- package/bundled/ai/standards/acceptance-criteria-traceability.ai.yaml +178 -0
- package/bundled/ai/standards/agent-dispatch.ai.yaml +69 -0
- package/bundled/ai/standards/ai-command-behavior.ai.yaml +45 -0
- package/bundled/ai/standards/api-design-standards.ai.yaml +192 -0
- package/bundled/ai/standards/branch-completion.ai.yaml +82 -0
- package/bundled/ai/standards/change-batching-standards.ai.yaml +195 -0
- package/bundled/ai/standards/database-standards.ai.yaml +220 -0
- package/bundled/ai/standards/error-codes.ai.yaml +37 -2
- package/bundled/ai/standards/git-worktree.ai.yaml +77 -0
- package/bundled/ai/standards/logging.ai.yaml +21 -2
- package/bundled/ai/standards/model-selection.ai.yaml +81 -0
- package/bundled/ai/standards/pipeline-integration-standards.ai.yaml +184 -0
- package/bundled/ai/standards/systematic-debugging.ai.yaml +73 -0
- package/bundled/ai/standards/verification-evidence.ai.yaml +84 -0
- package/bundled/ai/standards/workflow-enforcement.ai.yaml +253 -0
- package/bundled/core/acceptance-criteria-traceability.md +293 -0
- package/bundled/core/agent-dispatch.md +149 -0
- package/bundled/core/ai-command-behavior.md +239 -0
- package/bundled/core/api-design-standards.md +938 -0
- package/bundled/core/branch-completion.md +158 -0
- package/bundled/core/change-batching-standards.md +257 -0
- package/bundled/core/checkin-standards.md +43 -6
- package/bundled/core/database-standards.md +828 -0
- package/bundled/core/error-code-standards.md +228 -2
- package/bundled/core/forward-derivation-standards.md +54 -2
- package/bundled/core/git-worktree.md +131 -0
- package/bundled/core/model-selection.md +153 -0
- package/bundled/core/pipeline-integration-standards.md +230 -0
- package/bundled/core/systematic-debugging.md +156 -0
- package/bundled/core/testing-standards.md +49 -39
- package/bundled/core/verification-evidence.md +172 -0
- package/bundled/core/workflow-enforcement.md +132 -0
- package/bundled/locales/zh-CN/CLAUDE.md +2 -2
- package/bundled/locales/zh-CN/README.md +4 -4
- package/bundled/locales/zh-CN/SECURITY.md +92 -0
- package/bundled/locales/zh-CN/core/acceptance-criteria-traceability.md +301 -0
- package/bundled/locales/zh-CN/core/acceptance-test-driven-development.md +47 -0
- package/bundled/locales/zh-CN/core/accessibility-standards.md +124 -0
- package/bundled/locales/zh-CN/core/agent-dispatch.md +113 -0
- package/bundled/locales/zh-CN/core/ai-agreement-standards.md +103 -0
- package/bundled/locales/zh-CN/core/ai-command-behavior.md +247 -0
- package/bundled/locales/zh-CN/core/api-design-standards.md +946 -0
- package/bundled/locales/zh-CN/core/behavior-driven-development.md +48 -0
- package/bundled/locales/zh-CN/core/branch-completion.md +112 -0
- package/bundled/locales/zh-CN/core/change-batching-standards.md +265 -0
- package/bundled/locales/zh-CN/core/checkin-standards.md +43 -5
- package/bundled/locales/zh-CN/core/context-aware-loading.md +106 -0
- package/bundled/locales/zh-CN/core/database-standards.md +836 -0
- package/bundled/locales/zh-CN/core/deployment-standards.md +80 -0
- package/bundled/locales/zh-CN/core/error-code-standards.md +2 -2
- package/bundled/locales/zh-CN/core/forward-derivation-standards.md +493 -0
- package/bundled/locales/zh-CN/core/git-worktree.md +101 -0
- package/bundled/locales/zh-CN/core/model-selection.md +112 -0
- package/bundled/locales/zh-CN/core/performance-standards.md +104 -0
- package/bundled/locales/zh-CN/core/pipeline-integration-standards.md +238 -0
- package/bundled/locales/zh-CN/core/project-context-memory.md +124 -0
- package/bundled/locales/zh-CN/core/requirement-engineering.md +49 -0
- package/bundled/locales/zh-CN/core/security-standards.md +100 -0
- package/bundled/locales/zh-CN/core/systematic-debugging.md +106 -0
- package/bundled/locales/zh-CN/core/test-governance.md +116 -0
- package/bundled/locales/zh-CN/core/testing-standards.md +392 -156
- package/bundled/locales/zh-CN/core/verification-evidence.md +118 -0
- package/bundled/locales/zh-CN/core/virtual-organization-standards.md +104 -0
- package/bundled/locales/zh-CN/core/workflow-enforcement.md +132 -0
- package/bundled/locales/zh-CN/docs/CHEATSHEET.md +27 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +9 -1
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +37 -9
- package/bundled/locales/zh-CN/docs/USER-MANUAL.md +652 -0
- package/bundled/locales/zh-CN/integrations/github-copilot/copilot-instructions.md +1 -1
- package/bundled/locales/zh-CN/integrations/openspec/AGENTS.md +29 -4
- package/bundled/locales/zh-CN/integrations/spec-kit/AGENTS.md +143 -72
- package/bundled/locales/zh-CN/skills/ac-coverage-assistant/SKILL.md +126 -0
- package/bundled/locales/zh-CN/skills/api-design-assistant/SKILL.md +100 -0
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/SKILL.md +119 -0
- package/bundled/locales/zh-CN/skills/ci-cd-assistant/SKILL.md +82 -0
- package/bundled/locales/zh-CN/skills/commands/ac-coverage.md +97 -0
- package/bundled/locales/zh-CN/skills/commands/api-design.md +94 -0
- package/bundled/locales/zh-CN/skills/commands/atdd.md +163 -0
- package/bundled/locales/zh-CN/skills/commands/audit.md +77 -0
- package/bundled/locales/zh-CN/skills/commands/bdd.md +1 -1
- package/bundled/locales/zh-CN/skills/commands/brainstorm.md +87 -0
- package/bundled/locales/zh-CN/skills/commands/changelog.md +63 -0
- package/bundled/locales/zh-CN/skills/commands/check.md +219 -0
- package/bundled/locales/zh-CN/skills/commands/checkin.md +61 -0
- package/bundled/locales/zh-CN/skills/commands/ci-cd.md +77 -0
- package/bundled/locales/zh-CN/skills/commands/commit.md +81 -0
- package/bundled/locales/zh-CN/skills/commands/config.md +207 -0
- package/bundled/locales/zh-CN/skills/commands/coverage.md +74 -0
- package/bundled/locales/zh-CN/skills/commands/database.md +78 -0
- package/bundled/locales/zh-CN/skills/commands/derive-all.md +58 -0
- package/bundled/locales/zh-CN/skills/commands/derive-atdd.md +54 -0
- package/bundled/locales/zh-CN/skills/commands/derive-bdd.md +53 -0
- package/bundled/locales/zh-CN/skills/commands/derive-tdd.md +54 -0
- package/bundled/locales/zh-CN/skills/commands/derive.md +78 -0
- package/bundled/locales/zh-CN/skills/commands/dev-workflow.md +119 -0
- package/bundled/locales/zh-CN/skills/commands/discover.md +86 -0
- package/bundled/locales/zh-CN/skills/commands/docgen.md +67 -0
- package/bundled/locales/zh-CN/skills/commands/docs.md +65 -0
- package/bundled/locales/zh-CN/skills/commands/durable.md +87 -0
- package/bundled/locales/zh-CN/skills/commands/guide.md +52 -0
- package/bundled/locales/zh-CN/skills/commands/incident.md +92 -0
- package/bundled/locales/zh-CN/skills/commands/init.md +272 -0
- package/bundled/locales/zh-CN/skills/commands/methodology.md +1 -1
- package/bundled/locales/zh-CN/skills/commands/metrics.md +73 -0
- package/bundled/locales/zh-CN/skills/commands/migrate.md +92 -0
- package/bundled/locales/zh-CN/skills/commands/pr.md +80 -0
- package/bundled/locales/zh-CN/skills/commands/refactor.md +1 -1
- package/bundled/locales/zh-CN/skills/commands/release.md +62 -0
- package/bundled/locales/zh-CN/skills/commands/requirement.md +54 -0
- package/bundled/locales/zh-CN/skills/commands/reverse-bdd.md +47 -0
- package/bundled/locales/zh-CN/skills/commands/reverse-sdd.md +51 -0
- package/bundled/locales/zh-CN/skills/commands/reverse-tdd.md +51 -0
- package/bundled/locales/zh-CN/skills/commands/reverse.md +63 -0
- package/bundled/locales/zh-CN/skills/commands/review.md +50 -0
- package/bundled/locales/zh-CN/skills/commands/scan.md +76 -0
- package/bundled/locales/zh-CN/skills/commands/sdd-retro.md +40 -0
- package/bundled/locales/zh-CN/skills/commands/sdd.md +379 -0
- package/bundled/locales/zh-CN/skills/commands/security.md +75 -0
- package/bundled/locales/zh-CN/skills/commands/tdd.md +111 -0
- package/bundled/locales/zh-CN/skills/commands/update.md +337 -0
- package/bundled/locales/zh-CN/skills/commit-standards/SKILL.md +1 -2
- package/bundled/locales/zh-CN/skills/database-assistant/SKILL.md +97 -0
- package/bundled/locales/zh-CN/skills/dev-workflow-guide/SKILL.md +145 -0
- package/bundled/locales/zh-CN/skills/durable-execution-assistant/SKILL.md +84 -0
- package/bundled/locales/zh-CN/skills/incident-response-assistant/SKILL.md +107 -0
- package/bundled/locales/zh-CN/skills/metrics-dashboard-assistant/SKILL.md +67 -0
- package/bundled/locales/zh-CN/skills/migration-assistant/SKILL.md +77 -0
- package/bundled/locales/zh-CN/skills/pr-automation-assistant/SKILL.md +90 -0
- package/bundled/locales/zh-CN/skills/security-assistant/SKILL.md +79 -0
- package/bundled/locales/zh-CN/skills/security-scan-assistant/SKILL.md +72 -0
- package/bundled/locales/zh-CN/skills/spec-driven-dev/SKILL.md +73 -10
- package/bundled/locales/zh-CN/skills/spec-driven-dev/guide.md +267 -122
- package/bundled/locales/zh-TW/CLAUDE.md +2 -2
- package/bundled/locales/zh-TW/README.md +4 -4
- package/bundled/locales/zh-TW/SECURITY.md +92 -0
- package/bundled/locales/zh-TW/core/acceptance-criteria-traceability.md +301 -0
- package/bundled/locales/zh-TW/core/acceptance-test-driven-development.md +47 -0
- package/bundled/locales/zh-TW/core/accessibility-standards.md +84 -0
- package/bundled/locales/zh-TW/core/agent-dispatch.md +89 -0
- package/bundled/locales/zh-TW/core/ai-agreement-standards.md +87 -0
- package/bundled/locales/zh-TW/core/ai-command-behavior.md +247 -0
- package/bundled/locales/zh-TW/core/api-design-standards.md +946 -0
- package/bundled/locales/zh-TW/core/behavior-driven-development.md +63 -0
- package/bundled/locales/zh-TW/core/branch-completion.md +76 -0
- package/bundled/locales/zh-TW/core/change-batching-standards.md +265 -0
- package/bundled/locales/zh-TW/core/checkin-standards.md +39 -5
- package/bundled/locales/zh-TW/core/context-aware-loading.md +86 -0
- package/bundled/locales/zh-TW/core/database-standards.md +836 -0
- package/bundled/locales/zh-TW/core/deployment-standards.md +66 -0
- package/bundled/locales/zh-TW/core/error-code-standards.md +230 -4
- package/bundled/locales/zh-TW/core/forward-derivation-standards.md +62 -2
- package/bundled/locales/zh-TW/core/git-worktree.md +104 -0
- package/bundled/locales/zh-TW/core/model-selection.md +83 -0
- package/bundled/locales/zh-TW/core/performance-standards.md +84 -0
- package/bundled/locales/zh-TW/core/pipeline-integration-standards.md +238 -0
- package/bundled/locales/zh-TW/core/project-context-memory.md +79 -0
- package/bundled/locales/zh-TW/core/requirement-engineering.md +79 -0
- package/bundled/locales/zh-TW/core/security-standards.md +74 -0
- package/bundled/locales/zh-TW/core/systematic-debugging.md +95 -0
- package/bundled/locales/zh-TW/core/test-governance.md +88 -0
- package/bundled/locales/zh-TW/core/testing-standards.md +309 -86
- package/bundled/locales/zh-TW/core/verification-evidence.md +94 -0
- package/bundled/locales/zh-TW/core/virtual-organization-standards.md +88 -0
- package/bundled/locales/zh-TW/core/workflow-enforcement.md +132 -0
- package/bundled/locales/zh-TW/docs/CHEATSHEET.md +27 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +9 -1
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +37 -9
- package/bundled/locales/zh-TW/docs/USER-MANUAL.md +652 -0
- package/bundled/locales/zh-TW/integrations/github-copilot/copilot-instructions.md +1 -1
- package/bundled/locales/zh-TW/integrations/openspec/AGENTS.md +29 -4
- package/bundled/locales/zh-TW/integrations/spec-kit/AGENTS.md +142 -71
- package/bundled/locales/zh-TW/skills/ac-coverage-assistant/SKILL.md +127 -0
- package/bundled/locales/zh-TW/skills/ai-friendly-architecture/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/ai-instruction-standards/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/api-design-assistant/SKILL.md +97 -0
- package/bundled/locales/zh-TW/skills/atdd-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/audit-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/bdd-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/changelog-guide/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/checkin-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/ci-cd-assistant/SKILL.md +79 -0
- package/bundled/locales/zh-TW/skills/code-review-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/commands/ac-coverage.md +95 -0
- package/bundled/locales/zh-TW/skills/commands/api-design.md +92 -0
- package/bundled/locales/zh-TW/skills/commands/atdd.md +167 -0
- package/bundled/locales/zh-TW/skills/commands/audit.md +75 -0
- package/bundled/locales/zh-TW/skills/commands/bdd.md +1 -1
- package/bundled/locales/zh-TW/skills/commands/brainstorm.md +91 -0
- package/bundled/locales/zh-TW/skills/commands/changelog.md +67 -0
- package/bundled/locales/zh-TW/skills/commands/check.md +223 -0
- package/bundled/locales/zh-TW/skills/commands/checkin.md +65 -0
- package/bundled/locales/zh-TW/skills/commands/ci-cd.md +75 -0
- package/bundled/locales/zh-TW/skills/commands/commit.md +85 -0
- package/bundled/locales/zh-TW/skills/commands/config.md +211 -0
- package/bundled/locales/zh-TW/skills/commands/coverage.md +78 -0
- package/bundled/locales/zh-TW/skills/commands/database.md +76 -0
- package/bundled/locales/zh-TW/skills/commands/derive-all.md +62 -0
- package/bundled/locales/zh-TW/skills/commands/derive-atdd.md +58 -0
- package/bundled/locales/zh-TW/skills/commands/derive-bdd.md +54 -0
- package/bundled/locales/zh-TW/skills/commands/derive-tdd.md +55 -0
- package/bundled/locales/zh-TW/skills/commands/derive.md +79 -0
- package/bundled/locales/zh-TW/skills/commands/dev-workflow.md +120 -0
- package/bundled/locales/zh-TW/skills/commands/discover.md +87 -0
- package/bundled/locales/zh-TW/skills/commands/docgen.md +68 -0
- package/bundled/locales/zh-TW/skills/commands/docs.md +66 -0
- package/bundled/locales/zh-TW/skills/commands/durable.md +85 -0
- package/bundled/locales/zh-TW/skills/commands/guide.md +51 -0
- package/bundled/locales/zh-TW/skills/commands/incident.md +90 -0
- package/bundled/locales/zh-TW/skills/commands/init.md +273 -0
- package/bundled/locales/zh-TW/skills/commands/methodology.md +1 -1
- package/bundled/locales/zh-TW/skills/commands/metrics.md +71 -0
- package/bundled/locales/zh-TW/skills/commands/migrate.md +90 -0
- package/bundled/locales/zh-TW/skills/commands/pr.md +78 -0
- package/bundled/locales/zh-TW/skills/commands/refactor.md +1 -1
- package/bundled/locales/zh-TW/skills/commands/release.md +63 -0
- package/bundled/locales/zh-TW/skills/commands/requirement.md +61 -0
- package/bundled/locales/zh-TW/skills/commands/reverse-bdd.md +54 -0
- package/bundled/locales/zh-TW/skills/commands/reverse-sdd.md +58 -0
- package/bundled/locales/zh-TW/skills/commands/reverse-tdd.md +58 -0
- package/bundled/locales/zh-TW/skills/commands/reverse.md +70 -0
- package/bundled/locales/zh-TW/skills/commands/review.md +57 -0
- package/bundled/locales/zh-TW/skills/commands/scan.md +74 -0
- package/bundled/locales/zh-TW/skills/commands/sdd-retro.md +47 -0
- package/bundled/locales/zh-TW/skills/commands/sdd.md +362 -0
- package/bundled/locales/zh-TW/skills/commands/security.md +73 -0
- package/bundled/locales/zh-TW/skills/commands/tdd.md +115 -0
- package/bundled/locales/zh-TW/skills/commands/update.md +326 -0
- package/bundled/locales/zh-TW/skills/commit-standards/SKILL.md +2 -6
- package/bundled/locales/zh-TW/skills/database-assistant/SKILL.md +94 -0
- package/bundled/locales/zh-TW/skills/dev-workflow-guide/SKILL.md +140 -0
- package/bundled/locales/zh-TW/skills/docs-generator/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/documentation-guide/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/durable-execution-assistant/SKILL.md +81 -0
- package/bundled/locales/zh-TW/skills/error-code-guide/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/forward-derivation/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/git-workflow-guide/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/incident-response-assistant/SKILL.md +104 -0
- package/bundled/locales/zh-TW/skills/logging-guide/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/methodology-system/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/metrics-dashboard-assistant/SKILL.md +64 -0
- package/bundled/locales/zh-TW/skills/migration-assistant/SKILL.md +74 -0
- package/bundled/locales/zh-TW/skills/pr-automation-assistant/SKILL.md +87 -0
- package/bundled/locales/zh-TW/skills/project-discovery/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/refactoring-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/release-standards/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/requirement-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/reverse-engineer/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/security-assistant/SKILL.md +76 -0
- package/bundled/locales/zh-TW/skills/security-scan-assistant/SKILL.md +69 -0
- package/bundled/locales/zh-TW/skills/spec-driven-dev/SKILL.md +74 -14
- package/bundled/locales/zh-TW/skills/spec-driven-dev/guide.md +243 -98
- package/bundled/locales/zh-TW/skills/tdd-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/test-coverage-assistant/SKILL.md +1 -4
- package/bundled/locales/zh-TW/skills/testing-guide/SKILL.md +1 -5
- package/bundled/skills/README.md +11 -0
- package/bundled/skills/ac-coverage-assistant/SKILL.md +127 -0
- package/bundled/skills/ai-collaboration-standards/SKILL.md +10 -0
- package/bundled/skills/ai-friendly-architecture/SKILL.md +10 -0
- package/bundled/skills/ai-instruction-standards/SKILL.md +10 -0
- package/bundled/skills/api-design-assistant/SKILL.md +119 -0
- package/bundled/skills/atdd-assistant/SKILL.md +7 -0
- package/bundled/skills/bdd-assistant/SKILL.md +7 -0
- package/bundled/skills/brainstorm-assistant/SKILL.md +7 -0
- package/bundled/skills/checkin-assistant/SKILL.md +7 -0
- package/bundled/skills/ci-cd-assistant/SKILL.md +97 -0
- package/bundled/skills/code-review-assistant/SKILL.md +7 -0
- package/bundled/skills/commands/README.md +70 -0
- package/bundled/skills/commands/ac-coverage.md +135 -0
- package/bundled/skills/commands/api-design.md +86 -0
- package/bundled/skills/commands/atdd.md +69 -0
- package/bundled/skills/commands/audit.md +69 -0
- package/bundled/skills/commands/bdd.md +101 -0
- package/bundled/skills/commands/brainstorm.md +45 -0
- package/bundled/skills/commands/changelog.md +34 -0
- package/bundled/skills/commands/check.md +52 -1
- package/bundled/skills/commands/checkin.md +46 -0
- package/bundled/skills/commands/ci-cd.md +69 -0
- package/bundled/skills/commands/commit.md +79 -0
- package/bundled/skills/commands/config.md +48 -0
- package/bundled/skills/commands/coverage.md +53 -0
- package/bundled/skills/commands/database.md +70 -0
- package/bundled/skills/commands/derive-all.md +40 -0
- package/bundled/skills/commands/derive-atdd.md +33 -0
- package/bundled/skills/commands/derive-bdd.md +39 -0
- package/bundled/skills/commands/derive-tdd.md +40 -0
- package/bundled/skills/commands/derive.md +47 -0
- package/bundled/skills/commands/dev-workflow.md +104 -7
- package/bundled/skills/commands/discover.md +39 -0
- package/bundled/skills/commands/docgen.md +35 -0
- package/bundled/skills/commands/docs.md +40 -0
- package/bundled/skills/commands/durable.md +79 -0
- package/bundled/skills/commands/incident.md +84 -0
- package/bundled/skills/commands/init.md +55 -0
- package/bundled/skills/commands/methodology.md +72 -0
- package/bundled/skills/commands/metrics.md +65 -0
- package/bundled/skills/commands/migrate.md +84 -0
- package/bundled/skills/commands/pr.md +72 -0
- package/bundled/skills/commands/refactor.md +51 -0
- package/bundled/skills/commands/release.md +60 -0
- package/bundled/skills/commands/requirement.md +38 -0
- package/bundled/skills/commands/reverse-bdd.md +34 -0
- package/bundled/skills/commands/reverse-sdd.md +42 -0
- package/bundled/skills/commands/reverse-tdd.md +40 -0
- package/bundled/skills/commands/reverse.md +41 -0
- package/bundled/skills/commands/review.md +39 -0
- package/bundled/skills/commands/scan.md +68 -0
- package/bundled/skills/commands/sdd-retro.md +48 -0
- package/bundled/skills/commands/sdd.md +220 -0
- package/bundled/skills/commands/security.md +67 -0
- package/bundled/skills/commands/tdd.md +101 -0
- package/bundled/skills/commands/update.md +61 -0
- package/bundled/skills/commit-standards/SKILL.md +8 -2
- package/bundled/skills/database-assistant/SKILL.md +118 -0
- package/bundled/skills/dev-workflow-guide/SKILL.md +53 -7
- package/bundled/skills/dev-workflow-guide/workflow-phases.md +24 -0
- package/bundled/skills/durable-execution-assistant/SKILL.md +116 -0
- package/bundled/skills/forward-derivation/SKILL.md +7 -0
- package/bundled/skills/incident-response-assistant/SKILL.md +132 -0
- package/bundled/skills/methodology-system/SKILL.md +24 -2
- package/bundled/skills/metrics-dashboard-assistant/SKILL.md +109 -0
- package/bundled/skills/migration-assistant/SKILL.md +119 -0
- package/bundled/skills/pr-automation-assistant/SKILL.md +114 -0
- package/bundled/skills/project-discovery/SKILL.md +7 -0
- package/bundled/skills/refactoring-assistant/SKILL.md +7 -0
- package/bundled/skills/release-standards/SKILL.md +7 -0
- package/bundled/skills/requirement-assistant/SKILL.md +7 -0
- package/bundled/skills/reverse-engineer/SKILL.md +7 -0
- package/bundled/skills/security-assistant/SKILL.md +105 -0
- package/bundled/skills/security-scan-assistant/SKILL.md +96 -0
- package/bundled/skills/spec-driven-dev/SKILL.md +84 -4
- package/bundled/skills/spec-driven-dev/guide.md +156 -22
- package/bundled/skills/tdd-assistant/SKILL.md +7 -0
- package/bundled/skills/test-coverage-assistant/SKILL.md +11 -0
- package/bundled/skills/testing-guide/SKILL.md +23 -0
- package/package.json +1 -1
- package/src/commands/check.js +154 -8
- package/src/commands/config.js +231 -104
- package/src/commands/init.js +23 -3
- package/src/commands/update.js +250 -25
- package/src/config/ai-agent-paths.js +16 -0
- package/src/config/workflow-definitions.js +184 -0
- package/src/core/constants.js +6 -0
- package/src/flows/init-flow.js +23 -6
- package/src/i18n/messages.js +51 -3
- package/src/installers/integration-installer.js +67 -2
- package/src/installers/manifest-installer.js +1 -0
- package/src/installers/standards-installer.js +3 -2
- package/src/prompts/init.js +50 -3
- package/src/reconciler/manifest-migrator.js +2 -2
- package/src/reconciler/plan-executor.js +11 -0
- package/src/utils/integration-generator.js +327 -14
- package/src/utils/workflow-gate.js +292 -0
- package/standards-registry.json +160 -5
|
@@ -0,0 +1,836 @@
|
|
|
1
|
+
---
|
|
2
|
+
source: ../../../core/database-standards.md
|
|
3
|
+
source_version: 1.0.0
|
|
4
|
+
translation_version: 1.0.0
|
|
5
|
+
last_synced: 2026-03-18
|
|
6
|
+
status: current
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# 資料庫標準
|
|
10
|
+
|
|
11
|
+
> **語言**: [English](../../../core/database-standards.md) | 繁體中文
|
|
12
|
+
|
|
13
|
+
> 版本: 1.0.0 | 最後更新: 2026-03-18
|
|
14
|
+
|
|
15
|
+
**適用性**: 所有軟體專案
|
|
16
|
+
**範圍**: universal
|
|
17
|
+
**產業標準**: ISO/IEC 9075 (SQL)、ACID 特性、BASE 定理
|
|
18
|
+
**參考資源**: [use-the-index-luke.com](https://use-the-index-luke.com/)、[sqlstyle.guide](https://www.sqlstyle.guide/)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 目的
|
|
23
|
+
|
|
24
|
+
本標準定義資料庫設計、查詢、遷移與維運的指導方針,涵蓋關聯式與非關聯式資料庫。包含 Schema 設計原則、索引策略、遷移工作流程、查詢最佳化、交易管理與資料完整性 — 確保資料庫具備高效能、可維護且安全的特性。
|
|
25
|
+
|
|
26
|
+
**參考標準**:
|
|
27
|
+
- [ISO/IEC 9075 — SQL 標準](https://www.iso.org/standard/76583.html)
|
|
28
|
+
- [Use The Index, Luke — SQL 索引與調校](https://use-the-index-luke.com/)
|
|
29
|
+
- [Martin Fowler — 演進式資料庫設計](https://martinfowler.com/articles/evodb.html)
|
|
30
|
+
- [Designing Data-Intensive Applications (Martin Kleppmann)](https://dataintensive.net/)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 核心原則
|
|
35
|
+
|
|
36
|
+
| 原則 | 說明 |
|
|
37
|
+
|------|------|
|
|
38
|
+
| **資料完整性優先** | 約束、驗證與參照完整性在資料庫層級強制執行,而非僅在應用程式碼 |
|
|
39
|
+
| **Schema 即程式碼** | 資料庫 Schema 透過遷移腳本進行版本控制且可重現 |
|
|
40
|
+
| **最小權限** | 資料庫帳號使用其功能所需的最低權限 |
|
|
41
|
+
| **先量測再調校** | 使用 EXPLAIN 計畫與指標後再進行最佳化;避免過早最佳化 |
|
|
42
|
+
| **縱深防禦** | 在多個層級使用加密、遮罩與存取控制來保護敏感資料 |
|
|
43
|
+
| **向後相容** | Schema 變更必須在部署視窗期間維持向後相容 |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Schema 設計原則
|
|
48
|
+
|
|
49
|
+
### 正規化
|
|
50
|
+
|
|
51
|
+
套用正規化以消除冗餘並確保資料完整性。以第三正規形式(3NF)作為交易系統的基準。
|
|
52
|
+
|
|
53
|
+
| 正規形式 | 規則 | 違反範例 |
|
|
54
|
+
|----------|------|----------|
|
|
55
|
+
| **1NF** | 僅原子值;無重複群組 | 單一欄位中 `tags = "java,python,go"` |
|
|
56
|
+
| **2NF** | 1NF + 複合鍵無部分相依 | 非鍵欄位僅依賴複合主鍵的一部分 |
|
|
57
|
+
| **3NF** | 2NF + 無遞移相依 | `order.customer_name` 透過 `customer_id` 從 `customer.name` 衍生 |
|
|
58
|
+
|
|
59
|
+
### 反正規化決策矩陣
|
|
60
|
+
|
|
61
|
+
反正規化以完整性換取讀取效能。需刻意為之並記錄權衡考量。
|
|
62
|
+
|
|
63
|
+
| 判斷條件 | 正規化 | 反正規化 |
|
|
64
|
+
|----------|--------|----------|
|
|
65
|
+
| 讀寫比例 | 寫入密集或平衡 | 讀取密集(>90% 讀取) |
|
|
66
|
+
| 資料一致性 | 關鍵(財務、醫療) | 可接受最終一致性 |
|
|
67
|
+
| 查詢複雜度 | 可接受的 JOIN 效能 | JOIN 導致不可接受的延遲 |
|
|
68
|
+
| 資料異動頻率 | 經常更新 | 建立後很少變更 |
|
|
69
|
+
| 儲存成本 | 最小化重複 | 儲存便宜;速度是優先考量 |
|
|
70
|
+
|
|
71
|
+
**進行反正規化時:**
|
|
72
|
+
- 記錄資料來源(source of truth)與同步機制
|
|
73
|
+
- 加入註解說明選擇反正規化的原因
|
|
74
|
+
- 實作一致性檢查或校正排程
|
|
75
|
+
|
|
76
|
+
### 命名慣例
|
|
77
|
+
|
|
78
|
+
| 元素 | 慣例 | 範例 |
|
|
79
|
+
|------|------|------|
|
|
80
|
+
| 資料表 | `snake_case`,單數 | `user_account`、`order_item` |
|
|
81
|
+
| 欄位 | `snake_case` | `first_name`、`created_at` |
|
|
82
|
+
| 主鍵 | `id` | `user_account.id` |
|
|
83
|
+
| 外鍵 | `<被參照資料表>_id` | `order.user_account_id` |
|
|
84
|
+
| 布林欄位 | `is_` 或 `has_` 前綴 | `is_active`、`has_verified_email` |
|
|
85
|
+
| 時間戳記 | `_at` 後綴 | `created_at`、`updated_at`、`deleted_at` |
|
|
86
|
+
| 索引 | `idx_<資料表>_<欄位>` | `idx_user_account_email` |
|
|
87
|
+
| 唯一約束 | `uq_<資料表>_<欄位>` | `uq_user_account_email` |
|
|
88
|
+
| 檢查約束 | `ck_<資料表>_<描述>` | `ck_order_positive_amount` |
|
|
89
|
+
|
|
90
|
+
### 保留字
|
|
91
|
+
|
|
92
|
+
- 避免使用 SQL 保留字作為識別符號(`order`、`user`、`group`、`select`)
|
|
93
|
+
- 若無法避免,加上實體類型後綴:`user_account`、`order_record`、`user_group`
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 資料型別
|
|
98
|
+
|
|
99
|
+
### 選擇適當型別
|
|
100
|
+
|
|
101
|
+
| 場景 | 建議 | 避免 |
|
|
102
|
+
|------|------|------|
|
|
103
|
+
| 金額值 | `DECIMAL(19,4)` 或 `NUMERIC` | `FLOAT`、`DOUBLE`(精度損失) |
|
|
104
|
+
| 日期時間 | `TIMESTAMPTZ`(含時區) | `VARCHAR` 儲存日期 |
|
|
105
|
+
| 布林旗標 | `BOOLEAN` | `INT` (0/1)、`CHAR(1)` ('Y'/'N') |
|
|
106
|
+
| 短文字 (< 255) | `VARCHAR(n)` 含適當長度 | `TEXT` 用於已知長度欄位 |
|
|
107
|
+
| 長文字 | `TEXT` | `VARCHAR(MAX)` 或過大的 `VARCHAR` |
|
|
108
|
+
| IP 位址 | 原生 IP 型別或 `INET` | `VARCHAR(45)` |
|
|
109
|
+
| JSON 資料 | `JSONB` (PostgreSQL) 或原生 JSON | `TEXT` 儲存 JSON 字串 |
|
|
110
|
+
| 列舉值 | `ENUM` 型別或查詢表 | 字串化的值 |
|
|
111
|
+
|
|
112
|
+
### UUID vs 自動遞增
|
|
113
|
+
|
|
114
|
+
| 因素 | 自動遞增 | UUID |
|
|
115
|
+
|------|----------|------|
|
|
116
|
+
| 儲存大小 | 4-8 bytes | 16 bytes |
|
|
117
|
+
| 索引效能 | 較佳(循序寫入) | 較差(隨機插入造成 B-tree 碎片) |
|
|
118
|
+
| 分散式生成 | 需要協調 | 無需協調 |
|
|
119
|
+
| 安全性 | 可預測(可列舉) | 不可猜測 |
|
|
120
|
+
| URL 暴露 | 揭露記錄數量 | 可安全用於公開 URL |
|
|
121
|
+
| 合併/複寫 | 容易衝突 | 無衝突 |
|
|
122
|
+
|
|
123
|
+
**建議:**
|
|
124
|
+
- 單一資料庫系統的內部 ID 使用**自動遞增**
|
|
125
|
+
- 分散式系統或公開暴露的 ID 使用 **UUIDv7**(時間排序)
|
|
126
|
+
- 新專案考慮以 **UUIDv7** 為預設 — 兼具可排序性與唯一性
|
|
127
|
+
|
|
128
|
+
```sql
|
|
129
|
+
-- PostgreSQL:UUIDv7 作為主鍵
|
|
130
|
+
CREATE TABLE user_account (
|
|
131
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
132
|
+
email VARCHAR(255) NOT NULL,
|
|
133
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
-- 自動遞增替代方案
|
|
137
|
+
CREATE TABLE user_account (
|
|
138
|
+
id BIGSERIAL PRIMARY KEY,
|
|
139
|
+
public_id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
140
|
+
email VARCHAR(255) NOT NULL,
|
|
141
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
142
|
+
);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 索引策略
|
|
148
|
+
|
|
149
|
+
### 何時建立索引
|
|
150
|
+
|
|
151
|
+
| 建立索引的時機 | 避免建立索引的時機 |
|
|
152
|
+
|---------------|-------------------|
|
|
153
|
+
| 欄位經常出現在 `WHERE` 子句中 | 資料表少於 1,000 列 |
|
|
154
|
+
| 欄位用於 `JOIN` 條件 | 欄位基數極低(如布林值) |
|
|
155
|
+
| 欄位用於 `ORDER BY` | 資料表為寫入密集且很少讀取 |
|
|
156
|
+
| 欄位用於 `GROUP BY` | 欄位經常更新 |
|
|
157
|
+
| 需要唯一約束 | 每張資料表已超過 8 個索引 |
|
|
158
|
+
|
|
159
|
+
### 複合索引欄位順序
|
|
160
|
+
|
|
161
|
+
複合索引的欄位順序影響重大。遵循**等值優先、範圍最後**規則:
|
|
162
|
+
|
|
163
|
+
```sql
|
|
164
|
+
-- 查詢模式:
|
|
165
|
+
-- WHERE status = 'active' AND created_at > '2026-01-01' ORDER BY created_at
|
|
166
|
+
|
|
167
|
+
-- 正確:等值欄位在前,範圍/排序欄位在後
|
|
168
|
+
CREATE INDEX idx_order_status_created ON order_record (status, created_at);
|
|
169
|
+
|
|
170
|
+
-- 錯誤:範圍欄位在前,削弱等值篩選效果
|
|
171
|
+
CREATE INDEX idx_order_created_status ON order_record (created_at, status);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**欄位順序規則:**
|
|
175
|
+
1. 等值條件(`=`)優先
|
|
176
|
+
2. `IN` 條件其次
|
|
177
|
+
3. 範圍條件(`>`、`<`、`BETWEEN`)最後
|
|
178
|
+
4. `ORDER BY` 欄位放末端(若符合排序方向)
|
|
179
|
+
|
|
180
|
+
### 覆蓋索引
|
|
181
|
+
|
|
182
|
+
覆蓋索引包含查詢所需的所有欄位,實現僅索引掃描:
|
|
183
|
+
|
|
184
|
+
```sql
|
|
185
|
+
-- 查詢:SELECT email, first_name FROM user_account WHERE status = 'active';
|
|
186
|
+
|
|
187
|
+
-- 覆蓋索引 — 無需回表查詢
|
|
188
|
+
CREATE INDEX idx_user_account_status_covering
|
|
189
|
+
ON user_account (status) INCLUDE (email, first_name);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 部分索引
|
|
193
|
+
|
|
194
|
+
對資料列的子集建立索引,以減少索引大小並改善寫入效能:
|
|
195
|
+
|
|
196
|
+
```sql
|
|
197
|
+
-- 僅索引活躍記錄(90% 的查詢篩選 active)
|
|
198
|
+
CREATE INDEX idx_order_active
|
|
199
|
+
ON order_record (created_at)
|
|
200
|
+
WHERE status = 'active';
|
|
201
|
+
|
|
202
|
+
-- 僅索引非 NULL 值
|
|
203
|
+
CREATE INDEX idx_user_account_phone
|
|
204
|
+
ON user_account (phone_number)
|
|
205
|
+
WHERE phone_number IS NOT NULL;
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 索引反模式
|
|
209
|
+
|
|
210
|
+
| 反模式 | 問題 | 解決方案 |
|
|
211
|
+
|--------|------|----------|
|
|
212
|
+
| **過度索引** | 拖慢寫入、浪費儲存空間 | 每季審查索引;移除未使用的 |
|
|
213
|
+
| **未使用的索引** | 有維護成本但無讀取收益 | 監控 `pg_stat_user_indexes` 或同等工具 |
|
|
214
|
+
| **重複索引** | 多餘的開銷 | 索引 `(a, b)` 已涵蓋 `(a)` 的查詢 |
|
|
215
|
+
| **低基數欄位索引** | 全表掃描通常更快 | 改用部分索引或 Bitmap 索引 |
|
|
216
|
+
| **FK 缺少索引** | CASCADE 刪除與 JOIN 變慢 | 務必為外鍵欄位建立索引 |
|
|
217
|
+
| **索引欄位上使用函式** | 索引被繞過 | 建立函式/表達式索引 |
|
|
218
|
+
|
|
219
|
+
```sql
|
|
220
|
+
-- 反模式:函式阻止索引使用
|
|
221
|
+
SELECT * FROM user_account WHERE LOWER(email) = 'test@example.com';
|
|
222
|
+
|
|
223
|
+
-- 解決方案:表達式索引
|
|
224
|
+
CREATE INDEX idx_user_account_email_lower ON user_account (LOWER(email));
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 遷移策略
|
|
230
|
+
|
|
231
|
+
### 原則
|
|
232
|
+
|
|
233
|
+
| 原則 | 說明 |
|
|
234
|
+
|------|------|
|
|
235
|
+
| **版本控制** | 所有遷移與應用程式碼一同儲存在版本控制系統 |
|
|
236
|
+
| **循序執行** | 遷移以確定性順序執行 |
|
|
237
|
+
| **冪等性** | 執行兩次遷移產生相同結果 |
|
|
238
|
+
| **已測試** | 遷移在部署前以類生產資料量進行測試 |
|
|
239
|
+
| **有文件** | 每次遷移包含變更內容與原因的說明 |
|
|
240
|
+
|
|
241
|
+
### 命名慣例
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
YYYYMMDDHHMMSS_description.sql
|
|
245
|
+
|
|
246
|
+
範例:
|
|
247
|
+
20260318120000_create_user_account_table.sql
|
|
248
|
+
20260318120100_add_email_index_to_user_account.sql
|
|
249
|
+
20260318120200_add_phone_column_to_user_account.sql
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 正向遷移 vs 可逆遷移
|
|
253
|
+
|
|
254
|
+
| 方式 | 優點 | 缺點 | 適用時機 |
|
|
255
|
+
|------|------|------|----------|
|
|
256
|
+
| **可逆** (up/down) | 容易回滾、較安全 | 需維護更多程式碼、部分變更不可逆 | 開發環境、非破壞性變更 |
|
|
257
|
+
| **正向** | 較簡單、符合現實 | 需另外的回滾遷移 | 生產環境、破壞性變更 |
|
|
258
|
+
|
|
259
|
+
**建議:** 預設使用可逆遷移。對於破壞性操作(刪除欄位、刪除資料表),使用正向遷移並搭配獨立的回滾遷移檔案。
|
|
260
|
+
|
|
261
|
+
### 零停機遷移模式(Expand-Contract)
|
|
262
|
+
|
|
263
|
+
適用於無法容忍停機的系統 Schema 變更:
|
|
264
|
+
|
|
265
|
+
**第一階段 — Expand(向後相容)**
|
|
266
|
+
```sql
|
|
267
|
+
-- 新增欄位(可為 NULL,尚無約束)
|
|
268
|
+
ALTER TABLE user_account ADD COLUMN phone VARCHAR(20);
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**第二階段 — Migrate(雙寫)**
|
|
272
|
+
```sql
|
|
273
|
+
-- 回填現有資料
|
|
274
|
+
UPDATE user_account SET phone = legacy_phone WHERE phone IS NULL;
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**第三階段 — Contract(所有消費者更新後)**
|
|
278
|
+
```sql
|
|
279
|
+
-- 所有資料已填入後加入約束
|
|
280
|
+
ALTER TABLE user_account ALTER COLUMN phone SET NOT NULL;
|
|
281
|
+
-- 移除舊欄位(僅在確認無消費者使用後)
|
|
282
|
+
ALTER TABLE user_account DROP COLUMN legacy_phone;
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 回滾策略
|
|
286
|
+
|
|
287
|
+
| 場景 | 回滾方式 |
|
|
288
|
+
|------|----------|
|
|
289
|
+
| 新增欄位 | 移除該欄位 |
|
|
290
|
+
| 新增索引 | 移除該索引 |
|
|
291
|
+
| 新增資料表 | 移除該資料表 |
|
|
292
|
+
| 移除欄位 | 無法復原 — 需從備份還原或重新新增 |
|
|
293
|
+
| 資料轉換 | 執行反向轉換(若有設計) |
|
|
294
|
+
| 重新命名欄位 | 重新命名回來 |
|
|
295
|
+
|
|
296
|
+
**關鍵規則:** 絕不在停止寫入的同一次部署中移除欄位或資料表。使用 Expand-Contract 模式。
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 查詢最佳實踐
|
|
301
|
+
|
|
302
|
+
### N+1 查詢預防
|
|
303
|
+
|
|
304
|
+
N+1 問題發生在程式碼執行一個查詢取得清單,再對每個項目額外執行 N 個查詢。
|
|
305
|
+
|
|
306
|
+
```sql
|
|
307
|
+
-- N+1 問題(應用程式發出 N 個查詢)
|
|
308
|
+
-- 查詢 1:SELECT * FROM order_record WHERE user_id = 42;
|
|
309
|
+
-- 查詢 2..N:SELECT * FROM order_item WHERE order_id = ?; (對每筆訂單)
|
|
310
|
+
|
|
311
|
+
-- 解決方案:JOIN 或子查詢
|
|
312
|
+
SELECT o.*, oi.*
|
|
313
|
+
FROM order_record o
|
|
314
|
+
JOIN order_item oi ON oi.order_id = o.id
|
|
315
|
+
WHERE o.user_id = 42;
|
|
316
|
+
|
|
317
|
+
-- 或批次載入
|
|
318
|
+
SELECT * FROM order_item
|
|
319
|
+
WHERE order_id IN (SELECT id FROM order_record WHERE user_id = 42);
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### EXPLAIN 計畫使用
|
|
323
|
+
|
|
324
|
+
對以下查詢務必分析執行計畫:
|
|
325
|
+
- 每分鐘執行超過 100 次的查詢
|
|
326
|
+
- 執行時間 > 100ms 的查詢
|
|
327
|
+
- 涉及超過 10,000 列的查詢
|
|
328
|
+
- 部署前的任何新查詢
|
|
329
|
+
|
|
330
|
+
```sql
|
|
331
|
+
-- PostgreSQL
|
|
332
|
+
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
|
|
333
|
+
SELECT * FROM order_record WHERE status = 'pending' AND created_at > '2026-01-01';
|
|
334
|
+
|
|
335
|
+
-- 需關注的指標:
|
|
336
|
+
-- 大型資料表的 Seq Scan → 缺少索引
|
|
337
|
+
-- 高列數的 Nested Loop → 考慮 Hash Join
|
|
338
|
+
-- 高成本的 Sort → 加入符合 ORDER BY 的索引
|
|
339
|
+
-- 列數(估計 vs 實際) → 統計資料過時,執行 ANALYZE
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 分頁
|
|
343
|
+
|
|
344
|
+
| 方法 | 優點 | 缺點 | 適用時機 |
|
|
345
|
+
|------|------|------|----------|
|
|
346
|
+
| **Offset 分頁** | 簡單、支援隨機頁面存取 | 大 Offset 時效能差、並行寫入時結果不一致 | 小型資料集、管理後台 |
|
|
347
|
+
| **Keyset(游標)分頁** | 效能一致、結果穩定 | 無法隨機跳頁、多欄排序時較複雜 | API、無限捲動、大型資料集 |
|
|
348
|
+
|
|
349
|
+
```sql
|
|
350
|
+
-- Offset 分頁(大型資料表應避免)
|
|
351
|
+
SELECT * FROM order_record ORDER BY id LIMIT 20 OFFSET 10000;
|
|
352
|
+
-- 效能劣化:資料庫須掃描並丟棄 10,000 列
|
|
353
|
+
|
|
354
|
+
-- Keyset 分頁(建議使用)
|
|
355
|
+
SELECT * FROM order_record
|
|
356
|
+
WHERE id > :last_seen_id
|
|
357
|
+
ORDER BY id
|
|
358
|
+
LIMIT 20;
|
|
359
|
+
-- 無論頁面深度,效能一致
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 查詢反模式
|
|
363
|
+
|
|
364
|
+
| 反模式 | 問題 | 解決方案 |
|
|
365
|
+
|--------|------|----------|
|
|
366
|
+
| `SELECT *` | 取得不必要的資料、Schema 變更時可能中斷 | 明確列出所需欄位 |
|
|
367
|
+
| 查詢中的字串串接 | SQL 注入漏洞 | 使用參數化查詢 / Prepared Statement |
|
|
368
|
+
| 不同欄位的 `OR` | 阻止索引使用 | 使用 `UNION ALL` 或重構查詢 |
|
|
369
|
+
| `NOT IN` 含 NULL | 非預期的空結果 | 改用 `NOT EXISTS` |
|
|
370
|
+
| 隱含型別轉換 | 繞過索引、結果錯誤 | 明確轉型 |
|
|
371
|
+
| `LIKE '%prefix'` | 前導萬用字元阻止索引使用 | 使用全文搜索或反向索引 |
|
|
372
|
+
|
|
373
|
+
```sql
|
|
374
|
+
-- 反模式:SQL 注入風險
|
|
375
|
+
query = "SELECT * FROM user_account WHERE email = '" + email + "'";
|
|
376
|
+
|
|
377
|
+
-- 正確:參數化查詢
|
|
378
|
+
query = "SELECT * FROM user_account WHERE email = $1";
|
|
379
|
+
params = [email];
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## 交易管理
|
|
385
|
+
|
|
386
|
+
### ACID 特性
|
|
387
|
+
|
|
388
|
+
| 特性 | 說明 | 實施方式 |
|
|
389
|
+
|------|------|----------|
|
|
390
|
+
| **原子性 (Atomicity)** | 所有操作成功或全部失敗 | 使用交易;避免部分提交 |
|
|
391
|
+
| **一致性 (Consistency)** | 資料庫從一個有效狀態轉移到另一個 | 在資料庫層級強制約束 |
|
|
392
|
+
| **隔離性 (Isolation)** | 並行交易不互相干擾 | 選擇適當的隔離等級 |
|
|
393
|
+
| **持久性 (Durability)** | 已提交的資料在系統故障後存活 | 使用 WAL(預寫日誌);確認同步寫入 |
|
|
394
|
+
|
|
395
|
+
### 隔離等級
|
|
396
|
+
|
|
397
|
+
| 等級 | 髒讀 | 不可重複讀 | 幻讀 | 效能 | 使用場景 |
|
|
398
|
+
|------|------|-----------|------|------|----------|
|
|
399
|
+
| **Read Uncommitted** | 可能 | 可能 | 可能 | 最快 | 不建議使用 |
|
|
400
|
+
| **Read Committed** | 防止 | 可能 | 可能 | 快 | 大多數 RDBMS 的預設;一般用途查詢 |
|
|
401
|
+
| **Repeatable Read** | 防止 | 防止 | 可能 | 中等 | 財務報表、庫存檢查 |
|
|
402
|
+
| **Serializable** | 防止 | 防止 | 防止 | 最慢 | 金錢轉帳、訂位系統 |
|
|
403
|
+
|
|
404
|
+
**建議:** 使用 **Read Committed** 作為預設。僅在需要嚴格一致性的操作(如帳戶餘額更新、座位預訂)時提升至 **Repeatable Read** 或 **Serializable**。
|
|
405
|
+
|
|
406
|
+
### 死鎖預防
|
|
407
|
+
|
|
408
|
+
| 策略 | 實施方式 |
|
|
409
|
+
|------|----------|
|
|
410
|
+
| **一致的鎖定順序** | 在所有交易中以相同順序取得資料表/列的鎖定 |
|
|
411
|
+
| **短交易** | 盡可能保持交易簡短;將非資料庫工作移出交易外 |
|
|
412
|
+
| **鎖定逾時** | 設定 `lock_timeout` 以快速失敗而非無限等待 |
|
|
413
|
+
| **重試邏輯** | 對死鎖錯誤(SQLSTATE 40P01)實作指數退避重試 |
|
|
414
|
+
| **避免使用者互動** | 絕不在等待使用者輸入時保持交易開啟 |
|
|
415
|
+
|
|
416
|
+
```sql
|
|
417
|
+
-- 設定鎖定逾時以防止無限等待
|
|
418
|
+
SET lock_timeout = '5s';
|
|
419
|
+
|
|
420
|
+
-- 保持交易簡短
|
|
421
|
+
BEGIN;
|
|
422
|
+
UPDATE account SET balance = balance - 100 WHERE id = 1;
|
|
423
|
+
UPDATE account SET balance = balance + 100 WHERE id = 2;
|
|
424
|
+
COMMIT;
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### 樂觀鎖定 vs 悲觀鎖定
|
|
428
|
+
|
|
429
|
+
| 因素 | 樂觀鎖定 | 悲觀鎖定 |
|
|
430
|
+
|------|----------|----------|
|
|
431
|
+
| 機制 | 寫入時檢查版本欄位/時間戳記 | `SELECT ... FOR UPDATE` 取得列鎖定 |
|
|
432
|
+
| 衝突率 | 低衝突環境 | 高衝突環境 |
|
|
433
|
+
| 效能 | 衝突罕見時較佳 | 衝突頻繁時較佳 |
|
|
434
|
+
| 使用者體驗影響 | 使用者可能看到「其他人已修改」錯誤 | 使用者可能等待鎖定釋放 |
|
|
435
|
+
| 死鎖風險 | 無 | 可能 |
|
|
436
|
+
|
|
437
|
+
```sql
|
|
438
|
+
-- 樂觀鎖定
|
|
439
|
+
UPDATE order_record
|
|
440
|
+
SET status = 'shipped', version = version + 1
|
|
441
|
+
WHERE id = 42 AND version = 3;
|
|
442
|
+
-- 若受影響列數 = 0,表示另一個交易已修改 → 重試或錯誤
|
|
443
|
+
|
|
444
|
+
-- 悲觀鎖定
|
|
445
|
+
BEGIN;
|
|
446
|
+
SELECT * FROM order_record WHERE id = 42 FOR UPDATE;
|
|
447
|
+
-- 列已鎖定;其他交易等待
|
|
448
|
+
UPDATE order_record SET status = 'shipped' WHERE id = 42;
|
|
449
|
+
COMMIT;
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## SQL vs NoSQL 決策矩陣
|
|
455
|
+
|
|
456
|
+
| 判斷條件 | 關聯式 (SQL) | 文件型 (NoSQL) | 鍵值型 | 圖形型 |
|
|
457
|
+
|----------|-------------|---------------|--------|--------|
|
|
458
|
+
| **資料結構** | 結構化、明確定義的 Schema | 半結構化、彈性 Schema | 簡單的 key→value 配對 | 高度連結的實體 |
|
|
459
|
+
| **一致性** | 強一致(ACID) | 最終一致(BASE),部分支援 ACID | 最終一致 | 依實作而異 |
|
|
460
|
+
| **查詢複雜度** | 複雜 JOIN、聚合 | 簡單查詢、巢狀文件 | 單鍵查詢 | 關係遍歷 |
|
|
461
|
+
| **擴展模式** | 垂直擴展(scale-up) | 水平擴展(scale-out) | 水平擴展 | 依實作而異 |
|
|
462
|
+
| **Schema 變更** | 需要遷移 | 無 Schema / 彈性 | 無 Schema | Schema 可選 |
|
|
463
|
+
| **範例用途** | 財務系統、ERP、CRM | 內容管理、使用者檔案、產品目錄 | 快取、Session、速率限制 | 社交網路、推薦、詐騙偵測 |
|
|
464
|
+
| **範例資料庫** | PostgreSQL、MySQL、SQL Server | MongoDB、CouchDB、DynamoDB | Redis、Memcached、DynamoDB | Neo4j、Amazon Neptune |
|
|
465
|
+
|
|
466
|
+
### 決策指南
|
|
467
|
+
|
|
468
|
+
```
|
|
469
|
+
你的資料是否高度關聯且需要複雜查詢?
|
|
470
|
+
├── 是 → 關聯式 (SQL)
|
|
471
|
+
└── 否 → 你的資料是否為簡單的鍵值配對?
|
|
472
|
+
├── 是 → 鍵值型儲存
|
|
473
|
+
└── 否 → 關係是否為主要的查詢模式?
|
|
474
|
+
├── 是 → 圖形資料庫
|
|
475
|
+
└── 否 → 文件型資料庫
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**Polyglot Persistence(多語言持久化):** 許多系統受益於使用多種資料庫類型。範例:
|
|
479
|
+
- **PostgreSQL** 用於交易資料(訂單、帳戶)
|
|
480
|
+
- **Redis** 用於快取與 Session
|
|
481
|
+
- **Elasticsearch** 用於全文搜索
|
|
482
|
+
- **Neo4j** 用於推薦引擎
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 連線管理
|
|
487
|
+
|
|
488
|
+
### 連線池
|
|
489
|
+
|
|
490
|
+
每個應用程式都必須使用連線池。每次請求建立新的資料庫連線代價極高(TCP 握手、認證、SSL 協商)。
|
|
491
|
+
|
|
492
|
+
| 參數 | 建議預設值 | 說明 |
|
|
493
|
+
|------|-----------|------|
|
|
494
|
+
| **最小池大小** | 2-5 | 維持的最少閒置連線數 |
|
|
495
|
+
| **最大池大小** | 10-20 | 最大並行連線數 |
|
|
496
|
+
| **連線逾時** | 5 秒 | 等待從池取得連線的時間 |
|
|
497
|
+
| **閒置逾時** | 10 分鐘 | 超過此時間關閉閒置連線 |
|
|
498
|
+
| **最大存活時間** | 30 分鐘 | 回收連線以防止狀態過時 |
|
|
499
|
+
| **驗證查詢** | `SELECT 1` | 返回連線前的健康檢查 |
|
|
500
|
+
|
|
501
|
+
### 池大小公式
|
|
502
|
+
|
|
503
|
+
最大連線池大小的常用公式:
|
|
504
|
+
|
|
505
|
+
```
|
|
506
|
+
pool_size = (core_count * 2) + effective_spindle_count
|
|
507
|
+
|
|
508
|
+
範例:
|
|
509
|
+
- 4 核心伺服器,SSD: (4 * 2) + 1 = 9-10 個連線
|
|
510
|
+
- 8 核心伺服器,SSD: (8 * 2) + 1 = 17 個連線
|
|
511
|
+
- 4 核心伺服器,4 HDD: (4 * 2) + 4 = 12 個連線
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
**重要:** 更多連線不一定更好。過多連線會導致:
|
|
515
|
+
- 資料庫中的執行緒競爭
|
|
516
|
+
- 記憶體壓力(每個連線使用約 5-10 MB)
|
|
517
|
+
- 增加上下文切換
|
|
518
|
+
|
|
519
|
+
### 健康檢查
|
|
520
|
+
|
|
521
|
+
```sql
|
|
522
|
+
-- 基本健康檢查
|
|
523
|
+
SELECT 1;
|
|
524
|
+
|
|
525
|
+
-- 進階健康檢查(驗證讀寫能力)
|
|
526
|
+
SELECT NOW();
|
|
527
|
+
|
|
528
|
+
-- 使用前的連線驗證
|
|
529
|
+
SET statement_timeout = '2s';
|
|
530
|
+
SELECT 1;
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
## 資料完整性
|
|
536
|
+
|
|
537
|
+
### 約束
|
|
538
|
+
|
|
539
|
+
務必在資料庫層級強制資料完整性。應用程式層級的驗證是補充,不是替代。
|
|
540
|
+
|
|
541
|
+
| 約束 | 用途 | 範例 |
|
|
542
|
+
|------|------|------|
|
|
543
|
+
| `NOT NULL` | 防止缺少必要資料 | `email VARCHAR(255) NOT NULL` |
|
|
544
|
+
| `UNIQUE` | 防止重複值 | `UNIQUE (email)` |
|
|
545
|
+
| `CHECK` | 驗證值範圍/格式 | `CHECK (amount > 0)` |
|
|
546
|
+
| `FOREIGN KEY` | 強制參照完整性 | `REFERENCES user_account(id)` |
|
|
547
|
+
| `DEFAULT` | 提供合理的預設值 | `DEFAULT NOW()` |
|
|
548
|
+
| `EXCLUSION` | 防止範圍重疊 | `EXCLUDE USING gist (room WITH =, period WITH &&)` |
|
|
549
|
+
|
|
550
|
+
```sql
|
|
551
|
+
CREATE TABLE order_record (
|
|
552
|
+
id BIGSERIAL PRIMARY KEY,
|
|
553
|
+
user_account_id BIGINT NOT NULL REFERENCES user_account(id),
|
|
554
|
+
amount DECIMAL(19,4) NOT NULL CHECK (amount > 0),
|
|
555
|
+
status VARCHAR(20) NOT NULL DEFAULT 'pending'
|
|
556
|
+
CHECK (status IN ('pending', 'confirmed', 'shipped', 'delivered', 'cancelled')),
|
|
557
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
558
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
559
|
+
);
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### 串聯規則
|
|
563
|
+
|
|
564
|
+
| 規則 | 行為 | 適用時機 |
|
|
565
|
+
|------|------|----------|
|
|
566
|
+
| `CASCADE` | 自動刪除/更新子列 | 強擁有權關係(order → order_items) |
|
|
567
|
+
| `SET NULL` | 父列刪除時將 FK 設為 NULL | 可選關係(文章 → 作者刪除時) |
|
|
568
|
+
| `SET DEFAULT` | 父列刪除時將 FK 設為預設值 | 重新指派至預設值 |
|
|
569
|
+
| `RESTRICT` | 若存在子列則阻止父列刪除 | 保護關鍵參照(user → audit_log) |
|
|
570
|
+
| `NO ACTION` | 與 RESTRICT 相同(可延遲檢查) | 預設行為 |
|
|
571
|
+
|
|
572
|
+
**建議:** 預設使用 `RESTRICT`。僅在父子生命週期緊密耦合時使用 `CASCADE`。
|
|
573
|
+
|
|
574
|
+
### 軟刪除 vs 硬刪除
|
|
575
|
+
|
|
576
|
+
| 因素 | 軟刪除 | 硬刪除 |
|
|
577
|
+
|------|--------|--------|
|
|
578
|
+
| 實作方式 | `deleted_at TIMESTAMPTZ` 欄位 | `DELETE FROM table` |
|
|
579
|
+
| 資料復原 | 簡單 — 設定 `deleted_at = NULL` | 需從備份還原 |
|
|
580
|
+
| 查詢複雜度 | 每處都須加 `WHERE deleted_at IS NULL` | 查詢較簡單 |
|
|
581
|
+
| 儲存 | 隨時間增長 | 回收空間 |
|
|
582
|
+
| 合規性 | 保留稽核軌跡 | 可能違反保留要求 |
|
|
583
|
+
| 效能 | 大量軟刪除列的大型資料表 | 更乾淨的表統計資料 |
|
|
584
|
+
|
|
585
|
+
```sql
|
|
586
|
+
-- 軟刪除實作
|
|
587
|
+
ALTER TABLE user_account ADD COLUMN deleted_at TIMESTAMPTZ;
|
|
588
|
+
|
|
589
|
+
-- 為活躍記錄建立部分索引
|
|
590
|
+
CREATE INDEX idx_user_account_active ON user_account (email) WHERE deleted_at IS NULL;
|
|
591
|
+
|
|
592
|
+
-- 應用程式查詢模式
|
|
593
|
+
SELECT * FROM user_account WHERE deleted_at IS NULL AND email = $1;
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
**建議:** 對面向使用者的資料和任何需要稽核軌跡的內容使用軟刪除。對暫時性資料(Session、臨時 Token、超過保留期的日誌)使用硬刪除。
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## 備份與復原
|
|
601
|
+
|
|
602
|
+
### 備份策略類型
|
|
603
|
+
|
|
604
|
+
| 策略 | 說明 | 備份速度 | 還原速度 | 儲存成本 |
|
|
605
|
+
|------|------|----------|----------|----------|
|
|
606
|
+
| **完整備份** | 整個資料庫的完整複本 | 最慢 | 最快 | 最高 |
|
|
607
|
+
| **增量備份** | 自上次備份以來的變更 | 最快 | 最慢(需完整鏈) | 最低 |
|
|
608
|
+
| **差異備份** | 自上次完整備份以來的變更 | 中等 | 中等(完整 + 差異) | 中等 |
|
|
609
|
+
|
|
610
|
+
### RPO 與 RTO
|
|
611
|
+
|
|
612
|
+
| 指標 | 定義 | 目標範例 |
|
|
613
|
+
|------|------|----------|
|
|
614
|
+
| **RPO**(復原點目標) | 可接受的最大資料損失(時間) | 1 小時:每小時備份;0:持續複寫 |
|
|
615
|
+
| **RTO**(復原時間目標) | 可接受的最大停機時間 | 15 分鐘:自動容錯切換;4 小時:手動還原 |
|
|
616
|
+
|
|
617
|
+
### 備份排程建議
|
|
618
|
+
|
|
619
|
+
| 層級 | RPO | RTO | 策略 |
|
|
620
|
+
|------|-----|-----|------|
|
|
621
|
+
| **關鍵**(財務、醫療) | < 1 分鐘 | < 15 分鐘 | 同步複寫 + 持續 WAL 歸檔 |
|
|
622
|
+
| **重要**(電子商務、SaaS) | < 1 小時 | < 1 小時 | 串流複寫 + 每小時 WAL 歸檔 |
|
|
623
|
+
| **標準**(內部工具) | < 24 小時 | < 4 小時 | 每日完整 + 每小時增量 |
|
|
624
|
+
| **低**(開發、預備環境) | < 1 週 | < 1 天 | 每週完整備份 |
|
|
625
|
+
|
|
626
|
+
### 備份測試
|
|
627
|
+
|
|
628
|
+
| 要求 | 頻率 |
|
|
629
|
+
|------|------|
|
|
630
|
+
| 還原測試至獨立環境 | 每月 |
|
|
631
|
+
| 還原後驗證資料完整性 | 每次還原測試 |
|
|
632
|
+
| 量測實際 RTO vs 目標 | 每季 |
|
|
633
|
+
| 測試時間點復原 | 每半年 |
|
|
634
|
+
| 更新文件與執行手冊 | 每次測試後 |
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## 敏感資料處理
|
|
639
|
+
|
|
640
|
+
### 欄位層級加密
|
|
641
|
+
|
|
642
|
+
```sql
|
|
643
|
+
-- 寫入時加密
|
|
644
|
+
INSERT INTO user_account (email, ssn_encrypted)
|
|
645
|
+
VALUES ($1, pgp_sym_encrypt($2, $encryption_key));
|
|
646
|
+
|
|
647
|
+
-- 讀取時解密(僅授權角色可執行)
|
|
648
|
+
SELECT email, pgp_sym_decrypt(ssn_encrypted, $encryption_key) AS ssn
|
|
649
|
+
FROM user_account WHERE id = $1;
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### 資料分級
|
|
653
|
+
|
|
654
|
+
| 等級 | 說明 | 範例 | 處理方式 |
|
|
655
|
+
|------|------|------|----------|
|
|
656
|
+
| **公開** | 無敏感性 | 行銷內容、公開 API | 無特殊處理 |
|
|
657
|
+
| **內部** | 業務敏感 | 營收資料、產品路線圖 | 存取控制、禁止公開暴露 |
|
|
658
|
+
| **機密** | 個人識別資訊 | Email、電話、地址 | 靜態加密、存取日誌 |
|
|
659
|
+
| **限制** | 高度敏感 | 身分證號、信用卡、密碼 | 欄位加密、資料遮罩、嚴格稽核 |
|
|
660
|
+
|
|
661
|
+
### 資料遮罩
|
|
662
|
+
|
|
663
|
+
```sql
|
|
664
|
+
-- 基於 View 的遮罩,供客服人員使用
|
|
665
|
+
CREATE VIEW user_account_masked AS
|
|
666
|
+
SELECT
|
|
667
|
+
id,
|
|
668
|
+
LEFT(email, 2) || '***@' || SPLIT_PART(email, '@', 2) AS email,
|
|
669
|
+
'***-**-' || RIGHT(ssn, 4) AS ssn_masked,
|
|
670
|
+
first_name,
|
|
671
|
+
created_at
|
|
672
|
+
FROM user_account;
|
|
673
|
+
|
|
674
|
+
-- 僅授予客服團隊存取遮罩 View 的權限
|
|
675
|
+
GRANT SELECT ON user_account_masked TO support_role;
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### PII 管理檢查清單
|
|
679
|
+
|
|
680
|
+
- [ ] 識別並編目所有資料表中的 PII 欄位
|
|
681
|
+
- [ ] 靜態加密 PII(欄位層級或表空間加密)
|
|
682
|
+
- [ ] 傳輸中加密 PII(所有連線使用 TLS)
|
|
683
|
+
- [ ] 非生產環境實施資料遮罩
|
|
684
|
+
- [ ] 定義並執行保留政策
|
|
685
|
+
- [ ] 支援資料主體請求(GDPR 刪除權、存取權)
|
|
686
|
+
- [ ] 記錄所有對 PII 欄位的存取
|
|
687
|
+
- [ ] 在開發與預備環境中匿名化資料
|
|
688
|
+
|
|
689
|
+
### 稽核日誌
|
|
690
|
+
|
|
691
|
+
```sql
|
|
692
|
+
-- 稽核日誌資料表
|
|
693
|
+
CREATE TABLE audit_log (
|
|
694
|
+
id BIGSERIAL PRIMARY KEY,
|
|
695
|
+
table_name VARCHAR(100) NOT NULL,
|
|
696
|
+
record_id BIGINT NOT NULL,
|
|
697
|
+
action VARCHAR(10) NOT NULL CHECK (action IN ('INSERT', 'UPDATE', 'DELETE')),
|
|
698
|
+
old_values JSONB,
|
|
699
|
+
new_values JSONB,
|
|
700
|
+
changed_by VARCHAR(100) NOT NULL,
|
|
701
|
+
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
-- 基於觸發器的稽核(PostgreSQL 範例)
|
|
705
|
+
CREATE OR REPLACE FUNCTION audit_trigger_fn()
|
|
706
|
+
RETURNS TRIGGER AS $$
|
|
707
|
+
BEGIN
|
|
708
|
+
INSERT INTO audit_log (table_name, record_id, action, old_values, new_values, changed_by)
|
|
709
|
+
VALUES (
|
|
710
|
+
TG_TABLE_NAME,
|
|
711
|
+
COALESCE(NEW.id, OLD.id),
|
|
712
|
+
TG_OP,
|
|
713
|
+
CASE WHEN TG_OP != 'INSERT' THEN to_jsonb(OLD) END,
|
|
714
|
+
CASE WHEN TG_OP != 'DELETE' THEN to_jsonb(NEW) END,
|
|
715
|
+
current_user
|
|
716
|
+
);
|
|
717
|
+
RETURN COALESCE(NEW, OLD);
|
|
718
|
+
END;
|
|
719
|
+
$$ LANGUAGE plpgsql;
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
## 效能監控
|
|
725
|
+
|
|
726
|
+
### 慢查詢日誌
|
|
727
|
+
|
|
728
|
+
| 資料庫 | 設定 | 建議閾值 |
|
|
729
|
+
|--------|------|----------|
|
|
730
|
+
| PostgreSQL | `log_min_duration_statement` | 200ms(開發)、1000ms(生產) |
|
|
731
|
+
| MySQL | `slow_query_log`、`long_query_time` | 1 秒 |
|
|
732
|
+
| SQL Server | Extended Events 或 Query Store | 1 秒 |
|
|
733
|
+
|
|
734
|
+
### 關鍵監控指標
|
|
735
|
+
|
|
736
|
+
| 指標 | 警告閾值 | 嚴重閾值 | 工具 |
|
|
737
|
+
|------|----------|----------|------|
|
|
738
|
+
| **活躍連線數** | > 最大值的 70% | > 最大值的 90% | 資料庫儀表板 |
|
|
739
|
+
| **快取/緩衝命中率** | < 95% | < 90% | `pg_stat_bgwriter`、InnoDB buffer pool |
|
|
740
|
+
| **複寫延遲** | > 1 秒 | > 10 秒 | 複寫監控 |
|
|
741
|
+
| **交易速率** | 偏離基線 > 20% | 偏離 > 50% | 應用程式指標 |
|
|
742
|
+
| **鎖定等待時間** | 平均 > 1 秒 | > 5 秒 | 鎖定監控查詢 |
|
|
743
|
+
| **每分鐘死鎖數** | > 1 | > 5 | 資料庫日誌 |
|
|
744
|
+
| **資料表膨脹** | > 20% 死元組 | > 40% 死元組 | `pg_stat_user_tables` |
|
|
745
|
+
| **查詢執行時間 (p95)** | > 500ms | > 2 秒 | APM 工具 |
|
|
746
|
+
|
|
747
|
+
### 查詢計畫分析工作流程
|
|
748
|
+
|
|
749
|
+
```
|
|
750
|
+
1. 識別慢查詢(慢查詢日誌或 APM)
|
|
751
|
+
↓
|
|
752
|
+
2. 在預備環境以類生產資料執行 EXPLAIN ANALYZE
|
|
753
|
+
↓
|
|
754
|
+
3. 查找:
|
|
755
|
+
- 大型資料表的循序掃描 → 加入索引
|
|
756
|
+
- 實際與估計列數差距大 → 執行 ANALYZE(更新統計資料)
|
|
757
|
+
- 大量迭代的 Nested Loop → 重構查詢或加入索引
|
|
758
|
+
- 高成本的排序操作 → 加入符合排序順序的索引
|
|
759
|
+
↓
|
|
760
|
+
4. 套用修正(加入索引、改寫查詢、更新統計資料)
|
|
761
|
+
↓
|
|
762
|
+
5. 重新執行 EXPLAIN ANALYZE 驗證改善
|
|
763
|
+
↓
|
|
764
|
+
6. 部署並在生產環境監控執行時間
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
## 快速參考卡
|
|
770
|
+
|
|
771
|
+
### Schema 設計
|
|
772
|
+
|
|
773
|
+
```
|
|
774
|
+
✅ 所有識別符號使用 snake_case
|
|
775
|
+
✅ 單數資料表名稱(user_account,非 user_accounts)
|
|
776
|
+
✅ 外鍵使用 _id 後綴
|
|
777
|
+
✅ 必有 id、created_at、updated_at 欄位
|
|
778
|
+
✅ 在資料庫層級強制約束
|
|
779
|
+
✅ 正規化至 3NF,反正規化須有文件記載的理由
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### 查詢
|
|
783
|
+
|
|
784
|
+
```
|
|
785
|
+
✅ 務必使用參數化查詢
|
|
786
|
+
✅ 明確列出所需欄位,而非 SELECT *
|
|
787
|
+
✅ 使用 EXPLAIN ANALYZE 進行查詢最佳化
|
|
788
|
+
✅ 大型資料集優先使用 Keyset 分頁而非 Offset
|
|
789
|
+
✅ 批次操作以預防 N+1 查詢
|
|
790
|
+
✅ 設定 statement_timeout 以防止失控查詢
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
### 維運
|
|
794
|
+
|
|
795
|
+
```
|
|
796
|
+
✅ 使用連線池(絕不建立每次請求的連線)
|
|
797
|
+
✅ 版本控制所有遷移
|
|
798
|
+
✅ 以類生產資料測試遷移
|
|
799
|
+
✅ 使用 Expand-Contract 模式進行零停機 Schema 變更
|
|
800
|
+
✅ 監控慢查詢、連線數、快取命中率
|
|
801
|
+
✅ 定期測試備份還原
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
---
|
|
805
|
+
|
|
806
|
+
## 相關標準
|
|
807
|
+
|
|
808
|
+
- [安全標準](../../../core/security-standards.md) — 資料加密、存取控制、PII 處理
|
|
809
|
+
- [效能標準](../../../core/performance-standards.md) — 應用程式層級的效能最佳化
|
|
810
|
+
- [日誌標準](../../../core/logging-standards.md) — 資料庫操作的結構化日誌
|
|
811
|
+
- [部署標準](../../../core/deployment-standards.md) — 資料庫遷移作為部署管線的一部分
|
|
812
|
+
|
|
813
|
+
---
|
|
814
|
+
|
|
815
|
+
## 版本歷程
|
|
816
|
+
|
|
817
|
+
| 版本 | 日期 | 變更 |
|
|
818
|
+
|------|------|------|
|
|
819
|
+
| 1.0.0 | 2026-03-18 | 初始發布 |
|
|
820
|
+
|
|
821
|
+
---
|
|
822
|
+
|
|
823
|
+
## 參考資源
|
|
824
|
+
|
|
825
|
+
- [ISO/IEC 9075 — SQL 標準](https://www.iso.org/standard/76583.html)
|
|
826
|
+
- [Use The Index, Luke](https://use-the-index-luke.com/) — SQL 索引與調校
|
|
827
|
+
- [SQL Style Guide](https://www.sqlstyle.guide/) — 一致的 SQL 格式
|
|
828
|
+
- [Martin Fowler — 演進式資料庫設計](https://martinfowler.com/articles/evodb.html)
|
|
829
|
+
- [Designing Data-Intensive Applications](https://dataintensive.net/) — Martin Kleppmann
|
|
830
|
+
- [PostgreSQL 文件](https://www.postgresql.org/docs/)
|
|
831
|
+
|
|
832
|
+
---
|
|
833
|
+
|
|
834
|
+
## 授權
|
|
835
|
+
|
|
836
|
+
本標準以 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 授權發布。
|