900 lines
20 KiB
Markdown
900 lines
20 KiB
Markdown
# 关系数据库与通用数据平台技术方案
|
||
|
||
> 版本:V2(精简版)
|
||
>
|
||
> 适用范围:云游荔波及平台后续项目
|
||
>
|
||
> 数据前提:进入平台的数据已经完成采集、清洗、去重、融合和人工确认。
|
||
|
||
## 1. 核心结论
|
||
|
||
平台只保留两套业务数据存储:
|
||
|
||
1. **PostgreSQL:保存处理完成后的正式业务数据,是唯一权威数据源。**
|
||
2. **FalkorDB:保存正式业务数据生成的图谱节点和关系,主要用于关系查询和 ToB 可视化。**
|
||
|
||
不在新的关系数据平台中重复建设原始采集、候选审核、字段级溯源等复杂流程。未经处理的数据不能直接进入正式业务库,应在平台外完成处理后,再按标准模板导入。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A["平台外数据处理\n采集、清洗、去重、融合、审核"] --> B["标准数据文件或 API"]
|
||
B --> C["格式与关联校验"]
|
||
C -->|通过| D["PostgreSQL\n正式业务数据"]
|
||
C -->|不通过| E["错误报告\n退回修正"]
|
||
D --> F["图谱同步队列"]
|
||
F --> G["FalkorDB\n图谱投影"]
|
||
D --> H["通用数据后台\n地图、详情、导入导出"]
|
||
G --> I["图谱浏览器\n关系查询、ToB 展示"]
|
||
```
|
||
|
||
## 2. 数据职责
|
||
|
||
### 2.1 PostgreSQL 保存
|
||
|
||
- 酒店、美食、景区、交通等正式实体。
|
||
- 酒店房型、设施、政策等正式明细。
|
||
- 美食团购、菜系、营业时间等正式明细。
|
||
- 公交线路、方向、站点顺序和线路坐标。
|
||
- 评论、评价标签和图片。
|
||
- 实体之间已经确认的正式关系。
|
||
- 高德、携程、大众点评等外部平台 ID 和 URL。
|
||
- 数据修改记录。
|
||
- 导入、导出任务结果。
|
||
- 图谱同步队列和同步状态。
|
||
|
||
### 2.2 PostgreSQL 不保存
|
||
|
||
- 未清洗的网页或接口原始响应。
|
||
- 未确认的候选实体。
|
||
- 自动匹配过程中的每个中间结果。
|
||
- 重复数据的全部计算过程。
|
||
- 临时爬虫缓存。
|
||
- 无业务意义的实时文案,例如“仅剩 2 间”。
|
||
|
||
### 2.3 FalkorDB 保存
|
||
|
||
- 酒店、美食、景区、交通、公交线路、公交站、片区和行政区节点。
|
||
- 实体与片区、片区与荔波县的空间关系。
|
||
- 景区与子景点关系。
|
||
- 公交线路与站点关系。
|
||
- 已确认的附近、包含、分类等业务关系。
|
||
- 图谱展示需要的名称、类型、坐标和少量摘要属性。
|
||
|
||
### 2.4 FalkorDB 不保存
|
||
|
||
- 完整评论正文。
|
||
- 酒店全部房型和报价。
|
||
- 美食全部团购套餐。
|
||
- 大量设施、政策等详情字段。
|
||
- 导入文件和错误数据。
|
||
- 可从 PostgreSQL 重新生成的重复明细。
|
||
|
||
## 3. 简化后的平台结构
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph PG["PostgreSQL 正式业务库"]
|
||
P1["项目与权限"]
|
||
P2["通用实体"]
|
||
P3["酒店、美食、景区、交通明细"]
|
||
P4["评论、图片、设施、套餐"]
|
||
P5["正式关系"]
|
||
P6["导入导出记录"]
|
||
P7["图谱同步队列"]
|
||
end
|
||
|
||
subgraph API["FastAPI"]
|
||
A1["通用数据表 API"]
|
||
A2["批量导入导出"]
|
||
A3["地图与详情 API"]
|
||
A4["图谱同步服务"]
|
||
end
|
||
|
||
subgraph FK["FalkorDB"]
|
||
F1["正式实体节点"]
|
||
F2["正式业务关系"]
|
||
F3["片区与行政区关系"]
|
||
end
|
||
|
||
subgraph UI["React 管理后台"]
|
||
U1["通用数据管理"]
|
||
U2["荔波地图与详情"]
|
||
U3["图谱浏览器"]
|
||
end
|
||
|
||
PG <--> API
|
||
API --> FK
|
||
API <--> UI
|
||
FK --> U3
|
||
```
|
||
|
||
## 4. PostgreSQL 表结构
|
||
|
||
整体分成四组,避免结构混乱:
|
||
|
||
1. 平台管理表。
|
||
2. 正式实体表。
|
||
3. 业务明细表。
|
||
4. 同步与任务表。
|
||
|
||
### 4.1 平台管理表
|
||
|
||
| 表 | 作用 |
|
||
| --- | --- |
|
||
| `projects` | 项目工作区 |
|
||
| `data_table_registry` | 注册通用后台可管理的业务表 |
|
||
| `data_field_registry` | 定义业务表字段显示和校验规则 |
|
||
| `data_relation_registry` | 定义表之间的关联 |
|
||
| `data_change_logs` | 保存数据修改记录 |
|
||
|
||
通用后台只能访问 `data_table_registry` 中已注册的表,不能任意访问 PostgreSQL。
|
||
|
||
### 4.2 正式实体主表
|
||
|
||
所有地点类业务统一进入 `poi_entities`:
|
||
|
||
```text
|
||
poi_entities
|
||
├── entity_id UUID PK
|
||
├── tenant_id
|
||
├── project_id
|
||
├── entity_type
|
||
├── name
|
||
├── category_l1
|
||
├── category_l2
|
||
├── category_l3
|
||
├── address
|
||
├── district
|
||
├── adcode
|
||
├── phone
|
||
├── longitude
|
||
├── latitude
|
||
├── geom
|
||
├── h3_r9
|
||
├── h3_r10
|
||
├── status
|
||
├── version
|
||
├── created_at
|
||
├── updated_at
|
||
└── extra_data JSONB
|
||
```
|
||
|
||
`entity_type` 的当前标准值:
|
||
|
||
```text
|
||
hotel
|
||
restaurant
|
||
scenic
|
||
transport
|
||
bus_stop
|
||
```
|
||
|
||
主表只保存所有 POI 共有且经常查询的字段。项目特有但暂不稳定的少量字段可以放入 `extra_data`,不能把大段明细或一对多数据塞入其中。
|
||
|
||
### 4.3 外部平台标识
|
||
|
||
`entity_external_links` 只保存已经确认与实体对应的平台标识,不保存原始响应:
|
||
|
||
```text
|
||
entity_external_links
|
||
├── id
|
||
├── tenant_id
|
||
├── project_id
|
||
├── entity_id
|
||
├── platform
|
||
├── external_id
|
||
├── external_name
|
||
├── external_url
|
||
└── updated_at
|
||
```
|
||
|
||
示例:
|
||
|
||
```text
|
||
同一个酒店实体
|
||
├── amap:高德 POI ID 和 URL
|
||
└── ctrip:携程酒店 ID、名称和 URL
|
||
|
||
同一个美食实体
|
||
├── amap:高德 POI ID 和 URL
|
||
└── dianping:大众点评商户 ID、名称和 URL
|
||
```
|
||
|
||
### 4.4 公共明细表
|
||
|
||
| 表 | 内容 |
|
||
| --- | --- |
|
||
| `entity_images` | 实体和房型、套餐图片 |
|
||
| `entity_relations` | 已确认的正式实体关系 |
|
||
| `reviews` | 酒店、美食等真实评论 |
|
||
| `review_tags` | 评论摘要标签 |
|
||
|
||
`entity_relations` 保存正式关系:
|
||
|
||
```text
|
||
relation_id
|
||
tenant_id
|
||
project_id
|
||
source_entity_id
|
||
relation_type
|
||
target_entity_id
|
||
properties JSONB
|
||
status
|
||
updated_at
|
||
```
|
||
|
||
### 4.5 酒店表
|
||
|
||
```text
|
||
hotel_profiles
|
||
hotel_room_types
|
||
hotel_facilities
|
||
hotel_policies
|
||
```
|
||
|
||
#### `hotel_profiles`
|
||
|
||
一间酒店一条记录,保存:
|
||
|
||
- 携程酒店名。
|
||
- 开业时间。
|
||
- 客房数量。
|
||
- 酒店钻级。
|
||
- 携程评分。
|
||
- 用户点评数量。
|
||
- 参考起价。
|
||
- 酒店简介。
|
||
|
||
#### `hotel_room_types`
|
||
|
||
一个房型一条记录:
|
||
|
||
- 房型名称。
|
||
- 图片 URL。
|
||
- 床型。
|
||
- 面积。
|
||
- 楼层。
|
||
- 窗户。
|
||
- 可住人数。
|
||
- 早餐。
|
||
- 取消政策。
|
||
- 支付方式。
|
||
- 参考价格。
|
||
|
||
不保存“仅剩几间”等采集时刻的临时库存文案。
|
||
|
||
#### `hotel_facilities`
|
||
|
||
一个设施一条记录:
|
||
|
||
- 设施分类。
|
||
- 设施名称。
|
||
- 是否免费。
|
||
- 收费说明。
|
||
- 来源 URL。
|
||
|
||
### 4.6 美食表
|
||
|
||
```text
|
||
restaurant_profiles
|
||
restaurant_deals
|
||
restaurant_business_hours
|
||
```
|
||
|
||
#### `restaurant_profiles`
|
||
|
||
- 大众点评店名。
|
||
- 点评分类。
|
||
- 榜单排名。
|
||
- 营业状态。
|
||
- 点评评分。
|
||
- 用户点评数。
|
||
- 人均消费。
|
||
|
||
#### `restaurant_deals`
|
||
|
||
一个套餐一条记录:
|
||
|
||
- 套餐名称。
|
||
- 图片 URL。
|
||
- 当前价格。
|
||
- 原价。
|
||
- 折扣。
|
||
- 使用规则。
|
||
- 有效期。
|
||
|
||
### 4.7 景区表
|
||
|
||
```text
|
||
scenic_profiles
|
||
scenic_children
|
||
```
|
||
|
||
#### `scenic_profiles`
|
||
|
||
- 景区类型。
|
||
- 景区等级。
|
||
- 是否国家级。
|
||
- 游客价值分类。
|
||
- 开放时间。
|
||
- 门票说明。
|
||
- 官方简介。
|
||
|
||
#### `scenic_children`
|
||
|
||
保存景区内部子景点:
|
||
|
||
- 所属景区。
|
||
- 子景点名称。
|
||
- 子景点类型。
|
||
- 坐标。
|
||
- 游览说明。
|
||
|
||
### 4.8 交通表
|
||
|
||
```text
|
||
transport_profiles
|
||
bus_routes
|
||
bus_route_directions
|
||
bus_route_stops
|
||
route_geometries
|
||
```
|
||
|
||
线路站序必须使用独立表,不把站点数组拼接到一个文本字段。
|
||
|
||
### 4.9 空间表
|
||
|
||
保留并复用:
|
||
|
||
```text
|
||
kg_geo_cells
|
||
kg_route_metrics
|
||
```
|
||
|
||
实体坐标在 `poi_entities.geom` 中使用 PostGIS 保存。H3 片区 ID 同时保存在实体主表中。
|
||
|
||
## 5. 通用数据后台
|
||
|
||
通用后台管理的是“平台注册的正式数据表”,不是数据库管理器。
|
||
|
||
### 5.1 表注册
|
||
|
||
`data_table_registry`:
|
||
|
||
```text
|
||
table_code
|
||
project_id
|
||
display_name
|
||
physical_table
|
||
primary_key
|
||
title_field
|
||
parent_table_code
|
||
allow_create
|
||
allow_update
|
||
allow_delete
|
||
allow_import
|
||
allow_export
|
||
graph_enabled
|
||
display_order
|
||
```
|
||
|
||
### 5.2 字段注册
|
||
|
||
`data_field_registry`:
|
||
|
||
```text
|
||
table_code
|
||
field_code
|
||
display_name
|
||
data_type
|
||
required
|
||
searchable
|
||
sortable
|
||
editable
|
||
visible_in_list
|
||
visible_in_detail
|
||
importable
|
||
exportable
|
||
dictionary_values JSONB
|
||
validation_rule JSONB
|
||
display_order
|
||
```
|
||
|
||
后台根据注册信息自动生成:
|
||
|
||
- 数据列表。
|
||
- 查询条件。
|
||
- 新增表单。
|
||
- 编辑表单。
|
||
- 详情页面。
|
||
- CSV/XLSX 模板。
|
||
- 导入校验。
|
||
- 导出字段。
|
||
|
||
### 5.3 第一阶段不做在线建物理表
|
||
|
||
为了保持结构清晰:
|
||
|
||
- 项目管理员可以配置显示、字段顺序、校验和权限。
|
||
- 新增正式物理表或修改列类型仍然通过数据库迁移完成。
|
||
- 后续确实需要用户在线建表时,再作为独立能力设计。
|
||
|
||
这样既能复用一个通用后台,又不会让数据库结构失控。
|
||
|
||
## 6. 增删改查
|
||
|
||
统一 API:
|
||
|
||
```text
|
||
GET /v1/admin/data/{table_code}
|
||
POST /v1/admin/data/{table_code}
|
||
GET /v1/admin/data/{table_code}/{record_id}
|
||
PATCH /v1/admin/data/{table_code}/{record_id}
|
||
DELETE /v1/admin/data/{table_code}/{record_id}
|
||
POST /v1/admin/data/{table_code}/{record_id}/restore
|
||
```
|
||
|
||
### 6.1 查询
|
||
|
||
- 所有查询自动限制 `tenant_id` 和 `project_id`。
|
||
- 只允许查询已注册且标记为可搜索的字段。
|
||
- 使用参数化 SQL,不接受原始 SQL。
|
||
- 默认每页 50 条,单页上限 200 条。
|
||
- 支持筛选、搜索、排序和保存列配置。
|
||
|
||
### 6.2 新增和修改
|
||
|
||
- 按字段注册规则校验。
|
||
- `entity_id` 由服务器生成。
|
||
- 使用 `version` 防止多人覆盖。
|
||
- 保存操作人、时间和修改前后内容。
|
||
- 同一事务写入图谱同步队列。
|
||
|
||
### 6.3 删除
|
||
|
||
默认软删除:
|
||
|
||
```text
|
||
status = deleted
|
||
deleted_at
|
||
deleted_by
|
||
```
|
||
|
||
删除后图谱同步服务删除对应投影。管理员可以恢复。
|
||
|
||
## 7. 批量导入
|
||
|
||
进入平台的是已经处理好的数据,因此导入流程只做结构校验和正式入库,不再做清洗、融合和候选审核。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A["上传处理好的 CSV/XLSX"] --> B["字段和关联校验"]
|
||
B -->|失败| C["下载错误报告"]
|
||
B -->|通过| D["预览新增和更新数量"]
|
||
D --> E["确认导入"]
|
||
E --> F["事务写入正式表"]
|
||
F --> G["同步图谱"]
|
||
```
|
||
|
||
### 7.1 导入只保留一个任务表
|
||
|
||
```text
|
||
data_import_jobs
|
||
├── job_id
|
||
├── tenant_id
|
||
├── project_id
|
||
├── table_code
|
||
├── file_name
|
||
├── file_hash
|
||
├── import_mode
|
||
├── total_rows
|
||
├── inserted_rows
|
||
├── updated_rows
|
||
├── failed_rows
|
||
├── error_file
|
||
├── status
|
||
├── created_by
|
||
├── created_at
|
||
└── completed_at
|
||
```
|
||
|
||
不把每一条原始行长期保存在 PostgreSQL。校验失败行写入临时错误文件,供用户下载修正。
|
||
|
||
### 7.2 导入模式
|
||
|
||
| 模式 | 说明 |
|
||
| --- | --- |
|
||
| 仅新增 | 已存在的唯一键直接报错或跳过 |
|
||
| 新增并更新 | 按主键或外部平台 ID 更新,推荐默认 |
|
||
|
||
第一阶段不提供“完整覆盖并删除缺失数据”,避免误删。
|
||
|
||
### 7.3 校验内容
|
||
|
||
- 必填字段。
|
||
- 数据类型。
|
||
- 唯一 ID。
|
||
- 外键是否存在。
|
||
- 枚举值。
|
||
- 经纬度范围。
|
||
- 坐标是否位于项目允许区域。
|
||
- 公交站序是否连续。
|
||
- 酒店房型是否能找到酒店。
|
||
- 评论是否能找到对应实体。
|
||
|
||
### 7.4 多表数据包
|
||
|
||
酒店、美食等一对多数据使用 ZIP 多表导入:
|
||
|
||
```text
|
||
酒店数据.zip
|
||
├── 酒店实体.csv
|
||
├── 酒店详情.csv
|
||
├── 房型.csv
|
||
├── 设施.csv
|
||
├── 政策.csv
|
||
├── 评论.csv
|
||
└── 图片.csv
|
||
```
|
||
|
||
系统先校验整个数据包的主外键,全部通过后再提交,避免只导入主表、明细缺失。
|
||
|
||
## 8. 批量导出
|
||
|
||
导出全部来自 PostgreSQL 正式表。
|
||
|
||
支持:
|
||
|
||
- 当前表。
|
||
- 当前筛选结果。
|
||
- 选中记录。
|
||
- 主表及全部关联明细。
|
||
- 整个项目数据包。
|
||
- 图谱节点和关系。
|
||
|
||
云游荔波项目导出结构:
|
||
|
||
```text
|
||
云游荔波正式数据_YYYYMMDD.zip
|
||
├── 数据字典.csv
|
||
├── 酒店
|
||
│ ├── 酒店实体.csv
|
||
│ ├── 酒店详情.csv
|
||
│ ├── 房型.csv
|
||
│ ├── 设施.csv
|
||
│ ├── 政策.csv
|
||
│ └── 评论.csv
|
||
├── 美食
|
||
│ ├── 美食实体.csv
|
||
│ ├── 美食详情.csv
|
||
│ ├── 团购套餐.csv
|
||
│ └── 评论.csv
|
||
├── 景区
|
||
│ ├── 景区实体.csv
|
||
│ └── 子景点.csv
|
||
├── 交通
|
||
│ ├── 交通站点.csv
|
||
│ ├── 公交线路.csv
|
||
│ ├── 线路方向.csv
|
||
│ └── 线路站序.csv
|
||
└── 图谱
|
||
├── 节点.csv
|
||
└── 关系.csv
|
||
```
|
||
|
||
导出任务只需要一个 `data_export_jobs` 表记录状态、筛选条件、记录数、文件路径和文件哈希。
|
||
|
||
## 9. 图谱同步
|
||
|
||
为了避免 PostgreSQL 保存成功但 FalkorDB 写入失败,保留一个精简的同步队列表:
|
||
|
||
```text
|
||
graph_sync_queue
|
||
├── event_id
|
||
├── tenant_id
|
||
├── project_id
|
||
├── table_code
|
||
├── record_id
|
||
├── operation
|
||
├── record_version
|
||
├── status
|
||
├── retry_count
|
||
├── error_message
|
||
├── created_at
|
||
└── completed_at
|
||
```
|
||
|
||
业务写入和队列记录在同一个 PostgreSQL 事务中完成。
|
||
|
||
同步流程:
|
||
|
||
1. PostgreSQL 新增、修改或删除正式数据。
|
||
2. 同事务写入 `graph_sync_queue`。
|
||
3. 后台 Worker 读取待处理记录。
|
||
4. 按 `entity_id + version` 幂等更新 FalkorDB。
|
||
5. 成功后标记完成。
|
||
6. 失败自动重试并在后台显示错误。
|
||
|
||
不允许从 FalkorDB 反向修改 PostgreSQL。
|
||
|
||
## 10. 图谱投影
|
||
|
||
### 10.1 节点
|
||
|
||
```text
|
||
Area
|
||
GeoCell(界面显示“片区”)
|
||
Hotel
|
||
Restaurant
|
||
ScenicArea
|
||
Attraction
|
||
TransportStop
|
||
BusStop
|
||
BusRoute
|
||
Category
|
||
```
|
||
|
||
### 10.2 关系
|
||
|
||
```text
|
||
POI -[IN_H3_R9]-> GeoCell
|
||
GeoCell -[LOCATED_IN]-> Area
|
||
POI -[LOCATED_IN]-> Area
|
||
ScenicArea -[CONTAINS]-> Attraction
|
||
BusRoute -[SERVES_STOP]-> BusStop
|
||
BusStop -[NEXT_STOP]-> BusStop
|
||
POI -[HAS_CATEGORY]-> Category
|
||
POI -[NEARBY]-> POI
|
||
```
|
||
|
||
### 10.3 图节点属性
|
||
|
||
只同步:
|
||
|
||
- `entity_id`
|
||
- 名称。
|
||
- 类型。
|
||
- 分类。
|
||
- 经纬度。
|
||
- 地址摘要。
|
||
- 状态。
|
||
- PostgreSQL 数据版本。
|
||
|
||
详情页面需要的完整房型、设施、评论和套餐继续从 PostgreSQL 查询。
|
||
|
||
## 11. 页面数据来源
|
||
|
||
| 页面 | 数据来源 |
|
||
| --- | --- |
|
||
| 通用数据后台 | PostgreSQL |
|
||
| 荔波地图 POI | PostgreSQL + PostGIS |
|
||
| 酒店、美食详情侧栏 | PostgreSQL |
|
||
| 房型、设施、套餐、评论 | PostgreSQL |
|
||
| 公交路线地图 | PostgreSQL |
|
||
| 图谱浏览器 | FalkorDB |
|
||
| 图谱关系查询 | FalkorDB |
|
||
| CSV/XLSX 导出 | PostgreSQL |
|
||
|
||
现有荔波地图和详情布局保持不变,只调整后端数据来源。
|
||
|
||
## 12. 权限与项目隔离
|
||
|
||
所有正式业务表都必须包含:
|
||
|
||
```text
|
||
tenant_id
|
||
project_id
|
||
```
|
||
|
||
后端从当前项目上下文自动获得这两个值,不接受普通用户任意修改。
|
||
|
||
角色建议:
|
||
|
||
| 角色 | 权限 |
|
||
| --- | --- |
|
||
| 系统管理员 | 管理所有项目和注册表 |
|
||
| 项目管理员 | 管理本项目数据、导入导出 |
|
||
| 数据编辑 | 本项目增删改查 |
|
||
| 只读用户 | 查询和受限导出 |
|
||
|
||
## 13. 数据修改记录
|
||
|
||
只保留一个清晰的修改日志表:
|
||
|
||
```text
|
||
data_change_logs
|
||
├── change_id
|
||
├── tenant_id
|
||
├── project_id
|
||
├── table_code
|
||
├── record_id
|
||
├── operation
|
||
├── before_data JSONB
|
||
├── after_data JSONB
|
||
├── actor
|
||
├── reason
|
||
└── created_at
|
||
```
|
||
|
||
不再额外设计字段级来源选择、候选状态机和多套版本表。
|
||
|
||
## 14. 索引
|
||
|
||
核心索引:
|
||
|
||
```text
|
||
poi_entities (tenant_id, project_id, entity_type, status)
|
||
poi_entities (tenant_id, project_id, updated_at DESC)
|
||
poi_entities UNIQUE (tenant_id, project_id, entity_id)
|
||
entity_external_links UNIQUE
|
||
(tenant_id, project_id, platform, external_id)
|
||
poi_entities USING GIST (geom)
|
||
bus_route_stops UNIQUE (route_direction_id, stop_order)
|
||
reviews (entity_id, created_at DESC)
|
||
graph_sync_queue (status, created_at)
|
||
```
|
||
|
||
地图接口必须按当前视窗查询,不允许一次返回全部 POI。
|
||
|
||
## 15. 现有系统如何迁移
|
||
|
||
### 第一步:备份
|
||
|
||
- 导出当前 PostgreSQL 快照。
|
||
- 导出当前 FalkorDB RDB。
|
||
- 统计酒店、美食、景区、交通、公交和片区数量。
|
||
|
||
### 第二步:建立正式关系表
|
||
|
||
- 引入 Alembic。
|
||
- 补齐 PostGIS。
|
||
- 创建正式实体和业务明细表。
|
||
- 创建表注册、导入导出、修改日志和图谱队列表。
|
||
|
||
### 第三步:只迁移最终数据
|
||
|
||
- 从当前 FalkorDB 和已经整理好的 CSV 导出最终结果。
|
||
- 不迁移临时爬虫数据和中间匹配过程。
|
||
- 按 `entity_id`、高德 POI ID 和已确认平台 ID 建立关联。
|
||
- 酒店房型、设施、评论和美食套餐拆成明细表。
|
||
|
||
### 第四步:上线通用后台
|
||
|
||
- 注册酒店、美食、景区、交通等正式表。
|
||
- 自动生成列表、详情、编辑和导入导出页面。
|
||
- 现有业务页面暂时不变。
|
||
|
||
### 第五步:切换详情和地图
|
||
|
||
- 荔波地图、统计、筛选和详情读取 PostgreSQL。
|
||
- 图谱浏览器继续读取 FalkorDB。
|
||
|
||
### 第六步:启用图谱同步
|
||
|
||
- 开启 `graph_sync_queue` Worker。
|
||
- 对比新图谱和当前图谱。
|
||
- 确认一致后停止其他脚本直接修改 FalkorDB。
|
||
|
||
### 第七步:旧流程只读保留
|
||
|
||
现有以下数据仍可保留用于历史查看,但不属于新正式业务数据链路:
|
||
|
||
- `raw_records`
|
||
- `candidate_entities`
|
||
- `candidate_relations`
|
||
- `review_actions`
|
||
- `publish_jobs`
|
||
|
||
新数据不再经过这些表。
|
||
|
||
## 16. 代码结构
|
||
|
||
后端:
|
||
|
||
```text
|
||
app/data_platform/
|
||
├── registry.py
|
||
├── record_service.py
|
||
├── query_service.py
|
||
├── import_service.py
|
||
├── export_service.py
|
||
└── graph_sync_service.py
|
||
|
||
app/api/data_platform.py
|
||
app/workers/graph_sync_worker.py
|
||
app/migrations/
|
||
```
|
||
|
||
前端:
|
||
|
||
```text
|
||
admin-web/src/panels/data-platform/
|
||
├── TableList.tsx
|
||
├── DataTable.tsx
|
||
├── RecordForm.tsx
|
||
├── RecordDetail.tsx
|
||
├── ImportDialog.tsx
|
||
├── ExportDialog.tsx
|
||
└── SyncStatus.tsx
|
||
```
|
||
|
||
## 17. 验收标准
|
||
|
||
### 数据
|
||
|
||
- PostgreSQL 中的实体数量与最终确认数据一致。
|
||
- 每个实体只有一个稳定 `entity_id`。
|
||
- 酒店房型、设施、评论等明细均能正确关联主实体。
|
||
- 所有地图实体都有合法坐标或明确的无坐标状态。
|
||
- 不迁移临时库存和重复文本。
|
||
|
||
### 后台
|
||
|
||
- 注册一张业务表后,可自动获得查询、新增、编辑、删除、导入和导出能力。
|
||
- 普通用户不能访问未注册表。
|
||
- 不同项目之间不能看到或修改对方数据。
|
||
- 删除记录可以恢复。
|
||
|
||
### 图谱
|
||
|
||
- PostgreSQL 修改后自动更新 FalkorDB。
|
||
- 同步失败不影响 PostgreSQL 保存。
|
||
- 重复处理同一同步事件不会产生重复节点。
|
||
- FalkorDB 可以从 PostgreSQL 全量重建。
|
||
- 实体、片区和荔波县保持连通,不产生独立片区。
|
||
|
||
### 性能
|
||
|
||
- 列表默认 50 条分页。
|
||
- 常规查询 P95 小于 500 ms。
|
||
- 地图只查询当前视窗。
|
||
- 10,000 行处理好数据能够完成校验和导入。
|
||
|
||
## 18. 实施优先级
|
||
|
||
### P0:正式数据表
|
||
|
||
- `poi_entities`
|
||
- 外部平台链接。
|
||
- 酒店、美食、景区、交通明细。
|
||
- 评论、图片和正式关系。
|
||
|
||
### P1:通用后台
|
||
|
||
- 表和字段注册。
|
||
- 通用增删改查。
|
||
- 软删除和修改日志。
|
||
|
||
### P2:导入导出
|
||
|
||
- 标准模板。
|
||
- 单表和 ZIP 多表导入。
|
||
- 错误报告。
|
||
- 多表数据包导出。
|
||
|
||
### P3:图谱同步
|
||
|
||
- `graph_sync_queue`。
|
||
- 图谱 Worker。
|
||
- 同步状态和失败重试。
|
||
|
||
### P4:现有页面切换
|
||
|
||
- 荔波地图。
|
||
- 酒店、美食、景区、交通详情。
|
||
- 公交线路。
|
||
- 图谱浏览器保持不变。
|
||
|
||
## 19. 最终原则
|
||
|
||
1. 只允许处理完成的数据进入正式业务库。
|
||
2. PostgreSQL 只保存最终业务数据和必要运行记录。
|
||
3. FalkorDB 只保存最终数据的图谱投影。
|
||
4. 通用后台只管理平台注册的正式表。
|
||
5. 一对多数据必须拆成关系表。
|
||
6. 导入只做校验和入库,不再做数据清洗与融合。
|
||
7. 导出以 PostgreSQL 为唯一来源。
|
||
8. 所有业务修改先写 PostgreSQL,再异步更新图谱。
|
||
9. 现有候选审核流程与新正式数据平台分离。
|
||
10. 先完成清晰、稳定的数据主链路,再增加高级能力。
|