← 返回展示台

房屋租赁 SaaS 平台 · 基础数据梳理

版本:v0.1(草案,待调研结论回填后定稿)
目标规模:百万级房源 / 千万级租客 / 亿级账单流水
技术栈前提:Java 生态,多租户 SaaS
落盘位置:/Volumes/Extreme Pro/Workspace/rental-saas-20261018/


一、先把「数据」分成四类,这是整个设计的地基

绝大多数租赁系统设计失败的根因,是把四类生命周期完全不同的数据混在一张表里。本设计的

第一原则是按数据性质分层,而不是按业务模块分表。

类别特征典型数据存储载体变更频率
A. 主数据(Master)有唯一身份、被引用、需强一致租户、楼盘、楼栋、房间、租客、设备PostgreSQL(OLTP)低
B. 事务数据(Transactional)有状态机、有流水、需审计与对账合同、账单、收款、工单PostgreSQL(OLTP)+ 时间分区高
C. 时序/事件数据(Time-series)写多读少、按时间窗口聚合、几乎不改IoT 设备上报、门锁记录、操作审计、Agent 调用日志时序库(ClickHouse 为主)极高
D. 非结构化数据(Unstructured)大对象、内容寻址房源图片、视频、AR 全景图/glTF 模型、合同扫描件、工单现场照片对象存储(RustFS/S3)+ 元数据表中

关键结论:

  1. A + B 全部进 PostgreSQL,不拆库。理由:租赁业务本质是强事务 + 强关联(收租要对账、

合同要留痕),分布式事务带来的复杂度远大于它买到的扩展性。百万房源 / 千万租客这个量级,

PostgreSQL 单集群配好分区完全扛得住(详见 03 文档容量测算)。

  1. C 绝对不能进 PostgreSQL 主库。IoT 设备上报按每户 10 个设备、每 5 分钟一次估算,

百万房源即产生 每年 10 亿+ 行写入,压垮 OLTP 主库只是时间问题。必须旁路到时序库。

  1. D 的文件字节一律不进数据库,库里只存 media_asset 元数据 + 对象存储 key。

这是图片/视频/AR 模型这类大对象的唯一正确做法。


二、九大业务域的基础数据实体

按你给的范围(数字家庭、工单、物业、长短租、房源含 AR、Agent 能力)拆解。

每域只列「基础数据」,即需要持久化并有明确生命周期的实体,不含派生视图与缓存。

域 1 · 平台与租户(Platform / Tenancy)

这是 SaaS 的地基,所有业务表都必须挂在租户下。

实体说明关键字段
tenant租户(一家运营公司),SaaS 隔离单元租户码、名称、套餐、状态、隔离策略
tenant_config租户级配置(计费规则、账期、时区、编号规则)键值对 + 类型
user_account平台登录账号(与「租客」是两回事)手机号、密码散列、MFA
role / permissionRBAC 权限模型角色、权限码
user_role_binding账号-角色绑定—
user_tenant_binding账号-租户绑定(一人可服务多租户)—
data_scope_rule数据权限(某账号只看某几个楼盘)资源类型 + 范围

⚠️ 必须区分 user_account(系统操作者)与 tenant_person(租客自然人)。
二者可能重合(租客也登录 App),但绝不能合并 —— 系统操作者没有租赁合同,
租客也不需要后台权限。混表是租赁系统最常见的设计债。

域 2 · 资产与房源(Asset / Property)

房源是多层级结构,且长租与短租共用一套物理资产。

实体说明层级
property物业项目 / 小区1
building楼栋2
unit单元 / 座3
floor楼层(可虚拟)4
room房间 / 房源(核心实体)5
room_attribute房间属性(面积、朝向、户型、装修、配套),支持扩展—
room_status_log房间状态变更留痕(空置/预定/在租/维修/停用)—
bed床位(合租场景,一间房多床)6
parking_space车位(也是可租资产)附属
amenity配套设施字典(健身房、泳池)字典
room_amenity房间-设施关联关联

