简介《信贷数据库设计说明》是一份面向银行、金融机构及信贷系统开发、数据架构和测试人员的数据库设计文档完整覆盖信贷业务核心模块。文档以2018年1月最终修订版为准从总体设计规范出发明确了数据划分、表/字段/索引设计原则、对象命名规则、安全保密设计等基础内容再通过概念结构设计梳理客户管理、评级管理、授信申请、审批流程、合同管理、出账日终、贷后管理、减值准备、担保管理等模块的关系最后以逻辑结构设计提供各模块关系图、表清单与表明细便于直接指导建库和开发。资源包为单个docx文件压缩后大小约2.14MB适合作为信贷类项目数据库设计的参考模板或开发依据。目前已有232人学习下载内容结构清晰、颗粒度细尤其适合需要快速理解信贷业务数据模型或编写相似设计说明的读者。1. 信贷数据库设计说明解决的是对不上账和并发超放信贷数据库设计说明不是一份简单的建表清单而是把信贷业务规则翻译成库表、字段、约束、索引、账务科目和跑批口径的文档。很多团队开发速度很快建表半天搞定但到了月底结息对不上账、两笔放款同时扣额度导致超授信、提前还款后还款计划残留脏数据才回头翻设计文档发现关键规则根本没写清楚。这份说明要回答的问题很具体一笔借款从授信、放款到还款结清中间哪些数据必须落库状态怎么流转额度怎么扣又怎么恢复利息按什么口径算逾期从哪天开始计。它的读者也明确开发照着建表DBA 评估容量和分库策略风控同学抽数核口径以及对账负责人查每一分钱的来龙去脉。适合正在做信贷核心系统、消费金融系统或网贷平台账务模块的从业者参考。2. 核心实体怎么拆从客户到借据的表结构设计2.1 客户、授信、合同、借据先定四个主节点信贷数据库设计和普通业务系统最大的区别是多了一张「借据」表。电商订单、博客文章都可以围绕单一主实体建模但信贷系统里一笔借款从申请到结清要穿过四条数据链路客户信息、授信额度、合同借据、交易账务。常见做法是把这四条链路的物理模型拉开至少拆成以下这几个主节点实体主键业务含义上游关系客户表 customercust_id借款人主体信息独立入口授信表 credit_limitcredit_no客户可用总额度按客户 1:N借据表 loan_agreementagree_no单笔放款凭证按授信 1:N还款计划表 repay_planplan_id逐期应还本金利息按借据 1:N交易流水表 repay_transtrans_id实际还款入账明细按计划 1:N这里的核心决策是「合同」和「借据」到底拆不拆两张表。有些团队直接把合同当作借据一张表搞定理由是个人信贷合同就是一次放款。但一旦出现「循环贷」「随借随还」一个授信合同下会产生多笔借据不拆表就会让合同信息大量冗余。我一般建议拆开授信是额度维度借据是放款维度合同是法律维度三者在设计说明里各占一节别混在一起写。2.2 借据表 DDL字段、索引与状态值怎么落借据表是整份信贷数据库设计说明里最重要的一张表。它连接客户、额度、还款计划和交易流水所有跑批逻辑都以借据为入口。给出最小可用的建表语句后面讲字段取舍。CREATE TABLE loan_agreement ( agree_no varchar(32) NOT NULL COMMENT 借据号业务唯一, cust_id varchar(32) NOT NULL COMMENT 客户号对应customer表, credit_alloc_no varchar(32) DEFAULT NULL COMMENT 额度占用流水号, product_code varchar(16) NOT NULL COMMENT 产品编号, principal decimal(20,2) NOT NULL COMMENT 放款本金, rate decimal(9,6) NOT NULL COMMENT 年化利率存小数, term_type char(1) NOT NULL DEFAULT M COMMENT 期限单位D天/M月/Y年, term int NOT NULL COMMENT 期限数值, repay_mode varchar(8) NOT NULL COMMENT 还款方式EPL等额本息/DEBX等额本金/XIBX先息后本, status tinyint NOT NULL DEFAULT 0 COMMENT 0受理 1已放款 2正常 3逾期 4结清 5核销, disburse_date date DEFAULT NULL COMMENT 放款日, due_date date DEFAULT NULL COMMENT 到期日, created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (agree_no), KEY idx_cust_id (cust_id), KEY idx_due_status (due_date, status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT借据表;主键直接用业务号 agree_no在单库阶段没问题但后面讲分库分表时会说这是坑。利率用 decimal(9,6) 而不是 float年利率 5.4% 存成 0.0540006 位小数精度足够覆盖日利率换算的截断误差。term_type 和 term 拆成两个字段比存一个 term_days 灵活产品可以定义「12 个月」也能定义「360 天」。联合索引due_date, status是每日逾期跑批的核心路径查询条件是「今天到期且未结清」把 due_date 放前面区分度更高。2.3 状态流转必须画成状态机不能只留 status 字段字段注释写「0受理 1已放款 2正常 3逾期 4结清 5核销」这是最偷懒的做法。它只告诉后来者有哪些枚举值没告诉谁在什么条件下允许从哪个值变到哪个值。实际生产里最常见的翻车现场就是状态从「正常」直接跳到了「结清」核查时谁都说不出这笔核销是谁操作的。设计说明里必须单独开一节画状态机。借据状态至少要有这样几条路径受理后放款成功进入正常正常且到期未还进入逾期逾期经过减免审批进入核销正常或逾期还清后进入结清。禁止的状态跳转要明确写出来比如「逾期必须经过还款或核销动作才能结束不允许直接改成结清」。状态变更在设计说明里约定走统一接口由应用层校验流转合法性不要让每个业务方直接 update status。3. 额度模型与账务科目把「还能借多少」和「账怎么平」写清楚3.1 可用额度等于总额度减已用减冻结这个公式的并发条件授信额度表是信贷数据库设计和普通交易系统差异最大的地方。电商库存超卖最多赔个订单信贷额度超放是直接的资金损失。先看设计说明里必须写死的余额公式可用额度 授信总额度 - 已用额度 - 冻结额度其中已用额度是当前在贷本金冻结额度是已审批通过、尚未放款的部分。这个公式本身不复杂复杂的是并发下怎么保证不超扣。常见错误是先查余额、应用层判断够不够、再 update两个请求同时通过判断就会超放。正确的写法是把判断条件并进 update 语句UPDATE credit_limit SET used_amount used_amount #{amount}, updated_at NOW() WHERE cust_id #{custId} AND total_amount - used_amount - frozen_amount #{amount};这段 SQL 的关键在 where 条件里的不等式它把「查余额、算余量、扣减」三步压缩成一条原子语句数据库的行锁保证同一时刻只有一个事务能成功扣减。执行后检查影响行数返回 1 表示扣减成功返回 0 表示额度不足业务侧直接提示用户失败。注意这里不要用「先查后更」那是竞态条件的标准教材案例。3.2 额度流水表每一笔额度变动都要留痕额度余额可以被 update 直接改写改写后没有任何痕迹这是信贷数据库设计里不可接受的。余额是汇总值流水才是真相。设计说明里必须规定额度表只允许通过额度流水表归集更新禁止任何程序直接 update used_amount。额度流水表建议包含这些字段流水号、客户号、业务编号借据号、变动类型占用、释放、冻结、解冻、变动金额、变动前可用额度、变动后可用额度、操作时间、操作员。每次放款扣减额度时先插入一条占用流水再更新额度表余额。两个操作放在同一个本地事务里要么都成功要么都失败。我习惯把这个顺序定死先记流水再更余额。原因是流水只增不改是账余额可以随时被流水重算重建丢了也能恢复。反过来余额先改了流水没记上这笔账就永久消失了。这个原则写进设计说明后后续做额度对账会省很多事。3.3 账务设计借贷分录与 decimal 精度约定信贷系统的资金账务靠的是一张科目表和一张分录表。科目表定义「放款本金」「应收利息」「罚息」「已收本金」这些账户分录表记录每笔业务的借贷动作。借贷必相等是账务的底线不是说业务上一定同时影响两个科目而是每笔记账本身必须满足复式记账规则放款时借「发放贷款本金」贷「资金户」还款时借「资金户」贷「已收本金」和「利息收入」科目表由参数配置维护不要在业务代码里写死科目号。按理说账务逻辑可以独立成一个子系统但对于大多数信贷项目初期把账务表和业务表放在同一个库里、同一套事务里一致性最好维护。等到交易量上来再做账务库分离用异步对账兜底。金额字段全库统一 decimal(20,2)禁止 double 和 float。这个约定必须放在设计说明最前面的全局约定里否则不同表各用各的精度月底对账就会遇到「差一分钱」的玄学问题。4. 还款计划、利息与逾期口径落地表怎么建口径怎么写4.1 还款计划落不落表三种做法与选型还款计划表是信贷数据库设计里最容易引发争论的地方。不落表派认为根据借据本金、利率和还款方式每期应还金额可以随时算出来落表反而多一份需要维护的数据。落表派认为催收、对账、销账都需要逐期核对每次现算是灾难。三种常见做法做法优点缺点适用完全不落表实时计算无冗余无重算问题查询成本高无法记录已还期数演示项目、极低并发落表只生成一份计划查询快跑批简单提前还款要原地更新易脏还款方式单一的产品落表按批次生成多份计划支持提前还款重算留痕完整表数据量增长快正规信贷核心系统第三种做法是主流。给还款计划表加一个 plan_group_id 字段正常放款生成第一批计划标记为有效发生提前还款时把旧批次全部置为作废按剩余本金和新期限重新生成一批新计划。这样历史每一版还款计划都留痕对账时能说清楚每一期的本金利息是怎么来的。方案定了信贷数据库设计说明里就能明确写还款计划表只增不改状态靠批次管理。4.2 等额本息逐期试算与尾差修正一段可抄的 SQL等额本息每期应还金额按公式 A P × r ×1r^n /1r^n - 1计算其中 P 是放款本金r 是月利率年利率除以 12n 是总期数。每期利息等于剩余本金乘以月利率每期本金等于每期应还减去每期利息。这个公式的问题在于金额精度有限逐期计算必然产生尾差。如果每期应还四舍五入到分最后一期按公式算出来的本金累计和放款本金对不齐客户还完最后一期账上还会挂一分钱。所以生成计划后必须做一次尾差修正把累计误差调整到最后一期本金上UPDATE repay_plan SET repay_principal repay_principal ( #{principal} - ( SELECT COALESCE(SUM(repay_principal), 0) FROM repay_plan WHERE agree_no #{agreeNo} AND plan_status N ) ) WHERE agree_no #{agreeNo} AND plan_status N AND period_no ( SELECT MAX(period_no) FROM repay_plan WHERE agree_no #{agreeNo} AND plan_status N );这个 update 的含义是先按等额本息公式生成全量计划再以放款本金为锚点算出「计划本金累计」和「放款本金」的差值把差值加在最后一期本金上。plan_status N 限定只修正当前有效批次避免提前还款后新旧计划互相干扰。修正之后sum(应还本金) 必须等于本金这是还款计划表的一条铁律应该在设计说明里写成校验规则每天跑批核对。4.3 逾期金额、逾期天数与账龄口径宽限期和日切逾期口径写不清楚风控和催收会扯皮。信贷数据库设计说明里要固定三个定义逾期天数、逾期金额、账龄段。逾期天数常见口径是自然日逾期天数 max(0, 实际还款日 - 应还日 - 宽限期天数)。个人信贷通常给 3 天宽限期超过宽限才上逾期。注意「应还日」指还款计划表里那天的 24 点日切跑批在凌晨执行跑批时客户当天还款仍算正常跑批之后未还才进入逾期。这个日切时间点要在设计说明里写死否则不同模块对「今天是否逾期」的判断会不一致。逾期金额建议统一为「该期应还未还的本金 利息 罚息合计」而不是只算本金。账龄段按逾期天数切M1 是 1 至 30 天M2 是 31 至 60 天M3 是 61 至 90 天。逾期天数每天由跑批任务更新进逾期表而不是在查询时实时算这样催收系统、征信报送系统拿到的是同一份数据。5. 信贷数据库设计落地中的五个高频翻车点与排查方法这一章是血泪经验。以下五类问题在信贷数据库设计评审和生产运维里反复出现每一条都按「现象 → 原因 → 解决」写清楚拿去做排查清单正好。5.1 金额精度不统一对账永远差几分现象月底对账时还款计划表的累计本金和账务分录入账的本金差几分钱。开发排查半天发现有的表用 decimal(18,2)有的表用 decimal(20,4)还有老接口查出来是 double 转换过来的。原因设计说明没在全局约定里统一金额精度。不同人建表时各自选了精度decimal 乘法后小数位被截断或四舍五入误差累积。解决全库金额字段统一 decimal(20,2)利率单独用 decimal(9,6)。所有计算在中途用高精度decimal(20,6)运算最终入账时才四舍五入到分。这条规则写进数据库设计说明的前三页并在代码评审里卡死。5.2 状态乱跳没有状态机约束的数据像脱缰野马现象审计查一笔借据状态从「正常」直接跳到「核销」中间没有任何还款、减免或审批记录。问起来谁都不知道是哪个接口更新的。原因表里只有 status 字段注释没画状态机。各业务模块为了省事直接 update 状态跳过业务校验。解决数据库设计说明单独一章画状态流转图明确每个状态变更的触发动作、前置条件和目标状态。应用层统一封装状态变更方法只允许通过这个方法改状态从入口堵住乱跳。5.3 并发扣减额度先查后更导致超授信放款现象压测时同一个客户同时发起两笔借款两笔都放款成功合计金额超过授信总额。原因额度扣减逻辑是「select 出余额 → 应用层判断 → update」两个请求同时读到相同余额都判断额度够都执行了 update。解决按 3.1 的条件更新写法把判断写进 update 的 where 条件里返回影响行数判断是否成功。这条要在设计说明的时序图里体现出来不能只在代码层面修。5.4 提前还款后还款计划残留脏数据现象客户提前结清借据状态已变为结清但还款计划表里还有「已还本金大于应还本金」的负数剩余记录。征信报送数据在这些期数上怎么都对不上。原因提前还款时对原计划表做了原地更新——把未来期数本金改成 0而不是将整批计划作废。多次提前还款后同一期计划被改了多次历史信息丢失对账无据可依。解决采用 4.1 的批次方案。原计划批次整体置为作废plan_status 改为 O新生成一批计划接续 plan_group_id。查询报表默认只看有效批次历史批次留给审计追溯。5.5 业务号当物理主键分库分表时现挖坑现象业务量增长后按 cust_id 分库但 loan_agreement 的主键是 agree_no。跨库查询、全局唯一编号生成、数据迁移都变得异常困难经常出现不同分片生成重复业务号。原因设计之初把业务号既当业务标识又当物理主键。单库时没问题分库后业务号的生成规则被打散不能再依赖数据库自增保证全局唯一。解决在数据库设计说明里区分物理主键和业务号。物理主键用自增 id 或雪花 id业务号借据号单独作为唯一索引存在由发号器统一生成。这个调整要在设计早期做后期换主键的成本极高。6. 设计文档到生产跑批的最后一公里评审重点与对账验证6.1 评审时先问三个「谁」谁创建、谁修改、谁删除评审信贷数据库设计说明时与其逐字段检查类型长度不如先问三个问题这张表的每一行由谁创建创建后哪些字段允许被修改什么条件下允许删除。客户表基本信息只能由客户中心写入额度流水只能追加不允许修改借据表的 status 只能通过状态机接口变更还款计划一旦生成不允许原地改金额。这三个问题问完表设计的缺陷基本都能暴露出来。我习惯在评审前做一张字段权限表把核心表的每个字段按「创建 / 修改 / 删除」填上归属模块填不出来的字段就是设计没说清楚的地方必须回头补文档。6.2 一条对账 SQL 让还款计划与实收明细当场对平设计说明写得再好落地后还是要靠数据校验兜底。还款计划表和还款交易流水表对账是每月必做的动作把计划应还本金与实际入账本金按期数做比对SELECT p.period_no, SUM(p.repay_principal) AS plan_principal, COALESCE(SUM(t.actual_principal), 0) AS actual_principal FROM repay_plan p LEFT JOIN repay_trans t ON p.agree_no t.agree_no AND p.period_no t.period_no WHERE p.plan_status N GROUP BY p.period_no HAVING SUM(p.repay_principal) COALESCE(SUM(t.actual_principal), 0);这段 SQL 的用法是找出「计划应还本金」和「实际入账本金」不一致的期数。left join 保留所有计划期数coalesce 把未入账的空值转成 0group by period_no 按期数聚合having 过滤出差异行。跑出来有结果说明该期存在部分还款、减免或入账错误需要人工核对跑出来为空说明当期账面是平的。做信贷数据库设计这些年我最深的体会是文档里多写一句口径生产上就少熬一个通宵。还款计划生成、额度扣减、逾期判断这些逻辑看起来是代码问题根子全在设计说明有没有把规则定死。每次评审我会把「谁在什么时候写入、谁在什么时候修改」写在每张表的注释里这比任何字段字典都管用。希望帮到你。本文还有配套的精品资源点击获取