PostgreSQL文档编辑与撤销功能的关系表设计咨询
文档编辑场景的PostgreSQL表设计方案分析
单表方案(document表)
- 核心设计:通过
status字段(DRAFT/ENTERED)区分正式文档和编辑草稿,新增original_document_id关联原文档(正式文档该字段为NULL),配合edited_by_id记录编辑人。 - 优势:结构极简,无需跨表操作,查询、维护成本低;适合仅需单次编辑、无需保留历史版本的场景。
- 劣势:数据隔离性差,易出现误操作(比如误将正式文档标记为草稿);若需保留多版本编辑历史,仅靠
status字段无法满足,会导致表内数据冗余混乱。
分表方案(document + document_edit表)
- 核心设计:
document表存储已录入的正式文档,document_edit表存储编辑中的草稿,后者通过original_document_id关联原文档。 - 优势:正式数据与草稿完全隔离,避免误操作;可给草稿表单独扩展编辑相关字段(如编辑时长、操作日志),不影响正式表结构;未来扩展多人协作、草稿审核等功能时更灵活。
- 劣势:需维护两张表,保存更新时需同时操作正式表和草稿表,逻辑稍复杂;跨表查询关联成本略高。
最优方案建议
- 单次编辑无历史需求:优先选择单表方案,但必须补充
original_document_id字段(核心关联逻辑),同时保留status、edited_by_id、updated_at字段。 - 需保留编辑历史/未来有扩展需求:选择分表方案,甚至可将
document_edit改为document_version表,用is_active字段标记当前生效的正式文档,所有版本(包括草稿、历史正式版)都存在该表,document表仅存文档的基础元数据(如文档编号、所属用户),这种设计更具扩展性。
补充:文档行数据的表设计
无论采用哪种方案,建议单独创建document_item表存储文档的行数据(对应添加/删除行、调整数量、批量预留等操作),字段示例:
CREATE TABLE document_item ( id SERIAL PRIMARY KEY, document_id INT REFERENCES document(id) ON DELETE CASCADE, product_id INT, quantity NUMERIC(10,2), is_reserved BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
这样主表仅存储文档元数据,避免数据冗余,也便于单独对行数据进行增删改操作。
内容的提问来源于stack exchange,提问作者skelaw
相关产品推荐
相关产品推荐

