Files
AIclinicalresearch/docs/09-架构实施/02-数据库连接配置.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

693 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# <20>唳旿摨栞<E691A8><E6A09E>仿<EFBFBD>蝵?
> **<2A><><EFBFBD><EFB99D>𧋦嚗?* v1.0
> **<2A>𥕦遣<F0A595A6><EFBFBD>嚗?* 2025-11-09
> **蝏湔擪<E6B994><E693AA><EFBFBD>** <20><EFBFBD><E59786><EFBFBD>
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-11-09
---
## <20><> <20><>﹝霂湔<E99C82>
<EFBFBD><EFBFBD><EFBFBD>扇敶笌chema<EFBFBD>𠉛氖<EFBFBD><EFBFBD>摰墧鴌<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>餈墧𦻖<EFBFBD><EFBFBD>蝵桐縑<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡠺嚗?- 敶枏<E695B6><E69E8F>唳旿摨梶𠶖<E6A2B6>?- Schema<6D>𠉛氖餈<E6B096><EFBFBD>滨蔭
-<>宏餈<E5AE8F><E9A488><EFBFBD><EFBFBD><EFBFBD><EFBFBD>交䲮撘?- 撉諹<E69289><E8ABB9><EFBFBD><EFBFBD>皛𡁏䲮獢?
---
## <20><>儭?敶枏<E695B6><E69E8F>唳旿摨梶𠶖<E6A2B6>?
### <20>唳旿摨枏抅<E69E8F>砌縑<E7A08C>?
**餈墧𦻖靽⊥<E99DBD>嚗?*
```
<EFBFBD>唳旿摨梶掩<EFBFBD><EFBFBD>PostgreSQL 15+
<EFBFBD>唳旿摨枏<EFBFBD>蝘堆<EFBFBD>ai_clinical_research
銝餅㦤<EFBFBD><EFBFBD>嚗? localhost
蝡臬藁嚗? 5432
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> postgres
<EFBFBD><EFBFBD>嚗? postgres
```
**摰峕㟲餈墧𦻖摮㛖泵銝莎<E98A9D>**
```
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
```
---
### 敶枏<E695B6>Schema蝏𤘪<E89D8F>
**<EFBFBD><EFBFBD>Schema嚗?*
- <20>?**public** - <20><><EFBFBD>?3銝芾”<E88ABE>賢銁餈䠷<E9A488>
**銵冽<E98AB5><E586BD>𤏪<EFBFBD>13銝迎<E98A9D>嚗?*
#### 1. 撟喳蝱<E596B3><EFBFBD>嚗?銝芾”嚗?```sql
public.users -- <20><EFBFBD>銵?public.admin_logs -- 蝞∠<E89D9E><E288A0><EFBFBD>
```
#### 2. AI<41><EFBFBD><E7AE84><EFBFBD>嚗?銝芾”嚗?```sql
public.projects -- 憿寧𤌍蝞∠<E89D9E>
public.conversations -- 憿寧𤌍撖寡<E69296>
public.messages -- 撖寡<E69296><EFBFBD><E798A8>
public.general_conversations -- <20>𡁶鍂撖寡<E69296>
public.general_messages -- <20>𡁶鍂瘨<E98D82><E798A8>
```
#### 3. 銝芯犖<E88AAF><EFBFBD>摨橒<E691A8>2銝芾”嚗?```sql
public.knowledge_bases -- <20><EFBFBD>摨?public.documents -- <20><>
```
#### 4. <20><EFBFBD><E5ADB5><EFBFBD>頂蝏<E9A082><E89D8F>3銝芾”嚗?```sql
public.batch_tasks -- <20><EFBFBD><E5ADB5><EFBFBD><EFBFBD>?public.batch_results -- <20><EFBFBD><E5ADB5><EFBFBD><EFBFBD><EFBFBD>?public.task_templates -- 隞餃𦛚璅⊥踎
```
#### 5. 蝔蹂辣摰⊥䰻嚗?銝芾”嚗?```sql
public.review_tasks -- 摰⊥䰻隞餃𦛚
```
---
### <20>唳旿摨梶<E691A8>霈∩縑<E288A9>?
**銵冽㺭<E586BD>𧶏<EFBFBD>** 13銝?
**蝝<E89D9D><EFBCB7><EFBFBD>嚗?* 蝥?0銝?
**憭㚚睸蝥行<E89DA5>嚗?* 蝥?5銝?
**敶枏<E695B6><E69E8F>唳旿<E594B3>𧶏<EFBFBD>隡啁<E99AA1>嚗㚁<E59A97>**
- users: ~10<31>?- projects: ~20<32>?- conversations: ~50<35>?- messages: ~500<30>?- knowledge_bases: ~5<>?- documents: ~30<33>?- <20><EFBFBD>銵剁<E98AB5>瘚贝<E7989A><E8B49D>唳旿
**<2A>餅㺭<E9A485><EFBFBD>嚗?* < 10MB嚗<42><E59A97>霂閧㴓憓<E3B493><E68693>
---
## <20>㴓 Schema<6D>𠉛氖<F0A0899B><EFBFBD><E6A0BC><EFBFBD>
### 10銝芰𡠺蝡喹chema
#### <20><><EFBFBD>祕蝏<E7A595>挽霈?<3F>唳旿餈<E697BF>宏嚗?銝迎<E98A9D>
**1. platform_schema嚗<61><EFBFBD>啣抅蝖<E68A85><EFBFBD><E69285>**
```sql
-- 餈<>宏銵剁<E98AB5>
public.users <20>?platform_schema.users
public.admin_logs <20>?platform_schema.admin_logs 嚗<><E59A97>蝻橒<E89DBB><EFBFBD>霈歹<E99C88>
```
**2. common_schema嚗<61><E59A97>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>**
```sql
-- <20>啣遣銵剁<E98AB5>
common_schema.llm_usage -- LLM雿輻鍂霈啣<E99C88>
common_schema.feature_flags -- Feature Flags
```
**3. asl_schema嚗㇁I<E38781><EFBFBD><E7AE84><EFBFBD>讃嚗?*
```sql
-- <20>啣遣銵剁<E98AB5>
asl_schema.literature_projects -- <20><>讃憿寧𤌍
asl_schema.pico_configs -- PICO<43>滨蔭
asl_schema.literature_items -- <20><><EFBFBD>∠𤌍
-- <20><EFBFBD>銵刻<E98AB5>ASL霈曇恣<E69B87><E681A3>
```
**4. aia_schema嚗㇁I<E38781><EFBFBD><E7AE84><EFBFBD>嚗?*
```sql
-- 餈<>宏銵剁<E98AB5>
public.projects <EFBFBD>?aia_schema.projects
public.conversations <EFBFBD>?aia_schema.conversations
public.messages <EFBFBD>?aia_schema.messages
public.general_conversations <EFBFBD>?aia_schema.general_conversations
public.general_messages <EFBFBD>?aia_schema.general_messages
```
**5. pkb_schema嚗<61>葵鈭箇䰻霂<E4B0BB><E99C82>嚗?*
```sql
-- 餈<>宏銵剁<E98AB5>
public.knowledge_bases <EFBFBD>?pkb_schema.knowledge_bases
public.documents <EFBFBD>?pkb_schema.documents
```
#### <20><EFBFBD>撱箇征Schema嚗?銝迎<E98A9D>
**6. dc_schema嚗<61><EFBFBD><EFBFBD>瘣梹<E798A3>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
**7. rvw_schema嚗<61>恣蝔輻頂蝏<E9A082><E89D8F>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
**8. admin_schema嚗<61><E59A97><EFBFBD>亦恣<E4BAA6><E681A3><EFBFBD>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
**9. ssa_schema嚗<61><EFBFBD><EFBFBD><E99C88><E288AA><EFBFBD>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
**10. st_schema嚗<61><E59A97><E99C88><E288AA>𣂼極<F0A382BC><EFBFBD>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
---
## <20><><>宏餈<E5AE8F><E9A488>餈墧𦻖<E5A2A7>滨蔭
### 餈<><EFBFBD><EFBFBD>憭?
**1. 憭<>遢敶枏<E695B6><E69E8F>唳旿摨?*
```bash
# Windows PowerShell
cd D:\MyCursor\AIclinicalresearch\backend
# 雿輻鍂pg_dump憭<70>
pg_dump -h localhost -U postgres -d ai_clinical_research -F c -f backup_before_schema_migration_$(Get-Date -Format 'yyyyMMdd_HHmmss').dump
# <20>𤥁<EFBFBD><F0A4A581><EFBFBD>沒QL<51><EFBFBD>
pg_dump -h localhost -U postgres -d ai_clinical_research > backup_before_schema_migration_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql
```
**2. 撉諹<E69289><EFBFBD>**
```bash
# 璉<><E79289><EFBFBD>隞賣<E99A9E>隞嗅之撠?ls -lh backup_*.dump
# 撉諹<E69289><EFBFBD><EFBFBD><E981A2>捆嚗𠄎QL<51><EFBFBD>嚗?head -n 50 backup_*.sql
```
---
### 餈<>宏餈<E5AE8F><E9A488>餈墧𦻖<E5A2A7><EFBFBD>
#### <20><EFBFBD>1嚗帋蝙<E5B88B>沌risma Migrate嚗<65><EFBFBD><EFBFBD>
**餈墧𦻖<E5A2A7>滨蔭嚗?*
```env
# backend/.env
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
```
**<EFBFBD><EFBFBD><EFBFBD>宏嚗?*
```bash
cd backend
# <20>𥕦遣<F0A595A6><EFBFBD><EFBFBD>
npx prisma migrate dev --name schema_isolation_10_schemas
# <20><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?npx prisma migrate status
```
---
#### <20><EFBFBD>2嚗𡁶凒<F0A181B6><EFBFBD>銵玺QL<51>𡁏𧋦
**餈墧𦻖<E5A2A7><EFBFBD>嚗?*
```bash
# 雿輻鍂psql餈墧𦻖
psql -h localhost -U postgres -d ai_clinical_research
# <20>碶蝙<E7A2B6>函㴓憓<E3B493><E68693><EFBFBD>?export PGPASSWORD=postgres
psql -h localhost -U postgres -d ai_clinical_research -f migration_script.sql
```
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡁏𧋦嚗?*
```bash
cd docs/09-<2D><EFBFBD>摰墧鴌/migration-scripts
# <20>厰◇摨𤩺<E691A8>銵?psql -h localhost -U postgres -d ai_clinical_research -f 001-create-all-10-schemas.sql
psql -h localhost -U postgres -d ai_clinical_research -f 002-migrate-platform.sql
psql -h localhost -U postgres -d ai_clinical_research -f 003-migrate-aia.sql
psql -h localhost -U postgres -d ai_clinical_research -f 004-migrate-pkb.sql
# ... <20><EFBFBD><E6B8B8>𡁏𧋦
```
---
#### <20><EFBFBD>3嚗帋蝙<E5B88B>典虾閫<E899BE><E996AB>撌亙<E6928C>
**pgAdmin 4嚗?*
1. 餈墧𦻖靽⊥<E99DBD>嚗? - 銝餅㦤嚗饝ocalhost
- 蝡臬藁嚗?432
- <20>唳旿摨橒<E691A8>ai_clinical_research
- <20><EFBFBD>嚗䮝ostgres
-<><E69296>嚗䮝ostgres
2. <20><EFBFBD><EFBFBD>宏嚗? - <20><EFBFBD>Query Tool
- <20>㰘蝸SQL<51>𡁏𧋦
- <20><EFBFBD>
**DataGrip / DBeaver嚗?*
- <20>峕甅<E5B395><E79485><EFBFBD><EFBFBD>乩縑<E4B9A9>?- <20><EFBFBD>鈭见𦛚蝞∠<E89D9E>
- <20>嫣噶<E5ABA3><EFBFBD>
---
## <20>?餈<>宏撉諹<E69289>
### 1. 璉<><E79289>兄chema<6D>𥕦遣
**SQL撉諹<E69289>嚗?*
```sql
-- <20><EFBFBD><E4BAA6><EFBFBD><EFBFBD>农chema
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name NOT IN ('pg_catalog', 'information_schema')
ORDER BY schema_name;
-- 憸<><E686B8>蝏𤘪<E89D8F>嚗?-- admin_schema
-- aia_schema
-- asl_schema
-- common_schema
-- dc_schema
-- pkb_schema
-- platform_schema
-- public
-- rvw_schema
-- ssa_schema
-- st_schema
```
---
### 2. 璉<><E79289>亥”餈<E2809D>
**撉諹<E69289>platform_schema嚗?*
```sql
-- <20><EFBFBD>銵?SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'platform_schema';
-- 撉諹<E69289><E8ABB9>唳旿
SELECT COUNT(*) FROM platform_schema.users;
-- 憸<><E686B8>嚗帋<E59A97><E5B88B>㸆ublic.users<72><73><EFBFBD><EFBFBD><E8AD8D>?```
**<EFBFBD>aia_schema嚗?*
```sql
-- <20><EFBFBD><E4BAA6><EFBFBD><EFBFBD>㕑”
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'aia_schema';
-- 撉諹<E69289><E8ABB9>唳旿摰峕㟲<E5B395>?SELECT COUNT(*) FROM aia_schema.projects;
SELECT COUNT(*) FROM aia_schema.conversations;
SELECT COUNT(*) FROM aia_schema.messages;
```
**撉諹<E69289>pkb_schema嚗?*
```sql
SELECT COUNT(*) FROM pkb_schema.knowledge_bases;
SELECT COUNT(*) FROM pkb_schema.documents;
```
---
### 3. 撉諹<E69289>憭㚚睸<E39A9A>喟頂
**璉<><E79289>亥楊Schema憭㚚睸嚗?*
```sql
-- <20><EFBFBD><E4BAA6><EFBFBD><EFBFBD><EFBFBD><E58CA7>桃漲<E6A183>?SELECT
tc.table_schema,
tc.table_name,
kcu.column_name,
ccu.table_schema AS foreign_table_schema,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema IN ('platform_schema', 'aia_schema', 'pkb_schema', 'asl_schema', 'common_schema')
ORDER BY tc.table_schema, tc.table_name;
```
---
### 4. 撉諹<E69289><E89D9D>
**璉<><E79289>亦揣撘閙糓<E99699>行迤蝖株<E89D96>蝘鳴<E89D98>**
```sql
-- <20><EFBFBD><E4BAA6>𣂷葵Schema<6D><61><EFBFBD><EFBFBD>厩揣撘?SELECT
schemaname,
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE schemaname = 'aia_schema'
ORDER BY tablename, indexname;
```
---
### 5. Prisma撉諹<E69289>
**<EFBFBD>湔鰵Prisma<EFBFBD>滨蔭<EFBFBD>𡡞<EFBFBD><EFBFBD><EFBFBD>**
```bash
cd backend
# <20><><EFBFBD>Prisma Client
npx prisma generate
# 撉諹<E69289>Prisma Client<6E>舐鍂
npx ts-node -e "import { PrismaClient } from '@prisma/client'; const p = new PrismaClient(); p.user.count().then(console.log)"
```
---
## <20><> <20><EFBFBD><E5A2A7><EFBFBD>
### <20>箸艶1嚗朞<E59A97>蝘餉<E89D98>蝔衤葉<E8A1A4>𤑳緵<F0A491B3><EFBFBD>
**蝡见朖<E8A781><EFBFBD>嚗?*
```bash
# 憒<><E68692>雿輻鍂Prisma Migrate
npx prisma migrate reset
# <20><EFBFBD><EFBFBD>
psql -h localhost -U postgres -d ai_clinical_research < backup_before_schema_migration_YYYYMMDD_HHMMSS.sql
```
---
### <20>箸艶2嚗朞<E59A97>蝘餃<E89D98><E9A483>𣂼<EFBFBD><F0A382BC>𤑳緵<F0A491B3><EFBFBD>
**<EFBFBD><EFBFBD>A嚗帋<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
```bash
# 1. <20>𣳇膄敶枏<E695B6><E69E8F>唳旿摨?dropdb -h localhost -U postgres ai_clinical_research
# 2. <20>齿鰵<E9BDBF>𥕦遣
createdb -h localhost -U postgres ai_clinical_research
# 3. <20><EFBFBD><EFBFBD>
pg_restore -h localhost -U postgres -d ai_clinical_research backup_before_schema_migration_YYYYMMDD_HHMMSS.dump
```
**<EFBFBD><EFBFBD>B嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>斗鰵Schema嚗䔶<EFBFBD><EFBFBD>炠ublic**
```sql
-- <20>𣳇膄<F0A3B387>啣遣<E595A3><E981A3>chema嚗<61><E59A97><EFBFBD><EFBFBD>嚗?DROP SCHEMA IF EXISTS platform_schema CASCADE;
DROP SCHEMA IF EXISTS aia_schema CASCADE;
DROP SCHEMA IF EXISTS pkb_schema CASCADE;
DROP SCHEMA IF EXISTS asl_schema CASCADE;
DROP SCHEMA IF EXISTS common_schema CASCADE;
DROP SCHEMA IF EXISTS dc_schema CASCADE;
DROP SCHEMA IF EXISTS rvw_schema CASCADE;
DROP SCHEMA IF EXISTS admin_schema CASCADE;
DROP SCHEMA IF EXISTS ssa_schema CASCADE;
DROP SCHEMA IF EXISTS st_schema CASCADE;
-- public schema<6D><61>”憒<E2809D><E68692>鋡怠<E98BA1><E680A0><EFBFBD>嚗䔶<E59A97><EFBFBD><EFBFBD><EFBFBD>
```
---
## <20><><>宏璉<E5AE8F><E79289><EFBFBD><E4BAA4>?
### 餈<><EFBFBD>齿<EFBFBD><E9BDBF>?
- [ ] <20>?<3F>唳旿摨枏歇憭<E6AD87>遢嚗Ê̄ackup_before_schema_migration_*.dump嚗?- [ ] <20>?憭<><EFBFBD><E981A2>辣撌脤<E6928C>霂?- [ ] <20>?Prisma<6D>滨蔭撌脫凒<E884AB><EFBFBD>datasource.schemas嚗?- [ ] <20>?餈<><EFBFBD>𡁏𧋦撌脣<E6928C><EFBFBD><E686AD>001-010.sql嚗?- [ ] <20>?瘚贝<E7989A><E8B49D><EFBFBD>撌脤<E6928C><EFBFBD><E99C82>蝘餅郊撉?
---
### 餈<>宏銝剜<E98A9D><E5899C>?
- [ ] <20>?10銝杵chema<6D>𥕦遣<F0A595A6>𣂼<EFBFBD>
- [ ] <20>?銵刻<E98AB5>蝘餅<E89D98><E9A485>躰秤嚗?銝芣<E98A9D><E88AA3>唳旿<E594B3><E697BF>chema嚗?- [ ] <20>?<3F>唳旿摰峕㟲<E5B395><EFBFBD><EFBFBD><E99C82><EFBFBD>
- [ ] <20>?憭㚚睸蝥行<E89DA5><EFBFBD>
- [ ] <20>?蝝<E89D9D><EFBFBD><EFBFBD>𥕦遣
---
### 餈<><EFBFBD><EFBFBD><E693A7>?
- [ ] <20>?Prisma Client<6E><74><EFBFBD><EFBFBD>𣂼<EFBFBD>
- [ ] <20>?<3F>𡒊垢<F0A1928A>滚𦛚<E6BB9A>臬𢆡甇<F0A286A1>
- [ ] <20>?<3F><EFBFBD><E594B3><EFBFBD>瘚贝<E7989A><E8B49D><EFBFBD>嚗㇁IA<49><41>KB嚗?- [ ] <20>?API靚<49>鍂甇<E98D82>
- [ ] <20>?<3F>滨垢<E6BBA8><EFBFBD><EFBFBD>
---
## <20>圲 撣貉<E692A3><E8B289><EFBFBD>
### <20><EFBFBD>1嚗锭chema<6D>𥕦遣憭梯揖
**<EFBFBD>躰秤嚗?*
```
ERROR: schema "platform_schema" already exists
```
**閫<><E996AB>嚗?*
```sql
-- 璉<><E79289>兄chema<6D>臬炏摮睃銁
SELECT schema_name FROM information_schema.schemata
WHERE schema_name = 'platform_schema';
-- 憒<><E68692>摮睃銁雿<E98A81>蛹蝛綽<E89D9B><E7B6BD><EFBFBD><E887AC><EFBFBD>撱?DROP SCHEMA platform_schema CASCADE;
CREATE SCHEMA platform_schema;
```
---
### <20><EFBFBD>2嚗𡁏㺭<F0A1818F><EFBFBD>蝘餃仃韐?
**<2A>躰秤嚗?*
```
ERROR: duplicate key value violates unique constraint
```
**閫<><E996AB>嚗?*
1.<><E79289>交㺭<E4BAA4>格糓<E6A0BC>血歇<E8A180><EFBFBD><EFBFBD>
2.<><E79A9C><EFBFBD><EFBFBD>Schema
3. <20>齿鰵<E9BDBF><EFBFBD><EFBFBD>
---
### <20><EFBFBD>3嚗𡁜<E59A97><F0A1819C>桃漲<E6A183><EFBFBD>霂?
**<2A>躰秤嚗?*
```
ERROR: foreign key constraint "fk_user_id" cannot be implemented
```
**閫<><E996AB>嚗?*
1. 蝖桐<E89D96>鋡怠<E98BA1><E680A0><EFBFBD>銵典歇<E585B8><E6AD87><EFBFBD>蝘?2. 璉<><E79289><EFBFBD><E4BA99><EFBFBD>畾萇掩<E89087>见龪<E8A781>?3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E585B8><EFBFBD><EFBFBD><EFBFBD>𡡞<EFBFBD>撱?
---
## <20>圲 鈭穃<E988AD><E7A983><EFBFBD><E8A098><EFBFBD><E4BAA4>滨蔭嚗?025-11-16 <20><EFBFBD>嚗?
> **潃?<3F><EFBFBD><E6BBA9>湔鰵**嚗帋蛹<E5B88B><EFBFBD><E88880><EFBFBD>鈭?Serverless <20>函蔡嚗峕鰵憓噼<E68693><E599BC><EFBFBD><E4BAA4>滨蔭
> **霂衣<E99C82><E8A1A3><EFBFBD>﹝**嚗靀撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>](./04-撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>.md)
### <20>峕艶嚗帋蛹隞<E89BB9><EFBFBD><E98A8B><EFBFBD><E996AC><EFBFBD><EFBFBD>嚗?
**<2A><EFBFBD><E6A185>箸艶**嚗?```
<EFBFBD><EFBFBD>鈭?SAE <20>芸𢆡<E88AB8>拙捆嚗?- <20><EFBFBD>嚗?銝芸<E98A9D>靘页<E99D98>10銝芾<E98A9D><E88ABE>?- 擃睃陸嚗?00銝芸<E98A9D>靘页<E99D98>1000銝芾<E98A9D><E88ABE>?- RDS<44><53>憭扯<E686AD><E689AF>交㺭嚗?00 <20>?頞<><E9A09E>嚗?
蝏𤘪<EFBFBD>嚗𡁏㺭<EFBFBD><EFBFBD>餈墧𦻖<EFBFBD>堒偷嚗<EFBFBD><EFBFBD><EFBFBD>典援皞?```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗𡁜𢆡<F0A1819C><F0A286A1>恣蝞埈<E89D9E>摰硺<E691B0>餈墧𦻖<E5A2A7>?
```typescript
瘥誩<EFBFBD>靘贝<EFBFBD><EFBFBD>交㺭 = RDS<44><53>憭扯<E686AD><E689AF>交㺭 / SAE<41><45>憭批<E686AD>靘𧢲㺭
蝷箔<EFBFBD>嚗?00餈墧𦻖 / 20摰硺<E691B0> = 20餈墧𦻖/摰硺<E691B0>
```
---
### Prisma餈墧𦻖瘙𣳇<E79899>蝵?
**<2A><>辣雿滨蔭**嚗䫤backend/src/config/database.ts`
**<EFBFBD>滨蔭隞<EFBFBD><EFBFBD>**嚗?
```typescript
import { PrismaClient } from '@prisma/client'
// <20><EFBFBD><E586BD>恣蝞𡑒<E89D9E><F0A19192>交㺭
const dbMaxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
const maxInstances = Number(process.env.MAX_INSTANCES) || 20
const connectionLimit = Math.floor(dbMaxConnections / maxInstances)
console.log(`<EFBFBD><EFBFBD> <20>唳旿摨栞<E691A8><E6A09E><EFBFBD><E4BAA4>滨蔭嚗𡁏<E59A97>摰硺<E691B0><E7A1BA><EFBFBD>憭?{connectionLimit}銝芾<E98A9D><E88ABE>匝)
// <20>𥕦遣<F0A595A6><EFBFBD>Prisma Client
export const prisma = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
log: process.env.NODE_ENV === 'development'
? ['query', 'error', 'warn']
: ['error'],
errorFormat: 'minimal',
})
// 隡㗛<E99AA1><E3979B>喲𡡒餈墧𦻖
process.on('SIGTERM', async () => {
console.log('<27><><><EFBFBD>喲𡡒<E596B2>唳旿摨栞<E691A8><E6A09E>?..')
await prisma.$disconnect()
console.log('<27>?<3F>唳旿摨栞<E691A8><E6A09E>亙歇<E4BA99>喲𡡒')
process.exit(0)
})
process.on('SIGINT', async () => {
console.log('<27><><><EFBFBD>喲𡡒<E596B2>唳旿摨栞<E691A8><E6A09E>?..')
await prisma.$disconnect()
console.log('<27>?<3F>唳旿摨栞<E691A8><E6A09E>亙歇<E4BA99>喲𡡒')
process.exit(0)
})
// <20>臬𢆡<E887AC><EFBFBD>霂閗<E99C82><E99697>?prisma.$connect()
.then(() => console.log('<27>?<3F>唳旿摨栞<E691A8><E6A09E><EFBFBD><E4BAA4>?))
.catch((err) => {
console.error('<27>?<3F>唳旿摨栞<E691A8><E6A09E>亙仃韐?', err)
process.exit(1)
})
```
---
### <20><EFBFBD><E887AC><EFBFBD><E3979B>滨蔭
**<EFBFBD>砍𧑐撘<EFBFBD><EFBFBD>𤑳㴓憓?*嚗?
```bash
# backend/.env.development
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
# <20>砍𧑐撘<F0A79190><E69298><EFBFBD><E78390><EFBFBD><EFBFBD>滨蔭餈墧𦻖瘙𩤃<E79899><F0A9A483><EFBFBD>靘页<E99D98>
# DB_MAX_CONNECTIONS=N/A
# MAX_INSTANCES=N/A
```
**鈭𤑳垢<F0A491B3>煺漣<E785BA><EFBFBD>**嚗?
```bash
# SAE<41><EFBFBD><E689B9>?-> <20><EFBFBD><E887AC><EFBFBD><E3979B>滨蔭
DATABASE_URL=postgresql://user:password@rm-xxx.aliyuncs.com:5432/prod_db
DB_MAX_CONNECTIONS=400 # <20><EFBFBD>鈭駵DS<44><53>憭扯<E686AD><E689AF>交㺭
MAX_INSTANCES=20 # SAE<41><45>憭批<E686AD>靘𧢲㺭
```
**銝滚<E98A9D>RDS閫<53><EFBFBD><E881A2><EFBFBD><EFBFBD>交㺭**嚗?
| RDS閫<53>聢 | <20><>憭扯<E686AD><E689AF>交㺭 | 撱箄悅SAE摰硺<E691B0><E7A1BA>?| 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭 |
|---------|-----------|--------------|-------------|
| 2<>?GB | 200 | 10 | 20 |
| 4<>?GB | 400 | 20 | 20 |
| 8<>?6GB | 800 | 40 | 20 |
---
### <20>烐綉<E78390>唳旿摨栞<E691A8><E6A09E>交㺭
**摰墧𧒄<E5A2A7>亥砭餈墧𦻖<E5A2A7>?*嚗?
```typescript
// backend/src/common/monitoring/metrics.ts
import { prisma } from '@/config/database'
import { logger } from '@/common/logging'
export class DatabaseMetrics {
// <20>亥砭敶枏<E695B6>餈墧𦻖<E5A2A7>? static async getConnectionCount(): Promise<number> {
const result = await prisma.$queryRaw<Array<{ count: bigint }>>`
SELECT count(*) as count
FROM pg_stat_activity
WHERE datname = current_database()
`
return Number(result[0].count)
}
// <20>烐綉撟嗅<E6929F>霅? static async monitorConnections() {
const currentConnections = await this.getConnectionCount()
const maxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
const usagePercent = (currentConnections / maxConnections) * 100
logger.info('<27>唳旿摨栞<E691A8><E6A09E><EFBFBD><E4BAA6>?, {
current: currentConnections,
max: maxConnections,
usage: `${usagePercent.toFixed(1)}%`
})
// <20>𡃏郎嚗朞<E59A97><E69C9E>交㺭頞<E3BAAD><E9A09E>80%
if (usagePercent > 80) {
logger.warn('<EFBFBD>𩤃<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡃏', {
current: currentConnections,
max: maxConnections,
usage: `${usagePercent.toFixed(1)}%`,
action: '𧼮<EFBFBD>RDS閫<EFBFBD><EFBFBD><EFBFBD>AE摰硺<EFBFBD><EFBFBD>?
})
}
return { currentConnections, maxConnections, usagePercent }
}
}
```
**摰𡁏𧒄<F0A1818F>烐綉**嚗<><EFBFBD><EFBFBD>嚗?
```typescript
// backend/src/index.ts
import { DatabaseMetrics } from '@/common/monitoring/metrics'
// 瘥?<3F><><EFBFBD><EFBFBD>烐綉銝<E7B689>甈?setInterval(async () => {
await DatabaseMetrics.monitorConnections()
}, 5 * 60 * 1000)
```
---
### <20><><EFBFBD><EFBFBD>埝䰻
**<EFBFBD><EFBFBD>1嚗朞<EFBFBD><EFBFBD>交㺭<EFBFBD>堒偷**
**<EFBFBD><EFBFBD>𠶖**嚗?```
Error: P1001: Can't reach database server
Error: remaining connection slots are reserved
```
**<2A><EFBFBD>**嚗?- SAE摰硺<E691B0><E7A1BA><EFBFBD>憭?- 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭<E4BAA4>滨蔭餈<E894AD><E9A488>
- 摮睃銁餈墧𦻖瘜<F0A6BB96><E7989C>
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?```bash
# 1. <20><EFBFBD>敶枏<E695B6>餈墧𦻖<E5A2A7>?SELECT count(*) FROM pg_stat_activity
WHERE datname = 'ai_clinical_research';
# 2. <20><EFBFBD>餈墧𦻖<E5A2A7><EFBFBD>
SELECT client_addr, count(*)
FROM pg_stat_activity
WHERE datname = 'ai_clinical_research'
GROUP BY client_addr;
# 3. 靚<><EFBFBD>滨蔭
# <20><EFBFBD>A嚗𡁜<E59A97>撠騌AE<41><45>憭批<E686AD>靘𧢲㺭
MAX_INSTANCES=10 # 隞?0<>嫣蛹10
# <20><EFBFBD>B嚗𡁜<E59A97>蝥刪DS閫<53>
# 隞?<3F>?GB嚗?00餈墧𦻖嚗匧<E59A97>蝥批<E89DA5>4<EFBFBD>?GB嚗?00餈墧𦻖嚗?```
---
**<2A><EFBFBD>2嚗朞<E59A97><E69C9E><EFBFBD>瞍?*
**<2A><>𠶖**嚗?- 餈墧𦻖<E5A2A7><EFBFBD>蝏剖<E89D8F><E58996>?- <20>喃蝙瘚<E89D99><E7989A><EFBFBD><EFBFBD>嚗諹<E59A97><E8ABB9>交㺭銝滢<E98A9D><E6BBA2>?
**<2A>埝䰻**嚗?```typescript
// <20>?<3F>躰秤嚗𡁏<E59A97><E79488>撱箸鰵摰硺<E691B0>
function getUser() {
const prisma = new PrismaClient() // 餈墧𦻖瘜<F0A6BB96><E7989C>
return prisma.user.findMany()
}
// <20>?甇<>嚗帋蝙<E5B88B><EFBFBD><EFBFBD>摰硺<E691B0>
import { prisma } from '@/config/database'
function getUser() {
return prisma.user.findMany()
}
```
---
### <20><>雿喳<E99BBF>頝?
**DO <20>?*嚗?1. <20>?雿輻鍂<E8BCBB><EFBFBD> `prisma` 摰硺<E691B0>
2. <20>?<3F>滨蔭 `SIGTERM` 隡㗛<E99AA1><E3979B>喲𡡒
3. <20>?摰𡁏<E691B0><F0A1818F>烐綉餈墧𦻖<E5A2A7>?4. <20>?霈曄蔭餈墧𦻖<E5A2A7><EFBFBD>霅佗<E99C85>80%<25><><EFBFBD><EFBFBD>
5. <20>?雿輻鍂餈墧𦻖瘙𩤃<E79899>Prisma暺䁅恕<E48185>舐鍂嚗?
**DON'T <20>?*嚗?1. <20>?瘥𤩺活霂瑟<E99C82><E7919F>啣遣 `PrismaClient`
2. <20>?銝滚<E98A9D><E6BB9A><EFBFBD><E5899B>亙停<E4BA99><E5819C><EFBFBD><EFBFBD>蝔?3. <20>?敹賜裦餈墧𦻖<E5A2A7><EFBFBD><E59581>?4. <20>?霈曄蔭餈<E894AD><EFBFBD>?`MAX_INSTANCES`
5. <20>?<3F><EFBFBD><E585B6>∩誨<E288A9><E8AAA8><EFBFBD>湔𦻖<E6B994><EFBFBD> `$disconnect()`
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
- [撟喳蝱<EFBFBD><EFBFBD>霈暹鴌閫<EFBFBD><EFBFBD>](./04-撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>.md) - 摰峕㟲<E5B395><E39FB2><EFBFBD><EFBFBD><EFBFBD>霈曇恣
- [鈭穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD><EFBFBD>(../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983><EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md) - <20>唳旿摨㮖蝙<E3AE96><EFBFBD><E588BB>?- [<5B><EFBFBD><E887AC>滨蔭<E6BBA8><E894AD><EFBFBD>](../07-餈鞟輕<E99E9F><E8BC95>﹝/01-<2D><EFBFBD><E887AC>滨蔭<E6BBA8><E894AD><EFBFBD>.md) - <20><EFBFBD><E887AC><EFBFBD><E3979B>滨蔭
- [Schema<EFBFBD>𠉛氖<EFBFBD><EFBFBD>霈曇恣](../00-蝟餌<E89D9F><E9A48C><EFBFBD>霈曇恣/03-<2D>唳旿摨𤘪沲<F0A498AA><E6B2B2><EFBFBD>?md)
---
## <20><> <20>湔鰵霈啣<E99C88>
| <20><EFBFBD> | <20>湔鰵<E6B994><E9B0B5>捆 | <20>湔鰵鈭?|
|------|---------|--------|
| 2025-11-09 | <20><EFBFBD><E598A5><EFBFBD><EFBFBD>𥕦遣 | <20><EFBFBD><E59786><EFBFBD> |
| 2025-11-16 | <20><EFBFBD>鈭穃<E988AD><E7A983><EFBFBD><E8A098><EFBFBD><E4BAA4>滨蔭蝡㰘<E89DA1> | <20><EFBFBD><E59786><EFBFBD> |
---
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗?* v1.0
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025-11-09
**蝏湔擪<E6B994><E693AA><EFBFBD>** <20><EFBFBD><E59786><EFBFBD>