复式记账的关系数据模型

Ale*_*lex 20 sql database accounting database-design relational-database

假设有一家银行、一家大型商店等,希望正确地为内部帐户和跟踪客户帐户进行会计处理。而不是实现满足当前简单而狭隘的要​​求,这将是“家酿”:结果证明这些只是当前简单要求的临时拐杖,并且在出现新要求时很难或不可能扩展。

据我了解,复式记账法是一种行之有效的方法,可满足所有会计和审计要求,包括目前未考虑的要求。如果实施,它将:

  • 消除随着时间的推移会发生的增量增强和费用,
  • 将来不需要加强。

我研究了另一个问题的答案:简单银行账户的衍生账户余额与存储账户余额?,它为内部帐户提供了很好的信息。需要一个数据模型,以便理解实体;他们的互动;他们的关系,@PerformanceDBA 已经给出了这一点。该模型取自该答案:

虽然这对于简单的内部账户来说是令人满意的,但我需要看到一个提供完整复式记账方法的数据模型。

需要添加的文章是Journal; 内部 vs 外部Transactions;等等..

理想情况下,我想看看这些双条目行在数据库方面的样子,整个过程在 SQL 中的样子,在每种情况下哪些实体受到影响等等。案例如下:

  1. 客户将现金存入他的账户
  2. 银行每月向所有客户账户收取一次费用(样本批量作业),
  3. 客户在柜台进行一些操作,银行收取费用(提现+提现费用),
  4. 玛丽从她的账户中汇出一些钱到约翰在同一家银行的账户

让我们称之为System而不是BankBank可能太复杂而无法建模,让问题是关于使用帐户和资产操作的假想系统。客户与系统(存款、取款、后期费用、批量费用)以及彼此之间(转账)执行一组操作。

Per*_*DBA 71

A. 初步

你的方法

首先,我必须赞扬你的态度。很少有人不仅在扎实的基础上思考和工作,而且希望了解和实施复式记账系统,而不是:

  • 要么实施 DEA,从而遭受多次重写,并且在每次增量、每个新需求时都感到痛苦,

  • 或者实施 DEA,但从头开始重新发明轮子,通过自己解决问题,并在每次暴露错误和要求的错误修复时承受痛苦,这是一个永无止境的序列。

避免这一切,并寻求标准方法,是高度赞扬的。

此外,(f)您希望以关系数据模型的形式出现,您不受日期的奴役;达文; 费金; 等人的观点规定了Record ID基于记录归档系统,该系统削弱了建模练习和由此产生的“数据库”。这些天,有些人沉迷于原始 RFS 并压制了 EF Codd 博士的关系模型

1. 答案的方法

如果您不介意,我会按照逻辑顺序从头开始解释,这样我就可以避免重复,而不仅仅是回答您的特定要求。如果您完全了解这些要点,我深表歉意。

障碍

理想情况下,我想看看那些双条目行在数据库方面的样子

这是建模或定义任何东西所需的正确方法的障碍。

  • ID在每个文件上标记一个字段并使其成为“键”一样,会削弱建模练习,因为它会阻止对数据的分析(数据实际上代表的是什么),期望 Credit 有两行/Debit pair 在开始时会削弱对事物是什么的理解;会计行为是什么;这些行动有什么影响;最重要的是,数据将如何建模。尤其是在学习的时候。

亚里士多德教导我们:

最初对真理的最小偏离后来会成倍增加…… 一个原则是伟大的,与其说是力量,不如说是范围;因此,开始时很小的[错误]在最后变成了一个巨大的[错误]。

解释为,开始时的小错误(例如原则;定义)结果是最后的大错误。

因此,智力上的要求,第一件事,就是在建模练习结束时清除你的头脑。当然,当人们在会计方面了解它是什么时,这也是必需的。

2. 回答范围

假设有一家银行、一家大型商店等,希望正确地为内部帐户和跟踪客户帐户进行会计处理。
让我们称之为System而不是BankBank可能太复杂而无法建模...
客户与系统(存款,取款,后者费用,批量费用)以及彼此(转账)执行一组操作。

