数据库设计:计算帐户余额

001*_*001 64 database sql-server database-design sql-server-2008

如何设计数据库以计算帐户余额?

1)目前我从交易表中计算账户余额在我的交易表中我有"描述"和"金额"等.

然后我会将所有"金额"值相加,这将计算出用户的帐户余额.


我向我的朋友展示了这个,他说这不是一个好的解决方案,当我的数据库增长它会减慢???? 他说我应该创建单独的表来存储计算的帐户余额.如果这样做,我将不得不维护两个表,而且风险很大,帐户余额表可能会不同步.

有什么建议吗?

编辑:选项2:我应该在我的交易表"余额"中添加一个额外的列.现在我不需要经过多行数据来执行我的计算.

示例约翰购买100美元信贷,他债务60美元,然后他增加200美元信贷.

金额$ 100,余额$ 100.

金额 - 60美元,余额40美元.

金额$ 200,余额$ 240.

smi*_*man 60

一个从未得到优雅解决的古老问题.

我使用的所有银行业务包都存储了账户实体的余额.从运动历史中动态计算它是不可想象的.

正确的方法是:

  • 移动表对每个帐户都有一个"期初余额"交易.当您需要将旧动作从活动移动表移动到历史记录表时,您需要在几年内完成此操作.
  • 帐户实体具有余额字段
  • 移动表上有一个触发器,用于更新贷记和借记帐户的帐户余额.显然,它有承诺控制.如果你不能有一个触发器,那么需要一个独特的模块,它在承诺控制下写入动作
  • 您有一个可以离线运行的"安全网"程序,它可以重新计算所有余额并显示(并可选择更正)错误的余额.这对测试非常有用.

有些系统将所有运动存储为正数,并通过反转from/to字段或带有标志来表示信用/借记.就个人而言,我更喜欢信用额度,借方字段和签名金额,这使得逆转更容易遵循.

请注意,这些方法适用于现金和证券.

证券交易可能要复杂得多,特别是对于公司行为,您需要提供一笔交易,以更新一个或多个买方和卖方的现金余额,其安全头寸余额以及可能的经纪人/存款.

  • @ 001每笔交易包含3个字段.1 /要借记的帐户的ID.2 /要记入的帐户的ID.3 /金额,正数=从债权人转移到债务人,负数=从债权人转移到债权人(通常是逆转).我建议你阅读http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system (8认同)
  • 这个答案不正确,依赖于代码,而且很麻烦.对于(a)**符合审计要求**和立法机关的方法,(b)**不要求触发; 离线安全网; 重复列; 重复数据,(c)无论表格数量多少都表现良好,请看**[本答案](http://stackoverflow.com/a/29713230/484814/)**. (6认同)
  • "就我个人而言,我更喜欢信用额度,借记字段和签名金额,这使得逆转更容易遵循.",为什么不只有1个字段"金额"与标志? (4认同)

Her*_*him 5

这是我得到的数据库设计,只有一个表用于存储操作/事务的历史记录。目前正在许多小型项目中发挥魅力。

这不会取代特定的设计。这是一个通用的解决方案,可以适合大多数应用程序。

id :int 标准行 ID

operation_type:int 操作类型。支付、收取、利息等

source_type :int 操作从哪里进行。目标表或类别:用户、银行、提供商等

source_id : 数据库中源的int id

target_type:int 表示应用的操作。目标表或类别:用户、银行、提供商等

target_id:数据库中目标的int id

amount :decimal(19,2signed) 价格值正数或负数求和

account_balance:十进制(19,2 签名)结果余额

extra_value_a :decimal(19,2signed) [这是不使用字符串存储的最通用的选项] 您可以存储额外的数字:利息百分比、折扣、减少等。

创建时间:时间戳

对于 source_type 和 target_type ,最好使用枚举或表设备。

如果你想要一个特定的余额,你可以只查询按created_at降序限制到1排序的最后一个操作。你可以按源、目标、操作类型等查询。

为了获得更好的性能,建议将当前余额存储在所需的目标对象中。