# Schema隔离方案与成本分析 > **文档版本:** v1.0 > **创建日期:** 2025-11-06 > **最后更新:** 2025-11-06 > **文档状态:** 架构分析 > **作者:** 技术架构师 --- ## 📋 核心问题 1. 什么是真正的Schema隔离? 2. 从逻辑隔离到物理隔离的改造成本有多高? 3. 现在做Schema隔离的成本高吗? 4. 当前业务体量下,需要现在做吗? 5. 最佳实施时机是什么时候? --- ## 🎯 两种隔离方式对比 ### 逻辑隔离(当前方案) **定义:** - 所有表都在同一个Schema(`public`)中 - 通过**表名前缀**来区分不同模块 - 代码层面按模块组织 **示例:** ```sql -- 所有表都在public schema public.users -- 用户表 public.aia_projects -- AI问答模块的项目表 public.aia_conversations -- AI问答模块的对话表 public.asl_projects -- AI文献模块的项目表 public.asl_literature_items -- AI文献模块的文献表 public.pkb_knowledge_bases -- 知识库模块的知识库表 public.dc_projects -- 数据清洗模块的项目表 public.review_tasks -- 稿件审查模块的任务表 ``` **Prisma Schema示例:** ```prisma // 逻辑隔离:使用@@map指定表名 model AiaProject { id String @id @default(uuid()) userId String @map("user_id") name String // ... @@map("aia_projects") // 表名前缀标识模块 } model AslProject { id String @id @default(uuid()) userId String @map("user_id") name String // ... @@map("asl_projects") // 表名前缀标识模块 } ``` **查询方式:** ```typescript // 业务代码无感知 const project = await prisma.aiaProject.findUnique({ where: { id: projectId } }); ``` --- ### 物理隔离(真正的Schema隔离) **定义:** - 为每个模块创建**独立的PostgreSQL Schema** - 表分散在不同的Schema中 - 数据库层面真正隔离 **示例:** ```sql -- 创建独立Schema CREATE SCHEMA platform_schema; -- 平台层 CREATE SCHEMA aia_schema; -- AI问答模块 CREATE SCHEMA asl_schema; -- AI文献模块 CREATE SCHEMA pkb_schema; -- 知识库模块 CREATE SCHEMA dc_schema; -- 数据清洗模块 CREATE SCHEMA review_schema; -- 稿件审查模块 CREATE SCHEMA admin_schema; -- 运营管理端 -- 表分布在不同Schema platform_schema.users -- 用户表 aia_schema.projects -- AI问答的项目表 aia_schema.conversations -- AI问答的对话表 asl_schema.projects -- AI文献的项目表 asl_schema.literature_items -- AI文献的文献表 pkb_schema.knowledge_bases -- 知识库表 dc_schema.projects -- 数据清洗的项目表 review_schema.tasks -- 稿件审查的任务表 ``` **Prisma Schema示例:** ```prisma // 物理隔离:指定schema model AiaProject { id String @id @default(uuid()) userId String @map("user_id") name String // ... @@map("projects") // 表名不需要前缀 @@schema("aia_schema") // 指定Schema ⭐ } model AslProject { id String @id @default(uuid()) userId String @map("user_id") name String // ... @@map("projects") // 表名不需要前缀 @@schema("asl_schema") // 指定Schema ⭐ } ``` **查询方式:** ```typescript // 业务代码无感知(Prisma会自动处理) const project = await prisma.aiaProject.findUnique({ where: { id: projectId } }); // 实际执行的SQL: // SELECT * FROM aia_schema.projects WHERE id = $1 ``` --- ## 📊 两种方案对比 | 维度 | 逻辑隔离(当前) | 物理隔离(目标) | |------|----------------|----------------| | **复杂度** | ⭐ 简单 | ⭐⭐⭐ 中等 | | **实施难度** | ⭐ 低 | ⭐⭐⭐ 中等 | | **维护成本** | ⭐⭐ 低 | ⭐⭐⭐ 中等 | | **隔离性** | ⭐⭐ 中等(代码层面) | ⭐⭐⭐⭐⭐ 高(数据库层面) | | **权限控制** | ⭐⭐ 中等 | ⭐⭐⭐⭐⭐ 高(数据库级别) | | **微服务拆分** | ⭐⭐⭐ 需要改造 | ⭐⭐⭐⭐⭐ 易于拆分 | | **模块独立部署** | ⭐⭐ 困难 | ⭐⭐⭐⭐⭐ 容易 | | **跨模块查询** | ⭐⭐⭐⭐⭐ 容易(同一Schema) | ⭐⭐⭐ 需要跨Schema查询 | | **备份恢复** | ⭐⭐⭐ 整体备份 | ⭐⭐⭐⭐⭐ 可按Schema备份 | | **当前适用性** | ✅ 适合当前阶段 | ⚠️ 未来阶段 | --- ## 💰 改造成本分析 ### 从逻辑隔离到物理隔离需要改什么? #### 1. 数据库层面改造 **步骤1:创建Schema** ```sql -- 创建新Schema(非常简单) CREATE SCHEMA platform_schema; CREATE SCHEMA aia_schema; CREATE SCHEMA asl_schema; CREATE SCHEMA pkb_schema; CREATE SCHEMA dc_schema; CREATE SCHEMA review_schema; CREATE SCHEMA admin_schema; ``` **工作量:** 10分钟 --- **步骤2:创建新表结构** ```sql -- 在新Schema中创建表 CREATE TABLE aia_schema.projects ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL, name VARCHAR(255) NOT NULL, -- ... 其他字段 -- 外键可能需要跨Schema CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ); -- 类似的,为所有表创建新的表结构 ``` **工作量:** - 自动生成(Prisma Migrate):1-2小时 - 手动创建:1天 --- **步骤3:数据迁移** ```sql -- 迁移数据(从public到新Schema) INSERT INTO aia_schema.projects SELECT * FROM public.aia_projects; INSERT INTO aia_schema.conversations SELECT * FROM public.aia_conversations; -- ... 为所有表迁移数据 ``` **工作量:** - 数据量小(<100万行):1-2小时 - 数据量大(>100万行):半天到1天 **风险:** - ⚠️ 需要停机(或做在线迁移) - ⚠️ 需要验证数据完整性 - ⚠️ 外键约束可能有问题 --- **步骤4:清理旧表** ```sql -- 删除旧表(确认无误后) DROP TABLE public.aia_projects; DROP TABLE public.aia_conversations; -- ... ``` **工作量:** 1小时 **总计数据库改造工作量:** - 自动化:半天到1天 - 手动:2-3天 --- #### 2. 代码层面改造 **步骤1:修改Prisma Schema** **逻辑隔离(当前):** ```prisma model AiaProject { id String @id @default(uuid()) userId String @map("user_id") name String @@map("aia_projects") // 需要前缀 } ``` **物理隔离(修改后):** ```prisma model AiaProject { id String @id @default(uuid()) userId String @map("user_id") name String @@map("projects") // 不需要前缀 @@schema("aia_schema") // 新增:指定Schema ⭐ } ``` **工作量:** - 修改所有Model(约50-100个Model) - 时间:2-4小时 --- **步骤2:处理外键和关联** **问题:跨Schema的外键** ```prisma // User在platform_schema model User { id String @id @default(uuid()) email String @@map("users") @@schema("platform_schema") } // Project在aia_schema model AiaProject { id String @id @default(uuid()) userId String @map("user_id") // 跨Schema关联 ⚠️ user User @relation(fields: [userId], references: [id]) @@map("projects") @@schema("aia_schema") } ``` **Prisma处理:** - ✅ Prisma会自动处理跨Schema的关联 - ✅ 生成的SQL会包含正确的Schema前缀 - ⚠️ 但需要测试验证 **工作量:** - 测试所有跨Schema关联:半天到1天 --- **步骤3:业务代码改造** **好消息:业务代码几乎不需要改!** ✅ ```typescript // 业务代码完全不变 const project = await prisma.aiaProject.findUnique({ where: { id: projectId }, include: { user: true // 跨Schema关联,Prisma自动处理 } }); ``` **原因:** - ✅ Prisma ORM抽象了底层Schema - ✅ 业务代码只依赖Prisma Model,不直接写SQL **例外情况:** - ⚠️ 如果有原始SQL查询(`prisma.$queryRaw`),需要修改 - ⚠️ 如果有数据库视图(View),需要修改 - ⚠️ 如果有数据库函数(Function),需要修改 **工作量:** - 业务代码:0改造(如果没有原始SQL) - 原始SQL:需要逐个修改(估计10-20处) - 时间:半天到1天 --- **步骤4:运行Prisma Migrate** ```bash # 生成新的迁移文件 npx prisma migrate dev --name schema-isolation # 或手动迁移(生产环境) npx prisma migrate deploy ``` **工作量:** - 开发环境:10分钟 - 生产环境:需要详细计划(半天准备) --- #### 3. 测试验证 **需要测试的内容:** 1. ✅ 所有API接口是否正常 2. ✅ 跨Schema关联是否正常(用户-项目、项目-对话等) 3. ✅ 外键约束是否正常 4. ✅ 数据完整性检查 5. ✅ 性能测试(跨Schema查询性能) 6. ✅ 备份恢复测试 **工作量:** - 单元测试:自动化,1-2小时 - 集成测试:半天 - 端到端测试:1天 - 总计:1-2天 --- ### 总改造成本 **开发环境:** | 任务 | 工作量 | |------|-------| | 数据库Schema创建 | 10分钟 | | Prisma Schema修改 | 2-4小时 | | 数据迁移脚本 | 1-2小时 | | 原始SQL修改 | 半天 | | 测试验证 | 1-2天 | | **总计** | **2-3天** | **生产环境:** | 任务 | 工作量 | |------|-------| | 迁移方案设计 | 半天 | | 数据备份 | 1小时 | | 数据迁移 | 半天到1天 | | 验证测试 | 1天 | | 应急回滚方案 | 半天 | | **总计** | **3-4天** | **风险评估:** - ⚠️ **风险等级:中等** - ⚠️ **主要风险:数据迁移失败、外键约束问题、停机时间** - ✅ **缓解措施:详细测试、回滚方案、灰度发布** --- ## 🤔 现在做 vs 以后做 ### 现在做的优势 ✅ 1. **数据量小,迁移快** ``` 当前数据量(估算): - 用户:< 100 - 项目:< 500 - 对话:< 5,000 - 文档:< 1,000 迁移时间:< 1小时 风险:低 ``` 2. **业务复杂度低,测试简单** ``` 当前模块: - ✅ AIA(AI问答)- 已完成 - ✅ PKB(知识库)- 已完成 - ⏳ ASL(AI文献)- 未开发 - ⏳ DC、SSA、ST、RVW - 未开发 需要测试的模块少 ``` 3. **为未来打下坚实基础** ``` 优势: - ✅ 新模块(ASL、DC等)直接用物理隔离 - ✅ 避免未来大规模改造 - ✅ 支持模块独立部署 - ✅ 支持微服务拆分 ``` 4. **团队学习成本低** ``` 当前团队小: - 开发人员少,沟通成本低 - 代码改动影响范围小 - 易于推广新规范 ``` --- ### 现在做的劣势 ❌ 1. **需要投入时间** ``` 开发时间:2-3天(开发环境) 生产时间:3-4天(生产环境) 总计:1周 延迟:ASL模块开发延迟1周 ``` 2. **有一定风险** ``` 风险: - 数据迁移失败 - 外键约束问题 - 需要停机 缓解:详细测试、回滚方案 ``` 3. **当前没有紧迫需求** ``` 事实: - 没有微服务拆分需求 - 没有模块独立部署需求 - 没有私有化部署需求 结论:暂时不需要物理隔离 ``` --- ### 以后做的优势 ✅ 1. **延迟投入** ``` 当前:专注业务开发(ASL、DC等) 未来:有需求时再改造 优势:快速推进业务 ``` 2. **需求明确时再做** ``` 触发条件: - 需要微服务拆分 - 需要模块独立部署 - 需要私有化部署 - 数据量大,需要性能优化 此时改造目标明确 ``` --- ### 以后做的劣势 ❌ 1. **数据量大,迁移慢** ``` 未来数据量(估算): - 用户:10,000+ - 项目:100,000+ - 对话:1,000,000+ - 文档:500,000+ 迁移时间:数小时到数天 风险:高 ``` 2. **业务复杂,测试困难** ``` 未来模块: - ✅ 7个模块全部上线 - ✅ 复杂的跨模块关联 - ✅ 大量用户在使用 测试难度:高 回滚成本:高 ``` 3. **需要停机或在线迁移** ``` 停机迁移: - 影响用户体验 - 可能丢失订单 在线迁移: - 技术复杂度高 - 需要双写、数据同步 ``` 4. **改造成本成倍增长** ``` 未来改造成本(估算): - 开发时间:1-2周 - 测试时间:1-2周 - 生产迁移:1周 - 总计:3-5周 现在的3-5倍! ``` --- ## 🎯 建议与决策 ### 方案A:现在做物理隔离 ⭐⭐⭐⭐⭐ **强烈推荐** **适用场景:** - ✅ 有1周时间投入 - ✅ 重视长期架构健康 - ✅ 未来有模块独立部署需求 - ✅ 未来有私有化部署需求 **理由:** 1. **成本最低**:数据量小,迁移快(< 1小时) 2. **风险最低**:业务简单,测试容易 3. **收益最大**:为未来7个模块打下坚实基础 4. **避免技术债**:避免未来大规模改造 **实施计划:** ``` Week 1:Schema隔离改造(2-3天) Day 1-2:开发环境改造 - 创建Schema - 修改Prisma Schema - 数据迁移脚本 - 测试验证 Day 3:生产环境迁移 - 备份数据 - 执行迁移 - 验证测试 - 监控 Week 2:继续ASL模块开发 ``` **投入产出比:** ⭐⭐⭐⭐⭐ 极高 --- ### 方案B:暂不做物理隔离,继续逻辑隔离 ⭐⭐⭐ **可接受** **适用场景:** - ✅ 时间紧迫,必须尽快上线ASL模块 - ✅ 近期(6个月内)没有微服务拆分需求 - ✅ 近期没有私有化部署需求 **理由:** 1. **快速推进业务**:专注ASL模块开发 2. **逻辑隔离足够用**:当前阶段可以满足需求 3. **延迟改造**:未来有需求时再做 **但需要遵守纪律:** ⚠️ 非常重要 ``` 严格使用表名前缀: - aia_* - asl_* - pkb_* - dc_* - review_* - admin_* 为未来改造打基础 ``` **触发改造的条件:** 1. 需要微服务拆分 2. 需要模块独立部署 3. 需要私有化部署 4. 数据量超过100万行 **投入产出比:** ⭐⭐⭐ 中等 --- ### 方案C:混合方案(折中) ⭐⭐⭐⭐ **推荐** **方案描述:** 1. **新模块使用物理隔离** - ASL、DC、SSA、ST、RVW等新模块直接用物理隔离 - 从一开始就创建独立Schema 2. **老模块暂时保持逻辑隔离** - AIA、PKB等已完成模块暂时不动 - 等未来有需求时再迁移 **实施计划:** ``` 立即: 1. 创建新Schema CREATE SCHEMA asl_schema; CREATE SCHEMA dc_schema; CREATE SCHEMA admin_schema; ... 2. ASL模块使用物理隔离 model AslProject { @@schema("asl_schema") } 未来(6-12个月后): 3. 迁移老模块 - 迁移AIA到aia_schema - 迁移PKB到pkb_schema ``` **优势:** - ✅ 立即投入小(只需创建Schema,10分钟) - ✅ 新模块享受物理隔离的好处 - ✅ 老模块延迟改造,风险低 **投入产出比:** ⭐⭐⭐⭐ 高 --- ## 📊 决策矩阵 | 方案 | 立即投入 | 未来成本 | 风险 | 灵活性 | 推荐度 | |------|---------|---------|------|-------|-------| | **方案A:现在做物理隔离** | ⭐⭐⭐ 中(1周) | ⭐⭐⭐⭐⭐ 低 | ⭐⭐⭐⭐ 低 | ⭐⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ | | **方案B:继续逻辑隔离** | ⭐⭐⭐⭐⭐ 零 | ⭐⭐ 高 | ⭐⭐⭐ 中 | ⭐⭐ 低 | ⭐⭐⭐ | | **方案C:混合方案** | ⭐⭐⭐⭐⭐ 低(10分钟) | ⭐⭐⭐⭐ 中 | ⭐⭐⭐⭐ 低 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐ | --- ## 🎯 最终建议 ### 我的推荐:方案A(现在做物理隔离)⭐⭐⭐⭐⭐ **理由:** **1. 成本最低的时间窗口** ``` 当前: - 数据量小(< 1万行) - 迁移时间:< 1小时 - 测试时间:1-2天 - 总成本:1周 6个月后: - 数据量大(100万行+) - 迁移时间:数小时到数天 - 测试时间:1-2周 - 总成本:3-5周 成本差异:3-5倍! ``` **2. 最佳学习机会** ``` 当前: - 团队小,沟通成本低 - 模块少,改造范围小 - 易于建立规范 未来: - 团队大,沟通成本高 - 模块多,改造范围大 - 难以统一规范 ``` **3. 避免技术债累积** ``` 技术债的特点: - 时间越久,利息越高 - 改造成本成倍增长 - 影响业务创新 现在改造: - 一次性还清 - 轻装上阵 ``` **4. 为未来打下坚实基础** ``` 未来需求(6-12个月): - 审稿系统独立部署 - AI文献模块独立销售 - 私有化部署 - 微服务拆分 物理隔离是基础设施 ``` --- ### 如果必须选择方案B或C **推荐:方案C(混合方案)** **最低要求:** 1. ✅ 立即创建所有Schema(10分钟) 2. ✅ 新模块(ASL、DC等)使用物理隔离 3. ✅ 老模块(AIA、PKB)延迟迁移 **触发老模块迁移的条件:** - 数据量超过50万行 - 需要模块独立部署 - 需要私有化部署 --- ## 📋 实施清单(方案A) ### 准备阶段(1天) - [ ] 详细阅读Prisma Schema文档 - [ ] 设计Schema结构(platform_schema, aia_schema, asl_schema等) - [ ] 编写数据迁移脚本 - [ ] 准备测试用例 - [ ] 准备回滚方案 ### 开发环境改造(1-2天) - [ ] 创建所有Schema - [ ] 修改Prisma Schema(所有Model) - [ ] 运行Prisma Migrate - [ ] 迁移开发环境数据 - [ ] 运行单元测试 - [ ] 运行集成测试 - [ ] 手动测试所有功能 ### 生产环境迁移(1天) - [ ] 备份数据库 - [ ] 创建Schema - [ ] 执行数据迁移 - [ ] 验证数据完整性 - [ ] 启动应用 - [ ] 监控错误日志 - [ ] 性能测试 ### 验收标准 - [ ] 所有API接口正常 - [ ] 跨Schema关联正常 - [ ] 外键约束正常 - [ ] 数据完整性正常 - [ ] 性能无明显下降 - [ ] 无错误日志 --- ## 💡 技术细节:如何实现物理隔离 ### Step 1: 创建Schema ```sql -- 创建所有Schema CREATE SCHEMA platform_schema; CREATE SCHEMA aia_schema; CREATE SCHEMA asl_schema; CREATE SCHEMA pkb_schema; CREATE SCHEMA dc_schema; CREATE SCHEMA ssa_schema; CREATE SCHEMA st_schema; CREATE SCHEMA review_schema; CREATE SCHEMA admin_schema; ``` --- ### Step 2: 修改Prisma Schema **修改database配置:** ```prisma generator client { provider = "prisma-client-js" previewFeatures = ["multiSchema"] // 启用多Schema支持 ⭐ } datasource db { provider = "postgresql" url = env("DATABASE_URL") schemas = [ "platform_schema", "aia_schema", "asl_schema", "pkb_schema", "dc_schema", "ssa_schema", "st_schema", "review_schema", "admin_schema" ] // 声明所有Schema ⭐ } ``` **修改Model:** ```prisma // 平台层 model User { id String @id @default(uuid()) email String @unique password String // ... @@map("users") @@schema("platform_schema") // 指定Schema ⭐ } // AI问答模块 model AiaProject { id String @id @default(uuid()) userId String @map("user_id") name String user User @relation(fields: [userId], references: [id]) @@map("projects") // 不需要前缀 @@schema("aia_schema") // 指定Schema ⭐ } // AI文献模块 model AslProject { id String @id @default(uuid()) userId String @map("user_id") name String user User @relation(fields: [userId], references: [id]) @@map("projects") @@schema("asl_schema") // 指定Schema ⭐ } ``` --- ### Step 3: 生成迁移 ```bash # 生成迁移文件 npx prisma migrate dev --name schema-isolation --create-only # 查看生成的SQL # migrations/20251106_schema-isolation/migration.sql ``` **生成的SQL示例:** ```sql -- CreateSchema CREATE SCHEMA IF NOT EXISTS "platform_schema"; CREATE SCHEMA IF NOT EXISTS "aia_schema"; -- ... -- CreateTable CREATE TABLE "platform_schema"."users" ( "id" UUID NOT NULL DEFAULT gen_random_uuid(), "email" VARCHAR(255) NOT NULL, -- ... PRIMARY KEY ("id") ); CREATE TABLE "aia_schema"."projects" ( "id" UUID NOT NULL DEFAULT gen_random_uuid(), "user_id" UUID NOT NULL, "name" VARCHAR(255) NOT NULL, -- ... CONSTRAINT "fk_user" FOREIGN KEY ("user_id") REFERENCES "platform_schema"."users"("id") ON DELETE CASCADE, PRIMARY KEY ("id") ); ``` --- ### Step 4: 数据迁移 **编写迁移脚本:** ```sql -- migrate-data.sql -- 迁移用户表 INSERT INTO platform_schema.users SELECT * FROM public.users; -- 迁移AIA模块 INSERT INTO aia_schema.projects SELECT * FROM public.aia_projects; INSERT INTO aia_schema.conversations SELECT * FROM public.aia_conversations; INSERT INTO aia_schema.messages SELECT * FROM public.aia_messages; -- 迁移PKB模块 INSERT INTO pkb_schema.knowledge_bases SELECT * FROM public.knowledge_bases; INSERT INTO pkb_schema.documents SELECT * FROM public.documents; -- ... 其他表 ``` **执行迁移:** ```bash # 方式1:使用psql psql -U postgres -d ai_clinical_research -f migrate-data.sql # 方式2:使用Prisma npx prisma db execute --file migrate-data.sql ``` --- ### Step 5: 验证 ```typescript // test-schema-isolation.ts async function testSchemaIsolation() { // 测试跨Schema关联 const project = await prisma.aiaProject.findUnique({ where: { id: 'test-id' }, include: { user: true // 跨Schema关联(platform_schema.users) } }); console.log('跨Schema关联正常:', project); // 测试所有模块 const stats = { users: await prisma.user.count(), aiaProjects: await prisma.aiaProject.count(), aslProjects: await prisma.aslProject.count(), knowledgeBases: await prisma.knowledgeBase.count(), }; console.log('数据统计:', stats); } ``` --- ## 📊 成本收益总结 ### 投入成本 | 项目 | 时间 | 风险 | |------|------|------| | 学习和准备 | 1天 | 低 | | 开发环境改造 | 1-2天 | 低 | | 测试验证 | 1-2天 | 中 | | 生产环境迁移 | 1天 | 中 | | **总计** | **5-6天** | **中等** | ### 预期收益 | 收益 | 价值 | |------|------| | 模块独立部署 | ⭐⭐⭐⭐⭐ | | 微服务拆分 | ⭐⭐⭐⭐⭐ | | 数据库级别权限控制 | ⭐⭐⭐⭐ | | 按Schema备份恢复 | ⭐⭐⭐⭐ | | 避免未来大规模改造 | ⭐⭐⭐⭐⭐ | | **总价值** | **极高** | --- ## 🎯 最终建议总结 ### 我的建议:立即做物理隔离(方案A) **核心理由:** 1. ✅ **现在是成本最低的时间窗口**(数据量小,改造快) 2. ✅ **避免技术债累积**(未来改造成本成倍增长) 3. ✅ **为7个模块打下坚实基础**(模块独立部署、微服务拆分) 4. ✅ **支持未来商业模式**(模块化销售、私有化部署) **投入:** 1周 **收益:** 避免未来3-5倍的改造成本 **投入产出比:** 极高 --- **如果您决定采纳方案A,我可以立即帮您:** 1. 设计详细的Schema结构 2. 编写Prisma Schema修改方案 3. 编写数据迁移脚本 4. 制定详细的实施计划 5. 准备测试用例和验收标准 **您觉得呢?** 😊