@mison/ag-kit-cn 2.0.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.
- package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +285 -0
- package/.agent/agents/backend-specialist.md +268 -0
- package/.agent/agents/code-archaeologist.md +106 -0
- package/.agent/agents/database-architect.md +225 -0
- package/.agent/agents/debugger.md +225 -0
- package/.agent/agents/devops-engineer.md +242 -0
- package/.agent/agents/documentation-writer.md +104 -0
- package/.agent/agents/explorer-agent.md +73 -0
- package/.agent/agents/frontend-specialist.md +618 -0
- package/.agent/agents/game-developer.md +162 -0
- package/.agent/agents/mobile-developer.md +382 -0
- package/.agent/agents/orchestrator.md +438 -0
- package/.agent/agents/penetration-tester.md +188 -0
- package/.agent/agents/performance-optimizer.md +187 -0
- package/.agent/agents/product-manager.md +112 -0
- package/.agent/agents/product-owner.md +95 -0
- package/.agent/agents/project-planner.md +405 -0
- package/.agent/agents/qa-automation-engineer.md +103 -0
- package/.agent/agents/security-auditor.md +170 -0
- package/.agent/agents/seo-specialist.md +111 -0
- package/.agent/agents/test-engineer.md +158 -0
- package/.agent/mcp_config.json +12 -0
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/skills/api-patterns/SKILL.md +84 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +74 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +57 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/bash-linux/SKILL.md +201 -0
- package/.agent/skills/behavioral-modes/SKILL.md +264 -0
- package/.agent/skills/brainstorming/SKILL.md +164 -0
- package/.agent/skills/brainstorming/dynamic-questioning.md +359 -0
- package/.agent/skills/clean-code/SKILL.md +200 -0
- package/.agent/skills/code-review-checklist/SKILL.md +125 -0
- package/.agent/skills/database-design/SKILL.md +54 -0
- package/.agent/skills/database-design/database-selection.md +43 -0
- package/.agent/skills/database-design/indexing.md +39 -0
- package/.agent/skills/database-design/migrations.md +50 -0
- package/.agent/skills/database-design/optimization.md +36 -0
- package/.agent/skills/database-design/orm-selection.md +30 -0
- package/.agent/skills/database-design/schema-design.md +56 -0
- package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
- package/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/documentation-templates/SKILL.md +194 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +307 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +727 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1118 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/.agent/skills/game-development/SKILL.md +167 -0
- package/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +155 -0
- package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/intelligent-routing/SKILL.md +335 -0
- package/.agent/skills/lint-and-validate/SKILL.md +44 -0
- package/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -0
- package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/mobile-design/SKILL.md +394 -0
- package/.agent/skills/mobile-design/decision-trees.md +516 -0
- package/.agent/skills/mobile-design/mobile-backend.md +491 -0
- package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
- package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
- package/.agent/skills/mobile-design/mobile-design-thinking.md +355 -0
- package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
- package/.agent/skills/mobile-design/mobile-performance.md +767 -0
- package/.agent/skills/mobile-design/mobile-testing.md +356 -0
- package/.agent/skills/mobile-design/mobile-typography.md +432 -0
- package/.agent/skills/mobile-design/platform-android.md +666 -0
- package/.agent/skills/mobile-design/platform-ios.md +561 -0
- package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
- package/.agent/skills/mobile-design/touch-psychology.md +537 -0
- package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +311 -0
- package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +241 -0
- package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +489 -0
- package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +263 -0
- package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
- package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +431 -0
- package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +683 -0
- package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +149 -0
- package/.agent/skills/nextjs-react-expert/SKILL.md +286 -0
- package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
- package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
- package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
- package/.agent/skills/parallel-agents/SKILL.md +194 -0
- package/.agent/skills/performance-profiling/SKILL.md +149 -0
- package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/.agent/skills/plan-writing/SKILL.md +152 -0
- package/.agent/skills/powershell-windows/SKILL.md +166 -0
- package/.agent/skills/python-patterns/SKILL.md +441 -0
- package/.agent/skills/red-team-tactics/SKILL.md +203 -0
- package/.agent/skills/rust-pro/SKILL.md +190 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +135 -0
- package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +215 -0
- package/.agent/skills/server-management/SKILL.md +161 -0
- package/.agent/skills/systematic-debugging/SKILL.md +114 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
- package/.agent/skills/tdd-workflow/SKILL.md +149 -0
- package/.agent/skills/testing-patterns/SKILL.md +178 -0
- package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
- package/.agent/skills/vulnerability-scanner/checklists.md +131 -0
- package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +459 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/skills/webapp-testing/SKILL.md +187 -0
- package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +242 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +80 -0
- package/.agent/workflows/restore-localize-compat.md +525 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +295 -0
- package/AGENT_FLOW.md +609 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +260 -0
- package/bin/adapters/base.js +63 -0
- package/bin/adapters/codex.js +391 -0
- package/bin/adapters/gemini.js +137 -0
- package/bin/ag-kit.js +1336 -0
- package/bin/core/builder.js +80 -0
- package/bin/core/generator.js +59 -0
- package/bin/core/resource-loader.js +64 -0
- package/bin/core/transformer.js +208 -0
- package/bin/interactive.js +65 -0
- package/bin/utils/atomic-writer.js +97 -0
- package/bin/utils/git-helper.js +68 -0
- package/bin/utils/managed-block.js +65 -0
- package/bin/utils/manifest.js +241 -0
- package/bin/utils.js +82 -0
- package/docs/codex-rules-template.md +36 -0
- package/docs/mapping-spec.md +68 -0
- package/docs/multi-target-adapter.md +80 -0
- package/docs/official/README.md +53 -0
- package/docs/official/antigravity/agent-modes-settings.md +64 -0
- package/docs/official/antigravity/rules-workflows.md +96 -0
- package/docs/official/antigravity/skills.md +147 -0
- package/docs/official/codex/agents-md.md +119 -0
- package/docs/official/codex/config-advanced.md +358 -0
- package/docs/official/codex/config-basic.md +141 -0
- package/docs/official/codex/config-reference.md +223 -0
- package/docs/official/codex/config-sample.md +216 -0
- package/docs/official/codex/mcp.md +107 -0
- package/docs/official/codex/rules.md +79 -0
- package/docs/official/codex/skills.md +114 -0
- package/docs/official/sources-index.md +32 -0
- package/docs/operations.md +145 -0
- package/docs/terminology-style-guide.md +69 -0
- package/package.json +51 -0
- package/scripts/postinstall-check.js +112 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-design
|
|
3
|
+
description: 数据库设计原则与决策(Database design)。包含模式设计、索引策略、ORM 选择与 Serverless 数据库。
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 数据库设计
|
|
8
|
+
|
|
9
|
+
> **学习如何思考(THINK)**,而非机械复制 SQL 模式。
|
|
10
|
+
|
|
11
|
+
## 🎯 选择性阅读规则
|
|
12
|
+
|
|
13
|
+
**仅阅读与请求相关的文档!** 查阅内容地图,找到所需信息。
|
|
14
|
+
|
|
15
|
+
| 文件 | 描述 | 阅读时机 |
|
|
16
|
+
| ---- | ---- | -------- |
|
|
17
|
+
| `database-selection.md` | PostgreSQL vs Neon vs Turso vs SQLite | 选择数据库时 |
|
|
18
|
+
| `orm-selection.md` | Drizzle vs Prisma vs Kysely | 选择 ORM 时 |
|
|
19
|
+
| `schema-design.md` | 范式化、主键、关系设计 | 设计模式时 |
|
|
20
|
+
| `indexing.md` | 索引类型、复合索引 | 性能调优时 |
|
|
21
|
+
| `optimization.md` | N+1 问题、EXPLAIN ANALYZE | 查询优化时 |
|
|
22
|
+
| `migrations.md` | 安全迁移、Serverless 数据库 | 模式变更时 |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## ⚠️ 核心原则
|
|
27
|
+
|
|
28
|
+
- 需求不明确时,主动询问数据库偏好。
|
|
29
|
+
- 根据实际上下文选择数据库与 ORM。
|
|
30
|
+
- 不要任何场景都默认使用 PostgreSQL。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 决策检查清单
|
|
35
|
+
|
|
36
|
+
在设计模式(Schema)之前:
|
|
37
|
+
|
|
38
|
+
- [ ] **是否已询问数据库偏好?**
|
|
39
|
+
- [ ] **是否为当前上下文选择了合适的数据库?**
|
|
40
|
+
- [ ] **是否考虑了部署环境?**
|
|
41
|
+
- [ ] **是否规划了索引策略?**
|
|
42
|
+
- [ ] **是否定义了关系类型?**
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 反模式
|
|
47
|
+
|
|
48
|
+
❌ 为简单应用默认使用 PostgreSQL(SQLite 可能已足够)
|
|
49
|
+
❌ 忽略索引设计
|
|
50
|
+
❌ 在生产环境中使用 `SELECT *`
|
|
51
|
+
❌ 在结构化数据更优时强行存储 JSON
|
|
52
|
+
❌ 忽略 N+1 查询问题
|
|
53
|
+
|
|
54
|
+
---
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# 数据库选择(2025)
|
|
2
|
+
|
|
3
|
+
> 根据上下文选择数据库,不要只用默认选项。
|
|
4
|
+
|
|
5
|
+
## 决策树
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
您的需求是什么?
|
|
9
|
+
│
|
|
10
|
+
├── 需要完整的关系型功能
|
|
11
|
+
│ ├── 自托管(Self-hosted) → PostgreSQL
|
|
12
|
+
│ └── 无服务器(Serverless) → Neon, Supabase
|
|
13
|
+
│
|
|
14
|
+
├── 边缘部署(edge)/ 超低延迟
|
|
15
|
+
│ └── Turso(边缘级 SQLite)
|
|
16
|
+
│
|
|
17
|
+
├── AI / 向量搜索(vector search)
|
|
18
|
+
│ └── PostgreSQL + pgvector
|
|
19
|
+
│
|
|
20
|
+
├── 简单 / 嵌入式 / 本地存储
|
|
21
|
+
│ └── SQLite
|
|
22
|
+
│
|
|
23
|
+
└── 全球分布式挂载
|
|
24
|
+
└── PlanetScale, CockroachDB, Turso
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 各数据库对比
|
|
28
|
+
|
|
29
|
+
| 数据库 | 最佳适用 | 权衡 |
|
|
30
|
+
| ------ | -------- | ------------------ |
|
|
31
|
+
| **PostgreSQL** | 全功能,复杂查询 | 需要托管 |
|
|
32
|
+
| **Neon** | Serverless PG(无服务器 PostgreSQL),分支功能 | PG 自身的复杂度 |
|
|
33
|
+
| **Turso** | 边缘环境,低延迟 | SQLite 的局限性 |
|
|
34
|
+
| **SQLite** | 简单、嵌入式、本地 | 单个写入者(single-writer)限制 |
|
|
35
|
+
| **PlanetScale** | MySQL,全球量级扩展 | 无外键约束支持 |
|
|
36
|
+
|
|
37
|
+
## 需要问的问题
|
|
38
|
+
|
|
39
|
+
1. 部署环境是什么?(Serverless(无服务器)、容器、虚拟机等)
|
|
40
|
+
2. 查询有多复杂?(是否涉及深度嵌套、地理空间等)
|
|
41
|
+
3. Edge(边缘)/Serverless(无服务器)特性是否重要?
|
|
42
|
+
4. 是否需要向量搜索功能?
|
|
43
|
+
5. 是否需要全球分布支持?
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 索引原则
|
|
2
|
+
|
|
3
|
+
> 选对时机和方式,高效创建索引。
|
|
4
|
+
|
|
5
|
+
## 何时创建索引
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
应该建立索引的情况:
|
|
9
|
+
├── WHERE 子句中使用的列
|
|
10
|
+
├── JOIN 连接条件中使用的列
|
|
11
|
+
├── ORDER BY 中使用的列
|
|
12
|
+
├── 外键(foreign key)列
|
|
13
|
+
└── 唯一性约束(unique constraints)列
|
|
14
|
+
|
|
15
|
+
避免过度索引的情况:
|
|
16
|
+
├── 写操作频繁的表(会降低插入速度)
|
|
17
|
+
├── 区分度低(low-cardinality)的列
|
|
18
|
+
├── 很少被查询的列
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 索引类型选择
|
|
22
|
+
|
|
23
|
+
| 类型 | 用途 |
|
|
24
|
+
| ---- | ---- |
|
|
25
|
+
| **B-tree** | 通用目的,等值和范围查询 |
|
|
26
|
+
| **Hash** | 仅等值查询,速度更快 |
|
|
27
|
+
| **GIN** | JSONB、数组、全文搜索 |
|
|
28
|
+
| **GiST** | 几何、物理范围类型 |
|
|
29
|
+
| **HNSW/IVFFlat** | 向量相似度(pgvector) |
|
|
30
|
+
|
|
31
|
+
## 复合索引原则
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
复合索引的列顺序至关重要:
|
|
35
|
+
├── 等值过滤列在前(equality)
|
|
36
|
+
├── 范围过滤列在后(range)
|
|
37
|
+
├── 区分度高(指重复率低)的列在前
|
|
38
|
+
└── 必须匹配查询模式中的列序
|
|
39
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 迁移原则
|
|
2
|
+
|
|
3
|
+
> 面向零停机变更的安全迁移策略。
|
|
4
|
+
|
|
5
|
+
## 安全迁移策略
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
零停机变更建议:
|
|
9
|
+
│
|
|
10
|
+
├── 新增列(adding column)
|
|
11
|
+
│ └── 先设为 nullable(可为空) → 回填数据 → 再加 NOT NULL
|
|
12
|
+
│
|
|
13
|
+
├── 删除列(removing column)
|
|
14
|
+
│ └── 先停止使用 → 部署过渡版本 → 再删除列
|
|
15
|
+
│
|
|
16
|
+
├── 新增索引(adding index)
|
|
17
|
+
│ └── `CREATE INDEX CONCURRENTLY`(非阻塞)
|
|
18
|
+
│
|
|
19
|
+
└── 重命名列(renaming column)
|
|
20
|
+
└── 新增新列 → 迁移数据 → 部署 → 删除旧列
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 迁移哲学
|
|
24
|
+
|
|
25
|
+
- 不要一步到位做破坏性变更
|
|
26
|
+
- 先在数据副本上验证迁移
|
|
27
|
+
- 预先准备回滚方案
|
|
28
|
+
- 在可行场景下使用事务包裹
|
|
29
|
+
|
|
30
|
+
## Serverless 数据库
|
|
31
|
+
|
|
32
|
+
### Neon(Serverless PostgreSQL)
|
|
33
|
+
|
|
34
|
+
| 特性 | 价值 |
|
|
35
|
+
| -------------- | -------------- |
|
|
36
|
+
| Scale to zero(零实例) | 节省成本 |
|
|
37
|
+
| Instant branching(即时分支) | 开发/预览环境方便 |
|
|
38
|
+
| Full PostgreSQL(完整 PostgreSQL) | 兼容生态成熟 |
|
|
39
|
+
| Autoscaling(自动伸缩) | 自动应对流量波动 |
|
|
40
|
+
|
|
41
|
+
### Turso(Edge SQLite)
|
|
42
|
+
|
|
43
|
+
| 特性 | 价值 |
|
|
44
|
+
| -------------- | -------------- |
|
|
45
|
+
| Edge locations(边缘节点) | 超低延迟 |
|
|
46
|
+
| SQLite compatible(兼容 SQLite) | 使用简单 |
|
|
47
|
+
| Generous free tier(较大免费额度) | 成本友好 |
|
|
48
|
+
| Global distribution(全球分布) | 全球访问性能更好 |
|
|
49
|
+
|
|
50
|
+
<!-- /preview -->
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# 查询优化
|
|
2
|
+
|
|
3
|
+
> 解决 N+1 问题、使用 EXPLAIN ANALYZE(执行计划分析)、以及优化优先级。
|
|
4
|
+
|
|
5
|
+
## N+1 问题
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
什么是 N+1?
|
|
9
|
+
├── 用 1 条查询获取父记录(parent records)
|
|
10
|
+
├── 用 N 条查询分别获取每条父记录的关联记录
|
|
11
|
+
└── 结果:极其缓慢!
|
|
12
|
+
|
|
13
|
+
解决方案:
|
|
14
|
+
├── JOIN → 一个查询获取所有数据
|
|
15
|
+
├── 预加载(eager loading) → 让 ORM 处理 JOIN
|
|
16
|
+
├── DataLoader → 批量处理并缓存(多用于 GraphQL)
|
|
17
|
+
└── 子查询(subquery) → 在一个查询中批量获取关联数据
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 查询分析思维
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
在开始优化前:
|
|
24
|
+
├── 对查询执行 EXPLAIN ANALYZE
|
|
25
|
+
├── 寻找 Seq Scan(全表扫描)
|
|
26
|
+
├── 检查 实际行数(actual) vs 预估行数(estimated)
|
|
27
|
+
└── 识别缺失的索引
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 优化优先级
|
|
31
|
+
|
|
32
|
+
1. **添加缺失的索引**(这是最常见的问题)
|
|
33
|
+
2. **仅选择需要的列**(严禁使用 `SELECT *`)
|
|
34
|
+
3. **使用正确的 JOIN**(尽可能避免不必要的子查询)
|
|
35
|
+
4. **尽早限制结果集**(在数据库层面执行分页 `LIMIT`)
|
|
36
|
+
5. **引入缓存**(在合适的应用场景下)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# ORM 选择(2025)
|
|
2
|
+
|
|
3
|
+
> 根据部署需求和开发体验(DX)选择 ORM。
|
|
4
|
+
|
|
5
|
+
## 决策树
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
开发背景是什么?
|
|
9
|
+
│
|
|
10
|
+
├── 边缘部署(edge)/ 关注包体积
|
|
11
|
+
│ └── Drizzle(体积最小,贴近 SQL 语法)
|
|
12
|
+
│
|
|
13
|
+
├── 最佳开发体验(DX)/ schema(模式)优先
|
|
14
|
+
│ └── Prisma(自带迁移工具和可视化 Studio(控制台))
|
|
15
|
+
│
|
|
16
|
+
├── 追求最大控制权
|
|
17
|
+
│ └── 原始 SQL 配合查询构造器(query builder)
|
|
18
|
+
│
|
|
19
|
+
└── Python 生态
|
|
20
|
+
└── SQLAlchemy 2.0(支持异步)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 各 ORM 对比
|
|
24
|
+
|
|
25
|
+
| ORM | 最佳适用 | 权衡 |
|
|
26
|
+
| --- | -------- | ------------------ |
|
|
27
|
+
| **Drizzle** | 边缘端环境,TypeScript | 相对较新,生态示例较少 |
|
|
28
|
+
| **Prisma** | 开发体验,Schema 管理 | 运行较重,边缘端支持不佳 |
|
|
29
|
+
| **Kysely** | 类型安全的 SQL 构造器 | 需要手动管理迁移 |
|
|
30
|
+
| **Raw SQL(原始 SQL)** | 复杂查询,极致控制权 | 需要手动维护类型安全 |
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Schema(模式)设计原则
|
|
2
|
+
|
|
3
|
+
> 范式化、主键选择、时间戳策略以及关系建模。
|
|
4
|
+
|
|
5
|
+
## 范式化决策
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
何时进行范式化(normalization,拆分表):
|
|
9
|
+
├── 数据在多行之间重复出现
|
|
10
|
+
├── 更新操作需要修改多个地方
|
|
11
|
+
├── 实体间关系清晰明确
|
|
12
|
+
├── 查询模式能从拆分中获益(如减少冗余扫描)
|
|
13
|
+
|
|
14
|
+
何时进行反范式化(denormalization,嵌入/重复数据):
|
|
15
|
+
├── 读性能至关重要(减少 JOIN)
|
|
16
|
+
├── 数据极少发生变更
|
|
17
|
+
├── 相关数据总是被一起获取
|
|
18
|
+
├── 需要极简的查询语句
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 主键选择
|
|
22
|
+
|
|
23
|
+
| 类型 | 使用场景 |
|
|
24
|
+
| ---- | -------- |
|
|
25
|
+
| **UUID** | 分布式系统,安全性考虑(不泄露数据量) |
|
|
26
|
+
| **ULID** | 具备 UUID 性质 + 可按时间排序 |
|
|
27
|
+
| **自增(auto-increment)** | 简单应用,单一数据库环境 |
|
|
28
|
+
| **自然主键(natural key)** | 极少使用(具有业务含义的列) |
|
|
29
|
+
|
|
30
|
+
## 时间戳策略
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
建议为每一张表添加:
|
|
34
|
+
├── created_at → 创建时间
|
|
35
|
+
├── updated_at → 最后修改时间
|
|
36
|
+
└── deleted_at → 软删除时间(如果需要)
|
|
37
|
+
|
|
38
|
+
务必使用 TIMESTAMPTZ(带时区)而非原生 TIMESTAMP
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 关系类型
|
|
42
|
+
|
|
43
|
+
| 类型 | 场景 | 实现方式 |
|
|
44
|
+
| ---- | ---- | -------- |
|
|
45
|
+
| **一对一(One-to-One)** | 扩展数据 | 独立表并通过外键关联 |
|
|
46
|
+
| **一对多(One-to-Many)** | 父子、归属关系 | 在子表上建立外键 |
|
|
47
|
+
| **多对多(Many-to-Many)** | 双方均有复数关联 | 建立关联表(Junction table) |
|
|
48
|
+
|
|
49
|
+
## 外键删除策略
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
├── CASCADE → 随父记录一起级联删除子记录
|
|
53
|
+
├── SET NULL → 父记录删除后,子记录关联字段设为 NULL(变孤儿)
|
|
54
|
+
├── RESTRICT → 如果存在子记录,则阻止删除父记录
|
|
55
|
+
└── SET DEFAULT → 父记录删除后,子记录设为默认值
|
|
56
|
+
```
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Schema Validator - Database schema validation
|
|
4
|
+
Validates Prisma schemas and checks for common issues.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python schema_validator.py <project_path>
|
|
8
|
+
|
|
9
|
+
Checks:
|
|
10
|
+
- Prisma schema syntax
|
|
11
|
+
- Missing relations
|
|
12
|
+
- Index recommendations
|
|
13
|
+
- Naming conventions
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import sys
|
|
17
|
+
import json
|
|
18
|
+
import re
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
|
|
22
|
+
# Fix Windows console encoding
|
|
23
|
+
try:
|
|
24
|
+
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|
25
|
+
except:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def find_schema_files(project_path: Path) -> list:
|
|
30
|
+
"""Find database schema files."""
|
|
31
|
+
schemas = []
|
|
32
|
+
|
|
33
|
+
# Prisma schema
|
|
34
|
+
prisma_files = list(project_path.glob('**/prisma/schema.prisma'))
|
|
35
|
+
schemas.extend([('prisma', f) for f in prisma_files])
|
|
36
|
+
|
|
37
|
+
# Drizzle schema files
|
|
38
|
+
drizzle_files = list(project_path.glob('**/drizzle/*.ts'))
|
|
39
|
+
drizzle_files.extend(project_path.glob('**/schema/*.ts'))
|
|
40
|
+
for f in drizzle_files:
|
|
41
|
+
if 'schema' in f.name.lower() or 'table' in f.name.lower():
|
|
42
|
+
schemas.append(('drizzle', f))
|
|
43
|
+
|
|
44
|
+
return schemas[:10] # Limit
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def validate_prisma_schema(file_path: Path) -> list:
|
|
48
|
+
"""Validate Prisma schema file."""
|
|
49
|
+
issues = []
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
content = file_path.read_text(encoding='utf-8', errors='ignore')
|
|
53
|
+
|
|
54
|
+
# Find all models
|
|
55
|
+
models = re.findall(r'model\s+(\w+)\s*{([^}]+)}', content, re.DOTALL)
|
|
56
|
+
|
|
57
|
+
for model_name, model_body in models:
|
|
58
|
+
# Check naming convention (PascalCase)
|
|
59
|
+
if not model_name[0].isupper():
|
|
60
|
+
issues.append(f"Model '{model_name}' should be PascalCase")
|
|
61
|
+
|
|
62
|
+
# Check for id field
|
|
63
|
+
if '@id' not in model_body and 'id' not in model_body.lower():
|
|
64
|
+
issues.append(f"Model '{model_name}' might be missing @id field")
|
|
65
|
+
|
|
66
|
+
# Check for createdAt/updatedAt
|
|
67
|
+
if 'createdAt' not in model_body and 'created_at' not in model_body:
|
|
68
|
+
issues.append(f"Model '{model_name}' missing createdAt field (recommended)")
|
|
69
|
+
|
|
70
|
+
# Check for @relation without fields
|
|
71
|
+
relations = re.findall(r'@relation\([^)]*\)', model_body)
|
|
72
|
+
for rel in relations:
|
|
73
|
+
if 'fields:' not in rel and 'references:' not in rel:
|
|
74
|
+
pass # Implicit relation, ok
|
|
75
|
+
|
|
76
|
+
# Check for @@index suggestions
|
|
77
|
+
foreign_keys = re.findall(r'(\w+Id)\s+\w+', model_body)
|
|
78
|
+
for fk in foreign_keys:
|
|
79
|
+
if f'@@index([{fk}])' not in content and f'@@index(["{fk}"])' not in content:
|
|
80
|
+
issues.append(f"Consider adding @@index([{fk}]) for better query performance in {model_name}")
|
|
81
|
+
|
|
82
|
+
# Check for enum definitions
|
|
83
|
+
enums = re.findall(r'enum\s+(\w+)\s*{', content)
|
|
84
|
+
for enum_name in enums:
|
|
85
|
+
if not enum_name[0].isupper():
|
|
86
|
+
issues.append(f"Enum '{enum_name}' should be PascalCase")
|
|
87
|
+
|
|
88
|
+
except Exception as e:
|
|
89
|
+
issues.append(f"Error reading schema: {str(e)[:50]}")
|
|
90
|
+
|
|
91
|
+
return issues
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def main():
|
|
95
|
+
project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
|
|
96
|
+
|
|
97
|
+
print(f"\n{'='*60}")
|
|
98
|
+
print(f"[SCHEMA VALIDATOR] Database Schema Validation")
|
|
99
|
+
print(f"{'='*60}")
|
|
100
|
+
print(f"Project: {project_path}")
|
|
101
|
+
print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
102
|
+
print("-"*60)
|
|
103
|
+
|
|
104
|
+
# Find schema files
|
|
105
|
+
schemas = find_schema_files(project_path)
|
|
106
|
+
print(f"Found {len(schemas)} schema files")
|
|
107
|
+
|
|
108
|
+
if not schemas:
|
|
109
|
+
output = {
|
|
110
|
+
"script": "schema_validator",
|
|
111
|
+
"project": str(project_path),
|
|
112
|
+
"schemas_checked": 0,
|
|
113
|
+
"issues_found": 0,
|
|
114
|
+
"passed": True,
|
|
115
|
+
"message": "No schema files found"
|
|
116
|
+
}
|
|
117
|
+
print(json.dumps(output, indent=2))
|
|
118
|
+
sys.exit(0)
|
|
119
|
+
|
|
120
|
+
# Validate each schema
|
|
121
|
+
all_issues = []
|
|
122
|
+
|
|
123
|
+
for schema_type, file_path in schemas:
|
|
124
|
+
print(f"\nValidating: {file_path.name} ({schema_type})")
|
|
125
|
+
|
|
126
|
+
if schema_type == 'prisma':
|
|
127
|
+
issues = validate_prisma_schema(file_path)
|
|
128
|
+
else:
|
|
129
|
+
issues = [] # Drizzle validation could be added
|
|
130
|
+
|
|
131
|
+
if issues:
|
|
132
|
+
all_issues.append({
|
|
133
|
+
"file": str(file_path.name),
|
|
134
|
+
"type": schema_type,
|
|
135
|
+
"issues": issues
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
# Summary
|
|
139
|
+
print("\n" + "="*60)
|
|
140
|
+
print("SCHEMA ISSUES")
|
|
141
|
+
print("="*60)
|
|
142
|
+
|
|
143
|
+
if all_issues:
|
|
144
|
+
for item in all_issues:
|
|
145
|
+
print(f"\n{item['file']} ({item['type']}):")
|
|
146
|
+
for issue in item["issues"][:5]: # Limit per file
|
|
147
|
+
print(f" - {issue}")
|
|
148
|
+
if len(item["issues"]) > 5:
|
|
149
|
+
print(f" ... and {len(item['issues']) - 5} more issues")
|
|
150
|
+
else:
|
|
151
|
+
print("No schema issues found!")
|
|
152
|
+
|
|
153
|
+
total_issues = sum(len(item["issues"]) for item in all_issues)
|
|
154
|
+
# Schema issues are warnings, not failures
|
|
155
|
+
passed = True
|
|
156
|
+
|
|
157
|
+
output = {
|
|
158
|
+
"script": "schema_validator",
|
|
159
|
+
"project": str(project_path),
|
|
160
|
+
"schemas_checked": len(schemas),
|
|
161
|
+
"issues_found": total_issues,
|
|
162
|
+
"passed": passed,
|
|
163
|
+
"issues": all_issues
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
print("\n" + json.dumps(output, indent=2))
|
|
167
|
+
|
|
168
|
+
sys.exit(0)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
if __name__ == "__main__":
|
|
172
|
+
main()
|