需要明确的是,我确定的范围如下。如果不是,请纠正我:

  • 不是只有总帐的小型企业,没有客户帐户
  • 但是,一个小社区银行,没有分支(总公司是分支)
  • 您需要两个内部帐户,其中包括:
  • 一个简单的总帐
  • 以及外部帐户,每个客户一个
  • 我想到的最好的概念是小型社区银行,或者像这样运营的企业。一个农业合作社,每个农民都有一个账户,他可以在那里购买,并按月计费和支付,合作社像一家小银行一样运作,拥有完整的总账,并提供一些简单的银行设施。
  • 单个赌场(不是连锁)具有相同的要求。
  • 不是拥有多个分行的大型银行;各种金融产品;等等。
  • 而不是Systemor Bank,我会称它为House。稍后将清楚其相关性。

任何人士为复式方法只是总帐无需外部客户账户,可以从这个回答搜集,很容易。

同样,这里给出的数据模型很容易扩展,Ledger可以比给出的简单模型更大。


B. 解决方案

1.复式记账

1.1. 概念

知道它是什么名字;它具有巨大的价值;它比自己制作的系统更好,是一回事,知道什么足以实施它,又是另一回事。

  1. 首先,一个人需要对总账和一般会计原则有一个很好的理解。

  2. 第二,理解金钱代表价值的概念。价值不能被创造或破坏,它只能被移动。 账户中的一个存储桶另一个存储桶,也称为借方(从账户)和贷方(到账户)。

  3. 虽然SUM( all Credits ) = SUM( all Debits )确实可以从 DEA 系统中获得这样的报告,但这不是实施所需的理解,这只是一个最终结果。还有更多。

  • 虽然每笔交易确实由一对组成:相同金额的一个 Credit 和一个 Debit,但还有更多。

  • 对的每条腿;贷方和借方不在同一个账户或分类账中,它们在不同的账户、分类账或账户和分类账中。

  • SUM(所有学分)并不简单,因为它们在这些不同的地方(套)。它们不在同一个表的两行中(它们可能是,稍后更多)。同样,SUM( all Debits )

  • 因此,两个 SUM() 中的每一个都涵盖了完全不同的集合(关系集),并且必须首先获得,然后才能比较两个 SUM()。

1.2. 了解复式会计

在尝试实施 DEA 之前,我们需要正确理解我们正在实施的事物。我建议如下:

  1. 你说得对,第一原则是持有Credit/Debit Pair观点,在处理账本、总账中的任何事情时;客户账户;银行账户;等等。
  • 这是要持有的首要心态,与需要在这个或那个账户或分类账中完成的任何事情分开。

  • 我已经把它放在了顶部;左边,在数据模型中,这样所有文章的从属关系都在视觉上呈现。

  1. 复式记账系统的目的或目标是:
  • 消除(不仅仅是减少)所谓的:

    • “丢钱

    • “丢失”交易(贷方/借方对的一方或另一方)

    • 以及在追逐它上浪费的时间。

    • 不仅可以轻松找到钱,而且可以快速确定它到底发生了什么以及现在在哪里。

  • 完整的审计功能
    保持良好的账户是不够的,对于一个负责他人资金的企业来说,易于审计是必不可少的。也就是说,任何会计师或审计师都必须能够不受阻碍地检查账簿。

    • 这就是为什么第一件事是局外人,例如。审计师想知道的是,是否 SUM( all Credits ) = SUM( all Debits )。这也解释了为什么 DEA 概念高于公司可能保留的任何账户或会计系统。
  • 最大的好处虽然是第三级,但每天或月末的任务,例如试算表或结账,都可以轻松快速地结束。所有报告;声明;资产负债表; 等,可以简单地获得(SELECT如果数据库是关系,则使用单个)。

  1. 然后准备复式簿记的维基百科条目。
  • 互联网上有很多误导性信息,维基百科尤其糟糕,它永远在变化(真相不会改变,虚假会随着天气而变化),但抱歉,这就是我们所拥有的。仅使用它来获得概览,尽管它很长,但它没有结构或逻辑描述。按照链接获取更好的信息。

  • 我不完全同意维基百科文章中的术语。尽管如此,为了避免可避免的混淆,我将使用这些术语。

  • 网络上有可用的教程,有些教程比其他教程好。这些推荐给正在实施适当的会计系统的任何人,无论是否有 DEA。这需要时间,它与这样的答案无关,这就是我链接维基百科文章的原因

