面向企业负责人和技术人员,解释 CRM 系统中客户、联系人、商机、跟进记录等核心实体的关系设计、字段扩展、索引策略、审计日志与数据隔离方案。

软件定制开发团队
"真正有价值的技术内容,应该能帮助客户更快判断方向、预算和落地路径。"
一个 CRM 系统的质量,很大程度上取决于数据库设计。如果表结构混乱,后续功能扩展会非常困难,查询性能也会急剧下降。本文从企业实际需求出发,讨论客户、联系人、商机、跟进记录这四个核心实体的关系,以及扩展字段、索引、审计和数据隔离的常见做法。
以下内容适用于计划自建 CRM 或定制开发的企业负责人和技术团队。我们不会罗列所有字段,而是聚焦于关键关系和设计决策。
客户是 CRM 中最顶层的实体,通常代表一个公司或组织。在设计时,需要考虑以下几点:
常见的客户表字段示例(非完整列表):
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | bigint | 主键 |
| name | varchar(255) | 客户名称 |
| type | smallint | 客户类型代码 |
| parent_id | bigint | 上级客户ID |
| industry | varchar(100) | 行业 |
| source | varchar(50) | 来源渠道 |
| status | smallint | 状态(跟进中/已成交/已流失) |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
联系人是客户下的具体人员。一个客户可以有多个联系人,一个联系人也可以属于多个客户(例如顾问同时在多家公司任职)。常见设计有两种:
实际项目中,约 80% 的企业选择一对多设计。如果业务确实需要跨公司联系人,建议在中间表中增加“主要客户”标记字段。
联系人字段需要注意:
商机代表一个可能的销售机会,通常关联到客户和联系人。商机表是 CRM 中数据变化最频繁的表之一,设计时需要重点关注:
商机表常见字段:
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | bigint | 主键 |
| account_id | bigint | 关联客户 |
| contact_id | bigint | 主要联系人(可选) |
| name | varchar(255) | 商机名称 |
| amount | decimal(15,2) | 预计金额 |
| probability | smallint | 成交概率(0-100) |
| stage_id | smallint | 当前阶段 |
| expected_close_date | date | 预计成交日期 |
| owner_id | bigint | 负责人 |
| created_at | timestamp | 创建时间 |
跟进记录是 CRM 中数据量最大的表,记录每一次与客户的交互。包括电话、邮件、会议、拜访等。
设计要点:
跟进记录表字段示例:
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | bigint | 主键 |
| type | smallint | 活动类型(1-电话,2-邮件,3-会议) |
| target_type | varchar(50) | 关联对象类型(account/contact/opportunity) |
| target_id | bigint | 关联对象ID |
| content | text | 跟进内容 |
| start_time | timestamp | 开始时间 |
| duration | int | 持续时间(分钟) |
| creator_id | bigint | 创建人 |
| created_at | timestamp | 创建时间 |
没有两个企业的 CRM 需求完全一样。扩展字段的设计直接影响系统的灵活性。
对于大多数中小型项目,JSONB 方案在灵活性和性能之间取得了较好的平衡。如果预计扩展字段的查询非常频繁,可以考虑将高频扩展字段拆为独立列。
在项目初期,不要过度设计扩展字段。先确定 80% 的通用字段,预留一个 JSON 字段即可。随着业务发展,再逐步将高频使用的 JSON 字段提升为独立列。
CRM 系统的查询模式相对固定,主要集中在:按客户名称搜索、按联系人手机/邮箱查找、查询某个商机的跟进记录、按负责人查看待办事项。针对这些模式设计索引,可以避免大部分性能问题。
复合索引需要根据实际查询语句设计。例如,如果经常查询“某负责人在某阶段的商机”,可以建立 (owner_id, stage_id) 复合索引。如果查询条件还包括金额范围,则考虑 (owner_id, stage_id, amount)。
需要注意的是,复合索引的字段顺序很重要。将区分度高的字段放在前面,可以更有效地缩小查询范围。
如果跟进记录的内容需要全文搜索,建议使用数据库自带的全文索引(MySQL FULLTEXT 或 PostgreSQL tsvector),而不是 LIKE '%keyword%'。后者在数据量超过十万条后性能会急剧下降。
CRM 中的数据变更需要可追溯。审计日志不仅用于合规,也用于销售管理(如查看谁修改了商机金额)。
实际项目中,推荐使用应用层加数据库触发器的混合方案:核心表(商机、客户)使用触发器强制记录,次要表在应用层记录。
审计日志数据增长很快。建议按月或按季度进行归档,将超过一年的日志迁移到历史表或冷存储。归档策略应在设计阶段就考虑,避免后期数据量过大导致维护困难。
如果 CRM 系统需要服务多个部门或子公司,数据隔离是必须解决的问题。
对于大多数企业自用 CRM,共享表方案足够。如果涉及跨公司数据共享(如集团 CRM),可以考虑独立 Schema 方案。
除了租户隔离,还需要行级权限控制。例如,销售人员只能看到自己的客户,经理可以看到团队客户。
常见实现方式:
在实际项目中,这三种方式通常组合使用。权限控制逻辑建议放在应用层,而不是数据库层,因为数据库层实现行级权限会显著增加查询复杂度。
一个好的 CRM 数据库设计,不是一蹴而就的。以下是一些经验总结:
如果团队正在规划 CRM 系统,建议先从核心实体和关系开始,用最小可行产品验证业务逻辑,再逐步引入扩展字段、审计和权限控制。SystemDo 在多个 CRM 项目中采用的原则也是先稳定主数据模型,再围绕已经验证的查询和流程增加复杂度。
继续了解企业数字化、SEO / GEO、AI 自动化和软件定制开发中的常见问题。