第02章:架构设计与数据建模——用一张图说清楚你要建什么
第02章:架构设计与数据建模——用一张图说清楚你要建什么
2.1 先画架构,再写代码
多数餐饮连锁的数字化失败,不是因为技术不行,而是因为一开始就没想清楚要建什么。
“我们需要一个智能客服”——这句话听起来清晰,实际上模糊到无法执行。什么叫智能?覆盖哪些场景?数据从哪来?谁来维护?
这一章解决的是落地前的最后一公里:用需求表驱动架构,用架构指导数据建模。读完这一章,你应该能拿出一张清晰的系统架构图,以及一套可以直接落地的数据表结构。
2.2 需求采集:从老板的一句话到可执行的需求表
2.2.1 需求访谈三问法
问任何一个餐饮老板"你想要什么样的智能化",回答往往是模糊的。
真正有效的方式是从具体场景出发,用三问法挖掘:
第一问:这件事现在谁在做?怎么做?花多少时间?
→ 找出最大的效率损失点
第二问:这件事做不好的时候,会出什么乱子?
→ 找出最高优先级的场景
第三问:这件事做好了,最明显的标志是什么?
→ 找出可量化的成功指标
2.2.2 需求表模板
| 编号 | 功能名称 | 需求描述 | 当前痛点 | 优先级 | 成功指标 | 涉及数据 |
|---|---|---|---|---|---|---|
| F01 | 客户记忆 | 记住常客的口味偏好和上次点单 | 员工记不住,老顾客感觉被当新人 | P0 | 复购率提升10% | 客户档案、消费记录 |
| F02 | 智能订货 | 系统自动生成订货建议 | 订货靠经验,损耗高 | P0 | 食材损耗率降5% | 销售数据、库存、天气 |
| F03 | 飞书机器人 | 店长群自动汇报经营数据 | 每天手动统计数据 | P1 | 数据汇报时间减少80% | 订单、库存、人员 |
| F04 | 内容生成 | 自动生成朋友圈/点评文案 | 文案靠人工写,效率低 | P1 | 内容产出量提升3倍 | 菜品数据、节日日历 |
| F05 | 复购触达 | 沉睡客户自动激活 | 沉睡客户没有系统化管理 | P2 | 沉睡客户激活率15% | 客户生命周期数据 |
2.3 系统架构设计
2.3.1 整体架构图
┌─────────────────────────────┐
│ 飞书客户端 │
│ (总部群/店长群/门店群) │
└──────────────┬──────────────┘
│ 机器人 WebHook
┌──────────────▼──────────────┐
│ OpenClaw Agent │
│ (Skill 调度 + 对话管理) │
└───────┬──────────────┬───────┘
│ │
┌─────────────▼──┐ ┌─────▼──────────────┐
│ PostgreSQL │ │ ChromaDB │
│ (结构化数据) │ │ (向量知识库) │
│ 客户/订单/库存 │ │ 菜品知识/SOP/话术 │
└────────────────┘ └────────────────────┘
│ │
┌─────────────▼──────────────▼─────┐
│ FastAPI 后台服务 │
│ /orders /customers /dishes │
│ /inventory /reports /feishu │
└───────────────────────────────┘
│
┌─────────────▼──────────────┐
│ Streamlit 前台 │
│ 经营看板 / 知识库管理 │
│ 订货建议 / 客户查询 │
└─────────────────────────────┘
2.3.2 数据流分层
用户请求(飞书/企微/前台)
│
▼
OpenClaw Skill 调度
│
├── 意图识别
│ ├── 查询类 → Text-to-SQL → PG
│ ├── 推荐类 → RAG检索 → ChromaDB
│ ├── 操作类 → API调用 → FastAPI → PG
│ └── 生成类 → LLM + 知识库 → 生成内容
│
▼
结果组装 + 合规校验 + 记忆更新
│
▼
返回用户(文字/卡片/数据报表)
2.4 多门店数据模型设计
2.4.1 核心实体关系
store(门店)
├── customer(客户) 1:N(一家门店多个客户)
├── orders(订单) 1:N
├── inventory(库存) N:1
└── staff(员工) 1:N
customer
├── customer_memories(客户记忆向量) 1:1
├── orders(订单) 1:N
├── member_cards(会员卡) 1:N
└── lifecycle(生命周期状态) 1:1
dish(菜品)
├── dish_tags(菜品标签) N:N
├── recipe(配方) 1:1
└── dish_allergies(禁忌关联) N:N
2.4.2 多门店数据隔离策略
每家门店只能访问自己的数据,通过 store_id 字段强制隔离:
-- 所有涉及门店数据的查询,必须带 store_id 条件
-- 应用层强制注入:
WHERE store_id = :current_store_id
-- 店长角色:只看自己门店
-- 总部角色:可以看所有门店(特殊权限)
-- 员工角色:只看自己负责的客户(通过 create_user 关联)
2.5 数据库选型决策
2.5.1 什么时候用 PostgreSQL,什么时候用 ChromaDB
PostgreSQL(pgvector)擅长:
- 结构化查询:客户档案、订单数据、库存台账
- 事务处理:订单下单、库存扣减(原子性保证)
- 精准条件过滤:门店=北京、客单价>100、订单日期=今天
- SQL 聚合统计:GROUP BY、HAVING、子查询
ChromaDB(向量库)擅长:
- 语义相似度搜索:“我想吃点不辣的” → 找到所有清淡菜品
- 知识库检索:查询菜品卖点话术、服务SOP
- 客户记忆语义搜索:搜索"上次带小孩来"相关的客户记忆
- 非结构化内容匹配:模糊描述 → 精准结果
两者组合使用:
ChromaDB:存知识(菜品卖点、SOP、话术)
存客户记忆向量(口味偏好、消费习惯的语义表示)
PostgreSQL:存业务主数据(客户、订单、库存)
存向量索引锚点(对应 ChromaDB 的 ID)
2.6 建表SQL规划
2.6.1 建表顺序(依赖关系)
第一波(基础数据)
→ stores(门店)
→ dishes(菜品)
→ suppliers(供应商)
第二波(客户与交易)
→ customers(客户档案)
→ orders(订单主表)
→ order_details(订单明细)
→ customer_lifecycle(生命周期)
第三波(运营支撑)
→ inventory(日库存)
→ purchase_orders(采购单)
→ remind_tasks(待办任务)
→ feishu_channels(飞书频道配置)
第四波(知识库)
→ service_sop(服务SOP)
→ service_scripts(话术库)
→ dish_embeddings(菜品向量 — ChromaDB)
→ customer_memories(客户记忆向量 — ChromaDB)
2.6.2 最简可运行表结构(10张核心表)
-- 完整建表语句见附录B,以下为核心10张:
CREATE TABLE stores (
id SERIAL PRIMARY KEY,
name VARCHAR(100), region VARCHAR(50),
manager_name VARCHAR(50), feishu_group_id VARCHAR(100),
is_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE customers (
id SERIAL PRIMARY KEY, store_id INTEGER REFERENCES stores(id),
name VARCHAR(100), phone VARCHAR(30),
preference_tags TEXT[], -- 口味偏好标签:微辣/不要香菜/小孩份
last_order_id INTEGER,
member_level VARCHAR(20) DEFAULT '普通', -- 普通/银卡/金卡/钻石
lifetime_value DECIMAL(12,2) DEFAULT 0,
lifecycle_stage VARCHAR(20) DEFAULT '新客', -- 新客/活跃/沉睡/流失
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY, store_id INTEGER REFERENCES stores(id),
customer_id INTEGER REFERENCES customers(id),
order_time TIMESTAMP DEFAULT NOW(),
total_amount DECIMAL(10,2),
is_set_meal BOOLEAN DEFAULT FALSE,
source VARCHAR(20) -- 堂食/外卖/团购
);
CREATE TABLE order_details (
id SERIAL PRIMARY KEY, order_id INTEGER REFERENCES orders(id),
dish_id INTEGER, quantity INTEGER, unit_price DECIMAL(10,2)
);
CREATE TABLE dishes (
id SERIAL PRIMARY KEY, store_id INTEGER REFERENCES stores(id),
name VARCHAR(100), category VARCHAR(50),
price DECIMAL(10,2), cost DECIMAL(10,2),
is_recommended BOOLEAN DEFAULT FALSE,
tags TEXT[] -- 标签:辣/清淡/儿童适用/招牌
);
CREATE TABLE inventory (
id SERIAL PRIMARY KEY, store_id INTEGER REFERENCES stores(id),
dish_id INTEGER, current_qty DECIMAL(10,2),
unit VARCHAR(20), last_restock DATE
);
CREATE TABLE customer_lifecycle (
customer_id INTEGER PRIMARY KEY REFERENCES customers(id),
lifecycle_stage VARCHAR(20),
churn_probability DECIMAL(5,2), -- 流失概率 0~1
last_stage_change TIMESTAMP,
recommended_action TEXT
);
CREATE TABLE supplier_scores (
id SERIAL PRIMARY KEY, supplier_id INTEGER,
score_type VARCHAR(50), score DECIMAL(3,2),
evidence TEXT, created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE feishu_channels (
id SERIAL PRIMARY KEY, store_id INTEGER REFERENCES stores(id),
channel_type VARCHAR(20), -- 总部群/店长群/门店群
feishu_chat_id VARCHAR(100), is_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE remind_tasks (
id SERIAL PRIMARY KEY, customer_id INTEGER REFERENCES customers(id),
task_type VARCHAR(50), content TEXT,
remind_time TIMESTAMP, is_sent BOOLEAN DEFAULT FALSE
);
2.7 章节实施检查清单
完成本章后,你应该:
- [ ] 有1张手绘的系统架构图(哪怕是草图)
- [ ] 有一份填写完整的需求优先级表(哪怕只有3行)
- [ ] 确认了 PostgreSQL 和 ChromaDB 的组合方案
- [ ] 理解了多门店数据隔离策略
- [ ] 运行了核心10张表的建表SQL
- [ ] 明确了第一期上线的功能优先级(应该是 F01+F03,即客户记忆+飞书机器人)
本章小结
架构设计的核心就三件事:
- 需求表驱动:不要先想技术方案,先把场景和优先级说清楚
- PG+ChromaDB 双库协同:结构化查询用 PG,语义搜索用 ChromaDB
- 门店级数据隔离:所有数据查询强制带
store_id,权限兜底从设计第一天做起
下一章,我们开始构建第一章的核心能力:长期记忆系统。