2. 商业交易

理想情况下,我想看看这些双条目行在数据库方面的样子,整个过程在 SQL 中的样子,在每种情况下哪些实体受到影响等。

好的。让我们先了解事务,然后逐步了解支持它们的数据模型,然后检查示例行。任何其他顺序都会适得其反,并导致不必要的来回。

你的编号。绿色是House一般Ledger,蓝色是外部客户Account,黑色是中性。

  • 这是Treatment的第一个增量,即在不同情况下如何处理事物(您的关注以及您对具体示例的要求是完全正确的)。

  • Credit/Debit Pairs
    这是 DEA 的第一原则,理解对,作为对,除了对之外别无他物。

不要担心 GeneralLedger或 theAccount是如何设置的,或者数据模型是什么样的。从会计师的角度思考(必须在书中完成什么),而不是从开发人员的角度(必须在系统中完成的任务)。

请注意,该对的每条腿都在一组 (the Ledger) 中,或分成两组(一条腿在Ledger,另一条腿在Account)。没有两条腿都在的对Account

  • 由于 DEA 已实施,因此每个业务交易(与数据库交易不同)由两个操作组成,一个用于每个贷方/借方支路。这两个动作是纸质账簿中的两个条目。
  1. 客户将现金存入他的账户

Op11 Op12

  • 在 DayEnd 过程中,除其他任务外,所有现金都会被核算和检查。这一天是关闭的。HouseCash银行认为日常现金交易所需的所有现金都放在那里HouseReserve

Op13

  1. 银行每月向所有客户账户收取一次费用(样本批量作业)

操作2

  • 这每个充电AccountFee
  • Fee 依赖于 AccountType_Ext
  • 这是简单的情况。如果Fee依赖于其他东西,例如 中的交易数量Account;或CurrentBalance低于或高于某个限度;等等,没有显示。我相信你能弄清楚。
  1. 客户在柜台进行一些操作,银行收取费用(提现+提现费用),
  • 简单交易不产生费用,并且已经提供存款/取款。让我们检查一个实际收取费用的商业交易。

操作3

  • Mary 给她的儿子 Fred 寄了 500 美元,Fred 正在海外寻找鲸鱼来拯救,但钱已经花光了。银行对海外银行转账收取 30 美元。Fred 可以在任何合作银行分行收取资金(以相当于 500 美元的当地货币)。
  • 要将资金真正转移到外国银行,House必须与提供国际结算和货币兑换服务的当地大银行进行互动。这与我们无关,也未显示。在任何情况下,所有这些类型的Interbank事务都是每天批处理和处理一次,而不是每个AccountTransaction.
  • 在这个简单的DEA系统中,House并没有在外币账户Ledger。这很容易实现。
  1. 玛丽从她的账户中汇出一些钱到约翰在同一家银行的账户

Op4

  • 这笔钱目前在 Mary 的账户中(在今天的前一天存入),这就是为什么它在HouseReserve,而不是HouseCash
  • 这笔钱从HouseReservein 转入HouseCash是因为约翰今天可能会进入银行并将其取出。
  • 如实施例[1.3]中所描述的上方,在DayEnd过程,任何金钱坐在HouseCash在所有Accounts将被移动到HouseReserve。未显示。

3. 关系数据模型 • 初始

现在让我们看看数据建模者做了什么来支持会计师的需求,即业务交易。

  • 这当然是Treatment的第二个增量,建模者已经理解现实世界的业务事务是什么,用关系术语(FOPC; RM ; Logic; Normalisation )表示

  • 这不是满足重述范围所需的最简单的数据模型。

  • 有一些更简单的模型(稍后会详细介绍),但它们有这个模型没有的问题,这些问题如果不是必须的,也是需要避免的。

  • 图像太大,无法在线查看。在新选项卡中打开图像,以全尺寸欣赏它。

助教