设计要点:room 是「可出租的最小单元」,一切租赁、账单、设备都挂在 room_id 上。
短租与长租的差异不在物理表,而在「库存维度」:长租房间同一时刻只有 0/1 份库存,
短租需要间夜库存日历(见下)。

实体说明
room_calendar间夜库存日历(短租核心),按 room_id + biz_date 唯一,记录可售/已售/价格/限制
rate_plan价格方案(长租月租价、短租日价、阶梯价、会员价)
rate_policy价格策略(连住折扣、提前订优惠、最低入住天数)

防超卖的唯一正确做法:以 room_calendar 的 (room_id, biz_date) 唯一约束 +
行级锁(或 UPDATE ... WHERE sold_count < total_count 条件更新)做原子性扣减。
绝不能「先查再写」。

域 3 · 客户与租客(Customer / Person)

实体说明
tenant_person租客自然人(个人),含证件、手机、实名状态
tenant_org企业租客(公司名义承租)
tenant_person_org个人-企业归属(员工、联系人)
guarantor担保人
credit_profile信用档案(欠租记录、黑名单、评分)
tenant_person_identity证件附件与实名认证记录(走对象存储)
contact_record沟通/跟进记录(为 Agent 能力准备语料)

千万级租客的存储要点:租客表是跨租户全局实体还是租户内实体?
这是本设计最重要的一个判断 —— 同一自然人在两家运营公司都租过房,
若做成租户内实体会产生重复身份,风控与黑名单失效。**结论:租客自然人做全局表,
通过关联表挂到租户下**(详见 02 文档多租户章节的「混合隔离」)。

域 4 · 合同与租赁(Contract / Lease)

实体说明
contract合同主表,含类型(长租/短租)、起止、状态机
contract_party合同当事人(承租方、出租方、担保人、共租人)
contract_room合同-房间关联(一合同可含多间房)
contract_term合同条款(版本化,JSONB 存结构化条款)
contract_change变更单(续租、换房、改价、提前退租),保留原合同不动
contract_deposit押金记录(应收/实收/退还/扣除)
checkin_record入住/退租交割(水电底数、物品清单、钥匙)
contract_file合同电子档与电子签章记录

核心原则:合同只增不改。 任何变更都产生 contract_change 新记录 +
生成新版本,contract 上只维护 current_version。否则历史对账必然出错。

域 5 · 计费与收租(Billing / Payment)

实体说明
bill账单(租金/押金/水电/物业费/违约金),按月/按周期生成
bill_item账单明细(一张账单可拆多个费用项)
bill_period账期定义
fee_item费用项字典(租金、水费、电费、物业费、停车费)
meter仪表(水/电/燃气表),关联房间
meter_reading抄表读数(时序性质,但需精确保留)
payment收款流水(一笔支付)
payment_allocation核销明细(一笔收款核销多张账单)
refund退款单
invoice发票(申请、开具、红冲)
dunning_record催缴记录(为 Agent 自动催收准备)
late_fee_rule滞纳金规则

收租建模的关键:payment 与 bill 是多对多,必须用 payment_allocation 连接。
新人最常犯的错是给 bill 加一个 payment_id 字段 —— 一次性付清 3 个月房租就无法表达。
核销明细表还必须记录每笔核销金额,且核销过程幂等(唯一键 = 支付流水号 + 账单号)。

域 6 · 物业与工单(Property Service / Work Order)

实体说明
service_catalog服务项目录(保洁、维修、代收快递)
work_order工单主表,含类型、优先级、状态机
work_order_item工单明细(材料、工时、费用)
work_order_flow工单流转记录(谁在何时做了什么)
work_order_attachment现场照片/视频(对象存储引用)
staff服务人员(维修工、管家)与技能标签
dispatch_record派单记录
sla_ruleSLA 规则(响应时限、完工时限)
inspection_task巡检任务与巡检点

