因此,它就像我们的正常银行账户一样,我们有很多交易,导致资金流入或流出.账户余额总是可以通过简单地将交易价值相加得出.在这种情况下,将更新后的账户余额存储在数据库中,或者在需要时重新计算,哪种方法更好?

每个账户的预期交易量:<每天5次

帐户余额的预期取回:每当交易发生时,否则平均每天取回一次.

你建议如何对此做出决定?

推荐答案

前言

有一个客观道理:审计要求.此外,在处理公帑时,立法机关是必须遵守的.

您不必实现全部会计要求,您可以只实现您需要的部分.

相反,实施other than%的标准会计要求(其部分)是不明智的,因为这保证了当错误数量或负载超过某个阈值,或系统扩展时,您将不得不重新实施.这是可以避免的,因此也是应该避免的.

还需要说明的是:不要雇佣没有资质、未经认可的"审计师".这会有后果的,就像你雇了一个不合格的开发人员一样.如果税务局对你罚款,情况可能会更糟.

Method

非原始国家的标准会计方法是这样的.如果你愿意的话,这是其他人的"最佳实践".

此方法适用于任何具有类似操作的系统;需要;历史月度数据与当前月度需求,如库存控制等.

注意事项

首先,考虑因素.

  1. 切勿复制数据.
    如果可以导出当前余额(这里很简单),请不要将其与汇总列一起复制.这样的列是数据的重复.它违反了正常化规则.此外,它creates是更新异常,否则该更新异常是不存在的.

  2. 如果您确实使用汇总列,则每当更新事务时(如在更改中,而不是在插入新事务时),汇总列value变得过时,因此无论如何它都必须一直更新.这就是更新异常的后果.这就消除了拥有它的价值.

  3. 外部出版物.
    分开的点.如果余额被公布,就像在每月的银行对账单中一样,这样的文件通常有法律限制和影响,因此公布的当前余额值在公布后不能改变.

    • 在发布日期之后,在数据库中,外部发布的数据的任何变化都是不诚实行为、欺诈等的证据.

      • 这种试图改变已出版历史的行为是新手的标志.新手和精神病人会坚持认为历史是可以改变的.但众所周知,对法律的无知并不构成有效的辩护.
    • 你不会希望你的银行在2015年4月改变他们在2014年12月给你的银行对账单中公布的当前余额.

    • 该数字必须被视为已公布且不可更改的审计数字.

  4. 为了纠正过go 犯下的错误,也就是现在正在纠正的错误,所需的修正或调整将作为当月的新交易进行(即使它适用于上个月或某个持续时间).

    这是因为适用于该月份是关闭的、已审核的和已发布的,因为在发生并记录之后不能更改历史.唯一的effective个月是当期的.

    • 对于计息系统等,在不那么原始的国家,当发现错误时,它具有历史性的影响(例如,您在2015年4月发现证券上计算的利息不正确(自2014年12月以来),今天计算更正后的利息支付/扣减的值,用于错误的天数,并将总和作为交易插入当月.同样,唯一有效的月份是当前月份.

      当然,证券的利率也必须修正,这样错误就不会重演.

    • 如果你发现你的银行对你的储蓄(有息)账户利息的计算有误,并加以纠正,你就会得到当月的一笔存款,即构成整个调整值的一笔存款.那是当月的一笔交易.

      银行没有:改变历史; for each 历史月份申请利息;回顾历史上的银行对账单;重新发布历史银行对账单.不,除了可能在第三世界国家.

    • 同样的原则也适用于库存控制系统.它保持理智.

  5. 所有真实的会计系统(即那些在适用国家获得审计机构认可的公司,而不是比比皆是的米老鼠"套餐",使用复式记账系统进行交易,正是因为它防止了大量错误,其中最重要的是,资金不会"丢失".这需要总账和复式记帐.

    • 你没有要求那样,你也不需要那样,所以我不在这里描述它.但请记住,以防资金"失踪",因为这是你必须实施的,而不是什么创可贴解决方案,也不是另一个未经认证的"一揽子计划".

    This Answer services the Question that is asked, which is not Double-Entry Accounting.
    For a full treatment of that subject (detailed data model; examples of accounting Transactions; rows affected; and SQL code examples), refer to this Q&A:
    Relational Data Model for Double-Entry Accounting.

  6. 影响性能的主要问题超出了这个问题的范围,它们是关于您是否实现了真正的关系数据库(例如.为方便起见,60年代的以Record IDs为特征的记录归档系统被部署在SQL数据库容器中).

    • 使用真正的关系键等将保持高性能,而与表的数量无关.

    • 相反,RFS的性能会很差,它们根本无法执行."规模"在RFS的上下文中使用时,是一个欺骗性的术语:它隐藏了原因,并试图解决除原因之外的所有问题.最重要的是,这样的系统没有关系系统的关系完整性、关系能力或相对速度.

实施

关系数据模型•账户余额

Acct

关系数据模型·库存

Inv

记数法

  • 我所有的数据模型都在100中呈现,这是自1993年以来建立关系数据库模型的标准.

  • 对于那些刚接触Relational Model或其建模方法的人来说,"我的100"是必不可少的读物.请注意,IDEF1X模型具有丰富的细节和精确度,显示了所有需要的细节,而国产模型的细节要少得多.这意味着,这个符号必须被理解.

内容

  1. 对于每个帐户,AccountStatement表中将有一个ClosingBalance(每月每AccountNo一行),以及对帐单日期(通常是每月的第一天)和其他对帐单详细信息.

    • 这不是一个副本,因为它是审计和健全的目的要求.

      对于库存,它是PartAudit表中的QtyOnHand列(每月每PartCode一行)

    • 它还有一个附加值,因为它限制了当月需要查询to的事务行的范围

      • 同样,如果您的表是关系表,那么AccountTransaction的主键将是(AccountNo,事务DateTime),它将以毫秒的速度检索事务.

      • 而对于记录归档系统,"主键"将是TransactionID,您将按交易日期检索当前月份,这可能是正确的索引,也可能不是正确的索引,所需的行将分布在整个文件中.在任何情况下,在远低于ClusteredIndex的速度下,由于传播,它将导致表扫描.

  2. AccountTransaction表仍然很简单(现实世界中银行账户交易的概念很简单).它有一个正Amount列.

  3. 对于每Account个,CurrentBalance是:

    • 上个月的AccountStatement.ClosingBalance号,为方便起见,日期定在下个月的第一天

      (库存为PartAudit.QtyOnHand)

    • 加上当月AccountTransaction.Amounts的总和,其中TransactionType表示存款

      (对于库存,为PartMovement.Quantity)

    • 减go 当月的AccountTransaction.Amounts之和,其中`MovementType表示取款.

  4. 在这种方法中,只有当月的AccountTransactions人处于不断变化的状态,因此他们是must be derived人.之前的所有月份均已公布并结束,因此审计图为must be used.

  5. 可以清除AccountTransaction表中较旧的行.公款十年以上,否则五年,业余俱乐部系统一年.

  6. 当然,任何与会计系统相关的代码都必须使用真正的OLTP标准和真正的SQL ACID事务.

  7. 此设计包含所有范围级性能考虑因素(如果这一点不明显,请要求扩展).在数据库内伸缩是不成问题的,任何剩余的伸缩问题实际上都在数据库之外.


Corrective Advice

之所以需要说明这些问题,只是因为在如此多的答案中提供了错误的建议(当然,这些建议是由大众民主投票决定的),而且互联网上充斥着错误的建议(业余爱好者喜欢公布他们的主观"真相"):

  1. 很明显,有些人不明白我在技术上给出了一种方法,对一个清晰的数据模型进行操作.因此,它不是针对特定国家/地区的特定应用程序的伪代码.这个方法是针对有能力的开发人员的,对于那些需要手把手带领的人来说还不够详细.

    • 他们也不明白一个月的截止期限是example:如果你的税务局的截止日期是季度,那么一定要使用季度截止日期;如果你唯一的法律要求是年度,那么使用年度.

    • 即使出于外部或合规目的,您的截止日期是季度截止日期,公司也很可能 Select 每月截止日期,以便进行内部审计和保持理智(例如,以将通量状态的周期长度保持在最小).

      在澳大利亚,税务局对企业的截止日期是每季度一次,但较大的公司每月都会切断库存控制(这样可以避免长时间追查错误).

      银行每月都有法律合规要求,因此他们每月对数字进行内部审计,并结帐.

    • 在原始国家和流氓国家,银行为了明显的邪恶目的,将其流动状态保持在最大值.其中一些公司仅每年提交合规报告.这就是澳大利亚银行不会倒闭的原因之一.

  2. AccountTransaction表格中,不要在金额列中使用负数/正数.钱总是有正值的,没有负20美元(或那you owe me minus fifty dollars美元)这回事,然后算出双重否定有别的意思.

  3. 移动方向,或者说你打算如何处理资金,是一个独立和离散的事实(对AccountTransaction.Amount人来说).这需要单独的列(一个数据中的两个事实违反了规范化规则,结果是它给代码带来了复杂性).

    • 实现TransactionType参照表,其主键为(D, W),以存取款为起点.随着系统的发展,只需为调整贷方、调整借方、银行手续费、自动柜员机_提款等添加(A, a, F, w)即可.

    • 无需更改代码.

  4. 在一些原始国家,诉讼要求规定,在任何列出交易的报告中,每一行都必须显示运行总数.(注意,这不是审计要求,因为这些要求优于法院要求[(参考上面的方法);审计师比律师稍微没那么笨;等等)

    显然,我不会对法院的要求提出异议.问题是,原始编码员会将其转换为:oh, oh, we must implement aAccountTransaction.CurrentBalancecolumn.他们不明白这一点:

    • 要求在报表上打印一列并不是要求在数据库中存储值

    • 任何类型的运行总和都是派生值,并且很容易编码(如果对您来说不容易,请提出一个问题).只需在报告中实现所需的代码即可.

    • 将运行总数(如AccountTransaction.CurrentBalance)作为一个列来执行会导致可怕的问题:

      • 引入重复列,因为它是可派生的.打破常态.引入更新异常.

      • 更新异常:每当历史上插入事务或更改AccountTransaction.Amount时,所有AccountTransaction.CurrentBalances from that date to the present都必须重新计算和更新.

    • 在上述 case 中,提交给法院使用的报告现在已经过时(每一份在线数据报告在打印出来的那一刻就已经过时).也就是说.打印;查看;更改交易;重新打印;重新查看,直到您满意为止.这在任何情况下都是没有意义的.

    • 这就是为什么在不那么原始的国家,法院不接受任何旧的印刷纸张,他们只接受公布的数字,例如.银行对帐单,已经符合审计要求(请参考上述方法),不能召回、更改和重新打印.


Comments

亚历克斯:
是的,代码会很好看,谢谢.即使是一个示例"水桶工厂",这样人们可以一次永远地看到启动模式,也会让世界变得更美好.

对于上面的数据模型.

代码•报告当前余额

SELECT  AccountNo,
        ClosingDate = DATEADD( DD, -1 Date ), -- show last day of previous
        ClosingBalance,
        CurrentBalance = ClosingBalance + (
            SELECT SUM( Amount )
                FROM AccountTransaction
                WHERE AccountNo = @AccountNo
                    AND TransactionTypeCode IN ( "A", "D" )
                    AND DateTime >= CONVERT( CHAR(6), GETDATE(), 2 ) + "01"
                ) - (
            SELECT SUM( Amount )
                FROM AccountTransaction
                WHERE AccountNo = @AccountNo
                    AND TransactionTypeCode NOT IN ( "A", "D" )
                    AND DateTime >= CONVERT( CHAR(6), GETDATE(), 2 ) + "01"
                )
    FROM AccountStatement
    WHERE AccountNo = @AccountNo
        AND Date = CONVERT( CHAR(6), GETDATE(), 2 ) + "01"

通过非规范化事务日志(log),当我添加更多TX类型时,我用范式换取了更方便的查询和更少的视图/materialized 视图更改

god 保佑我.

  1. 当你违反标准时,你把自己放在第三世界的位置上,在那里,那些不应该打破的东西,那些在第一世界国家永远不会打破的东西,就会破裂.

    从权威那里寻求正确的答案,然后反对它,或者为你的不合标准的方法辩护,可能不是一个好主意.

  2. 反规范化(此处)会导致更新异常,即重复列,该列可以从TransactionTypeCode派生.你希望编码简单,但你愿意在两个地方编码,而不是一个地方.这正是容易出错的代码类型.

    根据E F Codd博士的Relational Model完全标准化的数据库提供了最简单、最逻辑、最直接的代码.(在我的工作中,我签约保证每一份报告都可以由一个SELECT人提供服务.)

  3. ENUM不是SQL.(免费的非SQL套件没有SQL遵从性,但它们确实有SQL中不需要的额外功能.)如果你的应用程序毕业于一个商业SQL平台,你将不得不将所有这些ENUMs作为普通的查找表重新编写.主键是CHAR(1)INT.然后你就会明白,这实际上是一张有PK的桌子.

  4. 错误的值为零(也会产生负面后果).真理的价值是1.我不会用1换0.因此,这不是一种权衡.这只是你的发展决定.

Database相关问答推荐

如何将表字段的默认值设置为 0.00?

实体关系图. IS A 关系如何转换为table表?

将数据库/后端添加到 android 应用程序

时间数据库设计,有一个转折(live vs draft rows)

我应该为 Realm 中的每个实体定义主键吗?

什么技术对处理数百万条记录最有效?

如何在 VS 2012 的 SQL Server 数据库项目中存储静态数据

PHP - 数据库抽象层使用静态类与单例对象?

设置默认数据库连接 Rails

如何处理 SQL Server 中列名中的空格?

更改列名 Rails

为什么 HikariCP 推荐固定大小的池以获得更好的性能

数据库中一致且全面的地址存储的最佳实践

为什么在连接表上有一个主键不好?

MySQL相对于其他数据库的缺点

App=EntityFramework 在 Sql 连接字符串中有什么作用?

如何通过数据库链接执行 Oracle 存储过程

查询以查找列的 nᵗʰ 最大值

我将如何为读写操作实现单独的数据库?

是否有用于 postgresql 的数据可视化工具,它也能够显示模式间关系?