3.1. 符号

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

  • 我的IDEF1X 简介对于那些不熟悉关系模型或其建模方法的人来说是必不可少的读物。请注意,IDEF1X 模型具有丰富的细节和精确度,显示了所有必需的细节,而本土模型不了解标准的必要性,定义要少得多。这意味着,需要完全理解符号。

3.2. 内容

  • 由其他人,而我产生了真正的关系数据模型之间的主要区别是:
    一个商业交易(通常两个动作;两条腿,每个信用卡/借记一个)与两面,每学分一个受单行/借记
    AccountTransactionLedgerTransaction

  • 大多数建模者会为贷方/借方对建模两行,每条腿或边各一个(嘿,一条腿是贷方,另一条腿是借方,如果我将其标准化,我会得到两行)。

  • 错误的。如果我告诉你 Fred 是 Sally 的父亲,你知道,从那个事实来看,Sally 是 Fred 的女儿。

  • A 只FOREIGN KEY需要声明一次,而不是每一方都声明一次。

  • 同样,信用/借记对是一个单一的商业交易
    一个单一的原子文章,可以从任何一方看到,就像一枚硬币的两个面。建模成这样。

  • 防止了所有可预防的错误,消除了对“丢失”腿的搜索。

  • 即使对于那些不符合标准的 OLTP 代码,这会导致相当可预防的并发问题,如果实现了这种方法,这也是一篇不会出现这些问题的文章。

  • 此外,%Transaction表中的行数减半。

  • 我已经安排的条款,使得
    外部 Account
    内部 LedgerLedgerTransaction
    内外 AccountTransaction
    都清楚。

  • 连同来自Wikipedia 条目的定义块。

  • 熟悉 DEA 贷方/借方对后,现在研究对的处理。请注意,处理是不同的,它基于许多标准(三种帐户类型;六种Ledger类型;等等),而这些标准又基于总帐的复杂性。

  • Ledger很简单,只有Asset/Liability帐户。当然,您可以自由扩展它。

  • 老鹰眼会注意到AccountStatement.ClosingBalance并且LedgerStatement.ClosingBalance实际上可以派生,因此(从表面上看)不应存储。然而,这些是公布的数字,例如。每个账户的每月银行对账单,因此需要审计,因此必须存储。

全面处理该问题,包括考虑因素;定义; 治疗,参考这个问答:

3.3. 概括