工单是强状态机实体,状态流转必须有 work_order_flow 全量留痕,
不允许只更新 work_order.status。否则 SLA 计时与责任判定无从谈起。

域 7 · 数字家庭 / IoT(Smart Home)

实体说明
device设备主数据(门锁、电表、水表、传感器、摄像头)
device_model设备型号与能力定义(支持的属性/指令)
device_binding设备-房间-租户绑定关系(含生效时间段)
device_credential设备密钥/证书
device_shadow设备影子(最新状态快照,覆盖写)
device_event设备事件(开锁、告警)→ 时序库
device_telemetry设备遥测(温度、电量)→ 时序库
device_command指令下发记录(含下发/回执状态)
scene / scene_action场景联动(回家模式、离家模式)
access_grant门锁临时密码/权限(租客、保洁、维修)

device_shadow(影子)与 device_telemetry(时序)必须分开:
前者是「此刻状态」,一张小表高频覆盖写,查询 O(1);
后者是「历史轨迹」,写入时序库。混在一起会让状态查询变成全表扫描。

域 8 · 多媒体与 AR 看房(Media / AR)

实体说明
media_asset媒体资源元数据(图片/视频/音频/模型),不存字节
media_variant多规格派生(缩略图、不同清晰度),一源多规格
media_binding媒体-业务对象绑定(房间、合同、工单、设备)
ar_sceneAR 场景(一个房间可有多套场景/多期拍摄)
ar_scene_node场景节点(全景图球面、三维模型、热点锚点)
ar_hotspot热点(点击跳到某位置/展示某信息/触发某操作)
ar_camera_path相机轨迹(漫游路线)
ar_scene_version场景版本(重新拍摄、模型更新)
vr_session看房会话(谁在何时看了哪个场景、停留时长)→ 行为数据

AR 看房的数据本质是三块:
① 全景图/立方体贴图(大文件,对象存储,按瓦片切分);
② glTF/GLB 三维模型(含 Draco 压缩,对象存储 + 版本号);
③ 空间锚点元数据(热点坐标、相机轨迹、房间尺寸),这部分是**小体积强结构数据,
必须进 PostgreSQL**,因为它要和房间、设备、账单关联(例如热点上挂「这台空调每月耗电」)。
千万不要把锚点数据塞进模型文件里 —— 那样就无法做「点热点→查真实设备状态」的联动。

域 9 · Agent 能力(AI Agent)

这是最新的一块,也是最容易被设计成「一堆散字段」的一块。

实体说明
agent_definitionAgent 定义(名称、系统提示词、可用工具集、模型配置)
agent_tool工具注册表(工具名、参数 Schema、后端实现、权限要求)
agent_session会话(谁、哪个渠道、关联哪个业务对象)
agent_message消息(角色、内容、token 用量、耗时)
agent_tool_call工具调用记录(入参、出参、是否成功、耗时)→ 审计用
agent_memory长期记忆(结构化键值 + 向量)
knowledge_doc知识库文档(制度、FAQ、话术)
knowledge_chunk文档切片 + 向量(pgvector)
prompt_template提示词模板与版本

Agent 落地的三个数据要点:
1. 工具调用必须可审计:agent_tool_call 要记录入参出参,否则 Agent 误操作无法追责。
2. 向量不必上专用库:本机 PostgreSQL 17 已装 pgvector 0.8.7,知识库切片量级
(十万~百万级)用 pgvector + HNSW 索引完全够用,省掉一套独立向量库的运维成本。
超过千万切片再考虑迁移。
3. Agent 的「记忆」要区分短期(会话上下文)与长期(跨会话画像),
长期记忆才是让它「越用越懂这个租客」的关键,也是租赁场景最值钱的数据资产。


三、跨域的关系主干(一张图看懂全局)

