知识全景图/ 软件工程与系统/ 如何设计业务数据库/ 导入、去重与对账

如何设计数据库导入、去重与对账

导入不是批量 insert,而是外部事实进入系统前的一道验收门。

这页只讲一件事:同一份银行流水导入两次,系统怎样不重、不漏、不误合并。

一、先看事故
事故根因设计动作
同一文件上传两次,月报翻倍。没有批次和文件指纹。import_batches,保存来源和 file_hash
CSV 有错行,但页面显示成功。原始行没有入库,失败原因丢了。import_rows,每行都有状态。
同日同额两笔消费被合并。弱指纹被当成强唯一键。强匹配可自动去重,弱匹配只能出候选。
手动账和导入账重复。导入直接写事实表。先匹配候选,再决定创建、合并或忽略。
想撤销导入却不知道删哪几条。事实行没有来源链接。事实表和原始行之间保留链接。
判断:事实表只接收已经解析、去重、确认过的数据;导入过程本身也必须可追溯。
二、建表前只问 5 个问题
问题最低设计
这次导入是谁发起、来自哪个文件或接口?import_batches 保存来源、文件 hash、状态、统计。
每一行原始输入去哪了?import_rows 保存原始内容、解析结果、错误原因。
什么算重复?外部交易号是强匹配;日期金额商户是弱候选。
手动账和导入账怎么合并?候选匹配要保留用户分类、备注和确认记录。
导入完成怎么证明?行数、金额、错误、重复、来源链接都要对得上。
三、最小模型
import_batches: id, ledger_id, source_type, file_hash, status row_count, success_count, duplicate_count, error_count import_rows: id, batch_id, row_no, raw_payload normalized_payload, row_status, error_message candidate_entry_id, applied_entry_id entry_import_links: ledger_entry_id, import_batch_id, import_row_id external_txn_id, match_type
四、验收规则
样本通过标准
同一文件重复上传。第二次不创建新事实行。
同一交易出现在不同文件。按外部交易号去重。
没有外部交易号。只能进入候选,不能静默合并。
解析失败行。有错误原因,批次不能假成功。
导入到一半失败。重跑幂等,不扩大影响范围。
五、下一步
重复写入
继续看幂等、事务、唯一约束和重试语义。
生产已导错
继续看 dry-run、小批次修复和复核。
记住:导入设计的核心不是快,而是证据链。先保留批次和原始行,再谈写入事实表。