Crater数据库表设计最佳实践:财务系统表结构案例
财务系统表结构概览
Crater作为开源发票解决方案,其数据库设计遵循财务数据完整性和业务流程关联性原则。核心表结构围绕客户-发票-支付三大主体构建,通过外键关系实现数据一致性。以下将从实体关系、字段设计、索引策略三个维度解析最佳实践。
核心实体关系图
客户管理表设计
客户表(customers)采用最小权限原则设计,基础字段满足业务需求的同时保护隐私数据。关键设计点包括:
字段设计亮点
- 分级字段策略:必选字段(name)与可选字段(phone/website)分离,
nullable()减少数据冗余 - 身份验证隔离:密码字段设为
nullable(),支持无需登录的客户管理模式 - 多维度关联:通过
company_id和creator_id实现数据隔离与权限控制
// [database/migrations/2021_06_28_111647_create_customers_table.php](https://link.gitcode.com/i/5344df887bef9d5aea5514367854f8bf)
$table->string('name'); // 客户名称(必选)
$table->string('email')->unique()->nullable(); // 邮箱(唯一索引+可选)
$table->string('password')->nullable(); // 密码(可选,支持免登录客户)
$table->integer('company_id')->unsigned()->nullable(); // 所属公司
$table->unsignedInteger('creator_id')->nullable(); // 创建者
索引优化
- 邮箱字段添加唯一索引确保客户身份唯一性
- 外键字段(company_id/creator_id)自动创建索引提升关联查询效率
发票系统表结构
发票模块采用主从表设计模式,invoices表存储 header 信息,invoice_items 表存储明细数据,通过invoice_id建立一对多关系。
发票主表(invoices)设计
// [database/migrations/2017_04_12_090759_create_invoices_table.php](https://link.gitcode.com/i/390ef642b8d878babf539f242faa30fa)
$table->date('invoice_date'); // 发票日期
$table->date('due_date'); // 到期日期
$table->string('invoice_number'); // 发票编号
$table->string('status'); // 状态(草稿/已发送/已支付等)
$table->unsignedBigInteger('sub_total'); // 小计金额
$table->unsignedBigInteger('total'); // 总计金额
$table->unsignedBigInteger('due_amount');// 未付金额
$table->boolean('sent')->default(false); // 发送状态
$table->boolean('viewed')->default(false); // 查看状态
$table->string('unique_hash')->nullable(); // 唯一访问标识
发票明细表(invoice_items)设计
明细项采用原子化设计,将折扣、税费等计算字段单独存储,避免重复计算:
// [database/migrations/2017_04_12_091015_create_invoice_items_table.php](https://link.gitcode.com/i/b14f3407cd9e6acf62277457eb8148ab)
$table->string('name'); // 项目名称
$table->unsignedBigInteger('price'); // 单价
$table->decimal('quantity', 15, 2); // 数量
$table->decimal('discount', 15, 2)->nullable(); // 折扣金额
$table->unsignedBigInteger('tax'); // 税额
$table->unsignedBigInteger('total'); // 小计金额
$table->integer('invoice_id')->unsigned(); // 关联发票ID
$table->integer('item_id')->unsigned()->nullable(); // 关联商品ID
支付流程表设计
支付模块通过状态追踪和审计字段确保财务数据可追溯,关键表结构如下:
支付表(payments)设计
// [database/migrations/2019_09_03_135234_create_payments_table.php](https://link.gitcode.com/i/459ffc8d5a3c24b8c4d114679b1d082f)
$table->string('payment_number'); // 支付编号
$table->date('payment_date'); // 支付日期
$table->unsignedBigInteger('amount'); // 支付金额
$table->integer('invoice_id')->unsigned()->nullable(); // 关联发票
$table->integer('payment_method_id')->unsigned()->nullable(); // 支付方式
支付状态流转
支付状态通过invoices表的paid_status字段与payments表的创建联动更新,实现数据一致性:
- 初始状态:
paid_status = 'unpaid',due_amount = total - 部分支付:更新
due_amount = due_amount - payment.amount - 全额支付:设置
paid_status = 'paid',due_amount = 0
周期性发票设计
针对订阅制业务场景,Crater设计了递归发票表(recurring_invoices),通过时间规则自动生成发票:
核心周期控制字段
// [database/migrations/2021_07_09_063502_create_recurring_invoices_table.php](https://link.gitcode.com/i/5caaa2edd08c002ea6b60b518e170bbf)
$table->dateTime('starts_at'); // 开始时间
$table->dateTime('next_invoice_at')->nullable(); // 下次生成时间
$table->string('frequency'); // 周期类型(daily/weekly/monthly等)
$table->enum('limit_by', ['NONE', 'COUNT', 'DATE'])->default('NONE'); // 终止条件
$table->integer('limit_count')->nullable(); // 生成次数限制
$table->date('limit_date')->nullable(); // 终止日期
周期发票生成流程
数据库设计最佳实践总结
1. 财务数据安全设计
- 金额字段使用
unsignedBigInteger避免负数 - 关键操作记录
creator_id实现操作审计 - 使用
unique_hash实现无登录访问验证
2. 性能优化策略
- 外键字段添加索引提升关联查询效率
- 状态字段使用
enum类型限制取值范围 - 大文本字段(notes)设为
nullable减少存储占用
3. 扩展性设计
- 采用多态关联支持多种税费计算方式
- 预留
custom_fields表支持自定义字段扩展 - 公司隔离设计支持多租户模式
完整数据库迁移文件可查看database/migrations/目录,包含从基础表到业务表的完整演进历史。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