在结束本节时,我们应该已经达成了这样的理解:

  • DEA 的总体原则,贷方/借方对,纯智力

  • 典型的商业交易,总是一个贷方/借方对,两条腿,会计账簿中的两个条目

  • 更深入地了解上述交易的处理方式

  • 该环境House管理(内部(;合作赌场中小银行)Ledger和外部客户Account

  • 首先看一下被提议用来处理所有这些的数据模型。


4. 关系数据模型 • 完整

这里又是一整套样本数据。

  • 重新主键

  • 请注意,LedgerNoandAccountNo不是代理,它们对组织有意义,在排序和构建Ledger等方面。它们是稳定的数字,而不是AUTOINCREMENTIDENTITY或任何类型的数字。

  • 主键为LedgerTransactionAccountTransaction是纯的,复合关系的按键。

  • 它不是纸质会计师所钟爱的某种交易编号。

  • 这也不是瘫痪Record ID

  • 可选键是更有意义的人类,因此我已经在实施例中使用它们(商业交易,[2]上面,下面和[5])。这个答案已经分层,这将是试图涉及的数百个噩梦1's, 2's,并3’s给对方。

  • 如果我们想了解某事物的含义,我们需要抓住事物存在的意义,而不是通过给它一个数字来去除它的意义。

  • 在示例数据中,主键为粗体。

数据


5. 与行的业务交易

理想情况下,我想看看这些双条目行在数据库方面的样子,整个过程在 SQL 中的样子,在每种情况下哪些实体受到影响等。

现在我们了解了业务事务以及为需求提供服务的数据模型,我们可以检查业务事务以及受影响的行。

  • 在 DEA 的术语中,每个业务交易都有两条腿,在纸质账簿中的两个条目,对于每个贷记/借记对,
    仍然是一个单一的业务交易,现在:
    它受到具有两个的单行的影响边,对于每个贷方/借方对。

  • 这是理解处理的第三个增量:业务交易;实现它们的数据模型;现在,受影响的行

  • 示例数据库行以简短形式的表名作为前缀。
    加号表示INSERT
    减号表示DELETE
    等于号UPDATE

  1. 客户将现金存入他的账户

第 11 行 第 12 行 第 13 行

  1. 银行每月向所有客户账户收取一次费用(样本批量作业)

第 2 行

  • 这也是一个批处理作业,只是 MonthEnd 过程中的一项任务。
  • 注意日期是当月的第一天。
  1. 客户在柜台进行一些操作,银行收取费用(提现+提现费用),

第 3 行

  • 明确地说,这是三个业务交易;每个条目两个,贷方/借方对的每一侧一个;每个受一个数据库行的影响。
  1. 玛丽从她的账户中汇出一些钱到约翰在同一家银行的账户

第 4 行


6. SQL 代码

通常有几种方法可以给猫剥皮(代码),但如果猫还活着,则很少(代码用于高并发系统)。

  • 关系模型建立在一阶谓词演算(又名一阶逻辑),所有的定义(DDL),因此所有查询(DML)是完全逻辑。

  • 因此,符合这种理解的数据模型完全是逻辑的。

  • 针对这种数据模型的查询非常简单:逻辑和直接。他们没有Record ID基于文件系统所需的复杂代码。

因此,在SQL代码请求可能的几种方法中,我给出了最直接和合乎逻辑的。

代码示例是适合 SO 的代码示例,您必须捕获错误并从错误中恢复;你不会尝试任何会失败的事情(在使用动词之前检查操作的有效性),并遵循 ACID 事务的 OLTP 标准。

6.1. SQL 视图 • 帐户当前余额

由于这个代码段在很多地方都会用到,让我们做正确的事情并创建一个视图。

  • 请注意,在真正的 SQL 平台上,源代码在提交时编译并运行,存储过程和视图以其编译形式存储,从而消除了每次执行时的编译。与米老鼠的 NONsql 套件不同。

  • 高端商业 SQL 平台做得更多,例如缓存视图的查询计划,以及存储过程中的查询。

CREATE VIEW Account_Current_V 
AS
    SELECT 
        AccountNo,
        Date = DATEADD( DD, -1, GETDATE() ), -- show previous day
        ClosingBalance,
        TotalCredit = (
            SELECT SUM( Amount )
                FROM AccountTransaction
                WHERE AccountNo = @AccountNo
                    AND XactTypeCode_Ext IN ( "AC", "Dp" )
                        -- this month
                    AND DateTime >= CONVERT( CHAR(6), GETDATE(), 2 ) + "01"
                ),
        TotalDebit = (
            SELECT SUM( Amount )
                FROM AccountTransaction
                WHERE AccountNo = @AccountNo
                    AND XactTypeCode_Ext NOT IN ( "AC", "Dp" )
                    AND DateTime >= CONVERT( CHAR(6), GETDATE(), 2 ) + "01"
                ),
        CurrentBalance = ClosingBalance + 
            <TotalCredit> -                  -- subquery above
            <TotalDebit>                     -- subquery above
        FROM AccountStatement                -- 1st day of this month
        WHERE Date = CONVERT( CHAR(6), GETDATE(), 2 ) + "01"

Run Code Online (Sandbox Code Playgroud)

6.2. SQL 事务 • [1.2] 从 [外部] 帐户中提取

另一个 DEA 业务交易的过程。

CREATE PROC Account_Withdraw_tr ( 
    @AccountNo, 
    @Amount
    ) 
AS
    IF EXISTS ( SELECT 1                   -- validate before verb
            FROM AccountCurrent_V 
            WHERE AccountNo = @AccountNo 
            AND CurrentBalance >= @Amount  -- withdrawal is possible
            )
        SELECT @LedgerNo = LedgerNo 
            FROM Ledger 
            WHERE Name = "HouseCash"
        BEGIN TRAN
        INSERT AccountTransaction 
            VALUES ( @LedgerNo, GETDATE(), "Cr", "Wd", @AccountNo, @Amount )
        COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)

6.3. SQL 事务 • [1.1] 存款到 [外部] 帐户