tenant (租户)
  ├── property (小区) ── building ── unit ── floor ── room ── bed
  │                                                      ├── room_attribute
  │                                                      ├── room_calendar (短租库存)
  │                                                      ├── device_binding ── device ── device_shadow
  │                                                      ├── media_binding ── media_asset
  │                                                      └── ar_scene ── ar_scene_node ── ar_hotspot
  │
  ├── tenant_person (租客,全局实体) ── credit_profile
  │        │
  │        └── contract ── contract_party / contract_room / contract_term
  │                 ├── bill ── bill_item
  │                 │      └── payment_allocation ── payment
  │                 └── contract_change (变更留痕)
  │
  ├── work_order ── work_order_flow / work_order_item / dispatch_record
  │        └── 关联 room / contract / tenant_person
  │
  └── agent_session ── agent_message ── agent_tool_call
           └── 关联任意业务对象 (多态引用)

三条贯穿全局的引用原则:

  1. room_id 是资产轴的唯一锚点 —— 设备、媒体、AR 场景、合同、工单最终都归到房间。
  2. contract_id 是履约轴的唯一锚点 —— 账单、押金、交割、催缴都归到合同。
  3. tenant_person_id 是人的唯一锚点 —— 但它是全局实体,不随租户隔离(见 02 文档)。

四、决策结论与遗留问题

已定案(本轮设计给出结论)

#问题结论依据
1租客自然人是全局实体还是租户私有?全局实体,不做租户隔离若隔离,跨公司黑名单失效,风控形同虚设。用哈希查重 + 证件加密平衡隐私。详见 02 文档
2短租是否与长租同库同表?同表 room,短租靠 room_calendar 库存日历物理资产是同一份,差异只在库存维度。分表会导致同一房间两套身份
4时序库选 ClickHouse 还是 TimescaleDB?ClickHouse遥测是纯追加+聚合场景,正是其主场;TimescaleDB 与主库同实例会抢 OLTP 资源。详见 02 文档
7向量库用专用还是 pgvector?pgvector(本机已装 0.8.7)百万切片以内 HNSW 足够,省一套中间件运维

仍需业务方确认(不影响建表,影响上层实现)

#问题影响建议
3是否需要 PostGIS?本机未安装,需运维部署若要做「地铁房」「学区房」「地图选址」,建议装。当前用 lng/lat 两列 + 应用层算距离,10 万房源内可接受
5电子签章自建还是第三方?影响 contract_file.sign_provider 取值强烈建议接第三方(法大大/e签宝),自建电子签法律效力难保证
6AR 看房自研还是接第三方?影响 ar_scene* 表的粒度建议接第三方拍摄能力(如贝壳如视/众趣),但锚点数据必须存自己库——否则业务联动被厂商锁死。本设计的 ar_hotspot 已按此预留
8短租房源是否与 OTA(携程/美团)打通?影响是否需要「渠道库存同步表」若要打通,需增加 channel_inventory 表做多渠道库存映射与超卖防护。这是一个隐藏的大坑:多渠道库存同步需分布式锁 + 补偿队列

下一步建议的实施顺序

  1. 先做域 1-5(平台/房源/租客/合同/收租) —— 这是业务闭环的最小集,

没有收租就没有商业模式。

  1. 再做域 6(工单) —— 直接决定租客满意度与续租率。
  2. 域 7(IoT)与域 8(AR) —— 差异化竞争力,但依赖硬件与内容生产,

建议先做单一楼盘试点。

  1. 域 9(Agent)最后 —— 它是放大器,没有前面的数据积累,

Agent 无米下锅。但 agent_tool_call 等审计表建议早期就建,

因为工具调用日志越早积累越有价值。


本文档为基础数据梳理草案,详细表结构与 DDL 见 02-多租户与技术栈选型.md、03-数据库设计.md。

目录

  1. 一、先把「数据」分成四类,这是整个设计的地基
  2. 二、九大业务域的基础数据实体
  3. 三、跨域的关系主干(一张图看懂全局)
  4. 四、决策结论与遗留问题