数据库文档编写,开发规范文档,数据库接入
This commit is contained in:
116
docs/sql/08_data_consistency_boundaries.md
Normal file
116
docs/sql/08_data_consistency_boundaries.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# 08 数据一致性边界:数据库保证什么?应用层还需要保证什么?
|
||||
|
||||
本节的目的:把“责任边界”讲清楚,避免团队误以为数据库已经覆盖了所有一致性问题。
|
||||
|
||||
---
|
||||
|
||||
## 1. 数据库层已经显式保证的内容(来自脚本)
|
||||
|
||||
### 1.1 约束(Constraints)保证
|
||||
|
||||
- **枚举合法性**:大量使用 `CHECK (status IN (...))`
|
||||
- 例:`ml_products.status`、`ml_orders.order_status/payment_status/shipping_status`
|
||||
- **唯一性**:
|
||||
- `order_no UNIQUE`
|
||||
- `coupon_code UNIQUE`
|
||||
- `ml_shopping_cart UNIQUE(user_id, product_id, sku_id)`
|
||||
- `ml_shops.merchant_id UNIQUE`(一商家一店)
|
||||
- `ml_delivery_tasks.order_id UNIQUE`(一订单一配送任务)
|
||||
|
||||
### 1.2 触发器保证
|
||||
|
||||
- **`updated_at` 自动维护**:避免应用层漏写
|
||||
- **默认地址唯一**:`ensure_single_default_address()`
|
||||
- **SKU → SPU 库存汇总**:`update_product_stock()`
|
||||
- **订单状态副作用(complete 脚本)**:`handle_order_status_change()` 自动写时间戳,并累计销量
|
||||
|
||||
### 1.3 RLS(行级安全)保证
|
||||
|
||||
- 用户私有数据仅可访问自己的行(档案/地址/购物车/收藏/浏览/券等)
|
||||
- 订单允许买家/卖家访问
|
||||
- 商品公开查询仅限上架
|
||||
|
||||
---
|
||||
|
||||
## 2. 数据库层“目前未完全覆盖”的一致性问题(需要显式补齐)
|
||||
|
||||
> 以下并不意味着当前设计不好,而是典型电商系统里必须明确“谁来保证”。
|
||||
|
||||
### 2.1 下单扣库存、防超卖
|
||||
|
||||
脚本可见“库存汇总”,但没有看到:
|
||||
|
||||
- 下单时对 `ml_product_skus.stock` 的原子扣减
|
||||
- 订单取消/超时未支付的库存回补
|
||||
- 库存冻结(预占)机制
|
||||
|
||||
**风险**:并发下单可能超卖。
|
||||
|
||||
**建议补齐方案**(按复杂度递增):
|
||||
|
||||
- **方案 A(最小补齐)**:提供一个原子扣减函数
|
||||
- `update ml_product_skus set stock = stock - :qty where id=:sku_id and stock >= :qty;`
|
||||
- 受影响行数为 1 表示扣减成功,否则失败
|
||||
- **方案 B(常见电商)**:引入“冻结库存”
|
||||
- SKU 增加 `reserved_stock` 或独立冻结表
|
||||
- 下单冻结、支付确认扣减、取消释放
|
||||
- **方案 C(审计与对账)**:引入库存流水
|
||||
- 每次扣减/回补记录流水,便于审计
|
||||
|
||||
### 2.2 支付对账与幂等
|
||||
|
||||
脚本中订单有 `payment_status/paid_amount`,但未见:
|
||||
|
||||
- 支付流水表(第三方支付回调存证)
|
||||
- 支付回调幂等键
|
||||
- 退款流水/退款幂等
|
||||
|
||||
**建议**:补交易流水表(或在应用层引入专门支付子系统)并明确幂等策略。
|
||||
|
||||
### 2.3 优惠券核销一致性
|
||||
|
||||
当前有 `ml_user_coupons.status/used_at/order_id`,但未见:
|
||||
|
||||
- “同一张券只能用一次”的强事务保证(除非应用层做 CAS 更新)
|
||||
- 与订单金额计算的强一致校验
|
||||
|
||||
建议:
|
||||
|
||||
- 用条件更新核销:`where status=1` 确保并发只成功一次
|
||||
- 关键核销与订单创建在同一事务内
|
||||
|
||||
### 2.4 统计字段回滚
|
||||
|
||||
脚本在订单完成时累计 `sale_count`,但未看到:
|
||||
|
||||
- 退款/取消是否回滚 `sale_count`
|
||||
|
||||
建议:
|
||||
|
||||
- 明确统计字段口径:
|
||||
- `sale_count` 是“累计成交量”还是“累计下单量”
|
||||
- 若需可回滚:要补对应触发器/作业,或使用流水聚合。
|
||||
|
||||
---
|
||||
|
||||
## 3. 建议的边界划分(团队共识)
|
||||
|
||||
- **数据库层**:
|
||||
- 基础合法性(约束/唯一性)
|
||||
- 关键自动维护字段(updated_at、默认地址唯一、库存汇总、SEO 等)
|
||||
- 访问控制(RLS)
|
||||
- **应用层**:
|
||||
- 复杂事务(下单扣库存、支付幂等、退款)
|
||||
- 业务规则组合(优惠叠加、分摊、拆单、风控)
|
||||
- 跨域协调(订阅与订单的统一计费/对账)
|
||||
|
||||
---
|
||||
|
||||
## 4. 推荐补充的“最小一致性清单”(可用于评审)
|
||||
|
||||
- 下单扣减库存是否原子?
|
||||
- 未支付关闭订单是否回补库存?
|
||||
- 支付回调是否幂等?
|
||||
- 退款回调是否幂等?
|
||||
- 优惠券核销是否并发安全?
|
||||
- 统计字段口径是否明确、是否需要回滚?
|
||||
Reference in New Issue
Block a user