一个 proc,设置为 SQL 事务,用于执行 DEA 业务事务。

CREATE PROC Account_Withdraw_tr ( 
    @AccountNo, 
    @Amount
    ) 
AS
    IF EXISTS ( SELECT 1                   -- validate before verb
            FROM AccountCurrent_V 
            WHERE AccountNo = @AccountNo 
            AND CurrentBalance >= @Amount  -- withdrawal is possible
            )
        SELECT @LedgerNo = LedgerNo 
            FROM Ledger 
            WHERE Name = "HouseCash"
        BEGIN TRAN
        INSERT AccountTransaction 
            VALUES ( @LedgerNo, GETDATE(), "Cr", "Wd", @AccountNo, @Amount )
        COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)

6.4. SQL 事务 • [内部] 分类帐帐户转移

将任何业务交易添加到 的过程LedgerAccount。它总是:

  • LedgerTransaction.LedgerNo,这是Credit
  • LedgerTransaction.LedgerNo_Dr,这是Debit腿。
  • 调用者给出的。
CREATE PROC Account_Deposit_tr ( 
    @AccountNo, 
    @Amount
    ) 
AS
    -- IF EXISTS, etc                        -- validate before verb
        BEGIN
        SELECT @LedgerNo ...
        BEGIN TRAN
        INSERT AccountTransaction 
            VALUES ( @LedgerNo, GETDATE(), "Dr", "Dp", @AccountNo, @Amount )
        COMMIT TRAN
        END
Run Code Online (Sandbox Code Playgroud)

6.5. SQL 批处理任务 • 帐户月末

只有一个任务,在 proc 中处理月末AccountStatement,作为批处理作业执行。

CREATE PROC Ledger_Xact_tr ( 
    @LedgerNo,    -- Credit Ledger Account
    @LedgerNo_Dr, -- Debit  Ledger Account
    @Amount 
    ) 
AS
    ... IF EXISTS, etc ...
        BEGIN TRAN
        INSERT LedgerTransaction  
            VALUES ( @LedgerNo, GETDATE(), @LedgerNo_Dr, @Amount )
        COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)

6.6. SQL 报告 • SUM(贷方)与 SUM(借方)

虽然SUM(all Credits) = SUM(all Debits)确实如此,并且可以从 DEA 系统获得这样的报告,但这不是理解。还有更多

希望我已经给出了方法和细节,并涵盖了理解更多内容,以便您现在可以轻松编写SELECT生成所需报告所需的内容。

或者也许是 external 的 Monthly Statement Accounts,带有运行总计AccountBalance列。想想:银行对账单。

  • 真正的关系数据库的众多高效率之一是,任何报告都可以通过单个SELECT命令提供服务。

一份PDF

最后但并非最不重要的一点是,最好将所有这些内嵌图形组织到一个PDF 中格式为 A3(我的美国朋友为 11x17)。为了学习和注释,请用 A2 (17x22) 打印。


  • 这个答案有两点值得注意(除了它的长度):a)没有引用既定的实践/教科书;b) 任何 ERP 或会计包都没有使用“业务事务是单行”的设计,并且有充分的理由:它是不充分的。确实,许多交易(尤其是银行业务)仅包含两条腿:借方和贷方(相等且相反)。但一般来说,可能有几个方面——通常是税收和/或费用,从一个账户到其他几个账户的多次分配。 (11认同)
  • @RexBloom QuickBooks 不是 DEA。QuickBooks 不能用于银行业(银行业需要 DEA)。在输入非 DEA“交易”之前,您正在执行一个**手动的、系统外**的过程(平衡)。在 DEA 下您不需要这样做,因为系统始终是平衡的,因为每个交易是平衡的,不需要人工控制,不是“两笔贷方交易”,而是两笔DEA交易,每笔一笔贷方**和**一笔借方交易。 (4认同)
  • 谢谢@taffer,你的坚持做得很好。通常,应收账款发票交易(输入复式记账会计系统)在一笔交易中至少使用三个帐户: 客户(应收账款总额);税(转移给政府);销售的产品(我们的收入)。在美国司法管辖区,我们必须分别核算联邦税、州税、市/地方税——因此,_在一笔交易中_至少有 5 个账户条目。从法律上讲,我们不能将税收视为“我们的”收入——因为我们只是代表政府征收。 (4认同)
  • @亚历克斯。1)我没有这么说(请不要听那些困惑的人的评论)。商业交易是纸质账户中的**两个条目**;每个贷方/借方支路一个条目。这是受我数据库中的一行的影响。2) `OTC_Transfer` 是 DEA 意义上的三笔业务交易,而不是一笔。只要理解这一点,它就可以被视为一个“大型”商业交易。3)尽管如此,我还是在全文中添加了一些澄清的话。以及一个额外的代码段。新年快乐。 (3认同)
  • @生而自由。1)这是记账端的模板(状态为‘已记账’)。其他状态;等等(你的列表)超出了Accounting的范围,可能会部署在一个单独的表中,这是一个队列,而不是提交给Accounting。2) 余额**在**会计,“Ledger”集群中。*外部*会计不可能有余额(如果有的话,那也是虚构的)。3) 您可以在`Account`中设置一个`Suspense`帐户,请阅读它。 (3认同)
  • @乔恩1)是的。这是两笔真实的(物理)会计交易,每笔交易都有不同的当事人(一方在商店;另一方在银行) 2) 发票将发送给谁,您的孩子?好的,一张发票有两个发票行项目。3) 必须正确管理税收:为每个州开设一个外部账户,为联邦开设一个外部账户。因此,任何应税项目都有两个会计交易。然后发票行项目就很容易了。 (3认同)
  • 因此,“单式记账”簿记是一种幼稚的方法,根本无法扩展。声明“此外,行数减半”。是假的。(好像现在有人担心节省磁盘空间。)您需要对信用帐户和借记帐户都建立索引(并使用对“帐户主帐户”的外键引用来声明这两个帐户)。在我看来,德里克似乎是凭空编造了这整件事。我有兴趣了解使用像这样的“单项”簿记的数据库设计的任何示例。没有人应该效仿这个例子。 (2认同)
  • 哦,我应该补充一点:功能齐全的帐户系统中的一个典型要求是保存“待处理”或“注册未完成”交易(有时称为“收件箱”)。例如,我们收到一张 100 美元的发票;我们知道供应商的账户(并且我们希望在查询/欠款中显示针对该供应商的 100 美元);但我们不知道行项目/费用的帐户编码(不是全部)。因此,我们以待处理状态发布“单方面”交易,以将其与完全发布/平衡交易区分开来。“单式记账”簿记不足以满足这一要求。 (2认同)
  • 也许“业务交易是单行”有点错误,因为“OTC 转账”由 3 行组成。我猜你的意思是“双重分录是单行”,并且每个业务交易有很多双重分录。 (2认同)
  • @亚历克斯。这个答案当然是为了这个目的而完成的。然而,其他人要求扩展 **Ledger**,我在[此处](/sf/answers/4190046451/)提供了该扩展。您可能感兴趣。 (2认同)
  • 一个借方(例如工资费用)可以与两个或多个贷方(例如工资、税金)相平衡。借方和贷方条目之间并不存在一对一的匹配,而是所有借方和贷方平衡的约束。我将使用 LedgerNo、Date、Type (Cr,Dr) 和 Amount 对 LedgerTransaction 进行建模。 (2认同)
  • 该模型是否支持涉及两个以上账户的复杂(“复合”)交易?例如“以 15,000 美元的价格购买土地,并提供 5,000 美元现金,并承诺在 90 天内支付余款”。这将借记土地 15,000 美元,贷记现金 5,000 美元,贷记应付票据 10,000 美元。如果是这样,数据库行会是什么样子? (2认同)
  • @Edward我在银行业的经验是,像你提到的复杂交易很常见。重要的是账本是平衡的,而不是每笔交易都有匹配的贷方和借方。工资单、信用卡账单、结算等都有大量的贷方和借方,可能会抵消到多个分类账户。甚至 Quick Books 也具有用于同样目的的拆分功能。如果我存入 1,000(贷方)并需要将其分配给两张发票(借方),我不会创建两笔贷方交易 - 这是一笔贷方与两笔借方的平衡。 (2认同)
  • @Edward 那么问题仍然是会计意义上的,与这个实现 DEA 的模型无关。不存在“复合”或“复杂”交易这样的事情。只有 DEA 交易或非 DEA(米老鼠)交易。你不能做你所描述的事情,因为它是反 DEA 的。您必须执行两项 DEA 交易: 土地/现金 5,000 美元 [DR, CR];土地/应付票据 10,000 美元 [DR、CR] .. 以及之前将现金存入现金账户的交易。 (2认同)
  • 好的,谢谢你的澄清。我现在明白你从哪里来了。教科书并没有这样对待——他们确实土地$15,000 [DR];应付票据 $10,000 [CR];现金 5,000 美元 [CR]。也许 DEA 中的“双倍”是指 CR 和 DR 双方的金额平衡,而不是单个 DR、CR 对?无论如何,你已经回答了我的问题 - 我知道你的模型现在是如何工作的。 (2认同)
  • @塔弗。1)我没有说过*DEA交易允许两个以上的账户*,因此我无法为其辩护。如果是两个以上的账户,那就**不是 DEA**。2)污水池文章说*至少两个帐户*,你需要追他们(不是我)作为参考。还有一个方法。 (2认同)
  • 好了,现在我已经完成了你的作业:*Dauber、Shim、Siegel (2012)。完整的注册会计师参考。Wiley。* 第 42 页有一个复合条目,第 46 页有另一个条目,第 111 页有另一个条目。 (2认同)
  • @PerformanceDBA 这里没有澄清的两个问题:1)如果我们有交易状态(如计划、待处理、拒绝)怎么办?我们应该将它们存储在会计系统和 AccountTransaction 表中还是应该存储在会计工具之外?2) 如果我们需要根据不同的状态计算不同的余额(例如待处理交易影响可用余额)怎么办?您的建议是什么? (2认同)
  • @だらんぎんじょん 1)我不区分DE会计和DE簿记(簿记只是会计的文书方面)。2)对于defns,你需要识别和使用一个权威,互联网是一个污水池,很少。试试这个定义**[什么是复式记账系统](https://www.accountingcoach.com/blog/what-is-the-double-entry-system)**。3)现在来说说行。它通常实现为两行,这需要适当的 ACID 事务(非免费软件),并且当需要许多引用时会出现问题。 (2认同)
  • 哦哇。非常感谢如此详细的解释。 (2认同)
  • @lowercase00 谢谢。我提供了一个关系数据库答案,它不是会计教程。对于会计方面,请随意使用您选择的会计权限......显然,我使用了不同的权限,这有点不那么混乱。 (2认同)

pou*_*def 5

这是我的架构(以 sqlite 为例),有 2 个表:

表格

-- This is a list of your chart of accounts
CREATE TABLE "accounts" (
    "name"      TEXT,
    "number"    INTEGER,
    "normal"    INTEGER
)

-- This is a table of each transaction
CREATE TABLE "transactions"
  (
     "id"        INTEGER, 
     "date"      TEXT,
     "amount"    REAL,
     "account"   INTEGER,
     "direction" INTEGER
  ) 

Run Code Online (Sandbox Code Playgroud)

根据此约定,accounts.normaltransaction.direction字段设置1为借方和-1贷方。最终用户永远不会看到这一点,但它使算术变得容易。

当您创建日记帐分录时,表中至少有 2 行transactions- 借方和贷方。他们应该共享相同的id

要查看您的余额,您可以运行以下查询:

select
  (account) as a,
  name,
  sum(amount * direction * normal) as balance
from
  transactions
  left join accounts on a = accounts.number
group by
  name
order by
  a,
  name;
Run Code Online (Sandbox Code Playgroud)

要查看分类帐,您可以运行以下命令:

select
  id,
  date,
  name,
  case when direction == 1 then amount end as DR,
  case when direction == -1 then amount end as CR
from
  transactions
  left join accounts on account = accounts.number
order by
  id,
  date,
  CR,
  DR;
Run Code Online (Sandbox Code Playgroud)

我有一篇更详细的文章,其中介绍了您可以运行的不同查询以及示例数据。但是,通过上面两个表,您可以创建一个有效的复式记账系统。