简体   繁体   English

复式记账系统中与状态的高级交易

[英]High level transactions with states in a double entry accounting system

Assume there is a system with Double-Entry accounting:假设有一个复式记账系统:

I prefer the latter model with normalised Transaction .我更喜欢带有规范化Transaction的后一种模型。

There are long running complex operations with many states.有许多状态的长期运行的复杂操作。 One large transaction affects many ext.一笔大交易会影响许多分机。 accounts (or even many ledgers), you can reverse (post opposite Transaction s), add new transactions aka Fee, Penalty or redistribute money from all involved ext.帐户(或什至许多分类帐),您可以逆转(发布相反的Transaction ),添加新交易,即费用,罚款或从所有相关分机重新分配资金。 account/ledgers transactions when state changes.状态更改时的帐户/分类帐交易。 Must keep references to Transactions and don't duplicate Amount in these process-specific tables.必须保留对Transactions引用,并且不要在这些特定于流程的表中复制Amount 在此处输入图片说明

More examples:更多例子:

在此处输入图片说明

The simple example of ApplicationTransaction is a Bet which consist of several Pledge s when you take some collateral from each participant. ApplicationTransaction的简单示例是一个Bet ,当您从每个参与者那里获取一些抵押品时,它由几个Pledge组成。 Each participant even has different assets at stake and House can take many of them to satisfy some requirement.每个参与者甚至有不同的资产, House可以使用其中的许多来满足某些要求。 I am thinking about generic ApplicationTransaction table with D iscriminator and many specific tables.我正在考虑带有D鉴别器和许多特定表的通用ApplicationTransaction表。

And ApplicationTransaction table with State column referencing many double-entry transactions it performs. ApplicationTransaction表的State列引用了它执行的许多复式交易。 During lifetime of the ApplicationTransaction it could post (make Transaction s) on its state changes, but not always.ApplicationTransaction生命周期内,它可以发布(制作Transaction s)其状态更改,但并非总是如此。 For example Bet takes collateral and releases it when Bet time is up, under some circumstances it redistributes initial amounts this operation held, but some of its states does not post.例如, Bet获取抵押品并在Bet时间到时释放它,在某些情况下,它会重新分配此操作持有的初始金额,但其某些状态不会发布。

A Lottery (which is the most made up use-case here) could be an example of ApplicationTransaction which affects many accounts, it starts and ends with massive "airdrop" of winnings. Lottery (这是这里最复杂的用例)可能是影响许多帐户的ApplicationTransaction一个例子,它以大量的“空投”奖金开始和结束。 Each instance has its own attribute values, the properties are static.每个实例都有自己的属性值,属性是静态的。

Another use case is Trade between two ext.另一个用例是两个分机之间的Trade accounts where House can be a middleman, must take assets from each side, move it to special LedgerAccount|XYZ|AL|Escrow| House可以作为中间人的账户,必须从每一方拿走资产,将其转移到特殊的LedgerAccount|XYZ|AL|Escrow| , one per ApplicationTransaction.Type , not per instance. ,每个ApplicationTransaction.Type一个,而不是每个实例。 Keep a record of transfers related to specific Trade instance, could last for a while, have several states, attributes, different outcomes for ext.记录与特定Trade实例相关的转移记录,可能会持续一段时间,具有多种状态、属性、不同的结果。 account holders which could be a penalty to one side and repayment to another.账户持有人可能是一方的罚款和另一方的还款。 Without orderbook or matching engine.没有订单或匹配引擎。 Such exchange process has several states, another counterparty could be involved in a dispute resolution if such State transition happens.这种交换过程有几个状态,如果发生这种State转换,另一个交易对手可能会参与争议解决。 Both participants must flag a Trade with something like Payment Received (assuming the payment is done outside of the system).两个参与者都必须用Payment Received东西来标记Trade (假设付款是在系统外完成的)。 That's a state transition.那是状态转换。 System could charge fee from each participant.系统可以向每个参与者收取费用。

It's not a single Transaction entry.它不是单个Transaction条目。 A group of them.他们中的一群人。 For instance if I need to put some amount into escrow I can put X * Emeralds and X * Diamonds in order to date a princess.例如,如果我需要将一些金额放入托管中,我可以放入 X * 祖母绿和 X * 钻石以便与公主约会。 So it not only posts many (AssetType, Amount, AccountNo) (N * assets * 2 parties) but also posts into Income LedgerAccount .因此,它不仅发布了许多(AssetType, Amount, AccountNo) (N * assets * 2 方),而且还发布到Income LedgerAccount Assume we perform a trade over a bucket of Assets .假设我们对一桶Assets进行交易。

Could also add some table which restricts possible transitions per operation type so we can add constraints.还可以添加一些表来限制每种操作类型的可能转换,以便我们可以添加约束。 I see it as a copy of State lookup table with extra NextState column references itself, this way it defines a set of available states.我将其视为 State 查找表的副本,带有额外的NextState列引用本身,这样它定义了一组可用状态。 Out of scope of this question though.虽然超出了这个问题的范围。

I am obviously not solving a new problem here, so the question is what is obviously wrong with my design and how correct direction would look like.我显然不是在这里解决新问题,所以问题是我的设计明显有什么问题以及正确的方向是什么样的。

Perhaps there is still misunderstanding from my side, but I don't think that each application use-case instance should produce disposable LedgerAccounts , because we don't create new HouseCash per use-case Deposit and Withdrawal .也许还有个从我身边误解,但我不认为每个应用程序用例实例应该产生一次性LedgerAccounts ,因为我们没有创造新的HouseCash每个用例DepositWithdrawal The Deposit/Withdrawal is also fits into ApplicationTransaction category, with few state transitions (like rejected by payment processor).存款/取款也适用于ApplicationTransaction类别,几乎没有状态转换(例如被支付处理器拒绝)。 In a real app you have a special tables to handle it, there is a payment method and amount, etc.在真正的应用程序中,您有一个特殊的表格来处理它,有付款方式和金额等。

Otherwise such approach will result in hundreds of thousands of disposable LedgerAccounts .否则这种方法将导致数十万个一次性LedgerAccounts The question is not a request to made a general purpose model of general purpose system for Universe, it's a question whether the direction is right, Not sure that we have to keep one-time accounts, as I already have stated, I see Account and LedgerAccount as something required to derive House reports, maintain customer accounts otherwise it looks as stupid as defining account per CPU-core on AWS EC2.问题不是要求为 Universe 建立通用系统的通用模型,而是方向是否正确的问题,不确定我们是否必须保留一次性帐户,正如我已经说过的,我看到AccountLedgerAccount作为导出 House 报告所需的东西,维护客户帐户,否则它看起来就像在 AWS EC2 上为每个 CPU 核心定义帐户一样愚蠢。

Reference Data Model参考数据模型

I prefer the latter model with normalised Transaction.我更喜欢带有标准化事务的后一种模型。

In keeping with SO guidelines, each Answer is limited to the Question.根据 SO 指南,每个答案仅限于问题。 The data model in the first Answer satisfies the Question, and assumes an understanding of the Ledger.第一个答案中的数据模型满足问题,并假设了解分类帐。 The second question assumes no understanding of the Ledger, so the second Answer gives a full explanation of the Ledger, and requires an even more detailed data model.第二个问题假设不了解Ledger,因此第二个Answer 对Ledger 进行了完整的解释,并且需要更详细的数据模型。

By all means, we will use the second data model .无论如何,我们将使用第二个数据模型


Problem • Approach问题 • 方法

There are long running complex operations with many states.有许多状态的长期运行的复杂操作。 One large transaction affects many ext.一笔大交易会影响许多分机。 accounts (or even many ledgers),帐户(甚至许多分类帐),
where you can rollback, add new transactions aka Fee, Penalty or redistribute money from all involved ext.您可以在其中回滚、添加新交易,即费用、罚款或从所有相关分机重新分配资金。 account/ledgers transactions when state changes.状态更改时的帐户/分类帐交易。

Definitely, absolutely, not.绝对,绝对,不是。 Please forget about thinking in IT or CS terms.请忘记用 IT 或 CS 术语思考。 Think only in Accounting terms (and later, at implementation, implement the Accounting requirements).仅从会计方面考虑(然后在实施时实施会计要求)。

  • Each Accounting or business transaction is single, immediate.每个会计或商业交易都是单一的、直接的。 It involves one Ledger Account Number LedgerNo on one side, and either another LedgerNo or an External Account Number AccountNo on the other side.它在一侧涉及一个分类帐帐号LedgerNo在另一侧涉及另一个LedgerNo或外部帐号AccountNo

  • There is no waiting, no states, no progression.没有等待,没有状态,没有进展。

  • There is no such thing as a business or Accounting transaction that affects "many external Accounts" (or many other Ledger Accounts).不存在影响“许多外部帐户”(或许多其他分类帐帐户)的业务或会计交易 Such a perception is not an Accounting one.这种看法不是会计方面的。

    • If you implement anything along those lines you will not have an Accounting system, you will have an Anti-Accounting system (with or without DEA), that fails Bookkeeping, fails Accounting, and fails Audit.如果你按照这些方式实施任何事情,你将没有会计系统,你将有一个反会计系统(有或没有 DEA),簿记失败,会计失败,审计失败。
  • You can have a procedure that affects many Accounts (Ledger-Ledger or Ledger-[External]Account).您可以有一个程序影响许多帐户(分类帐-分类帐或分类帐-[外部]帐户)。 But that procedure executes single business transactions.但该过程执行单个业务交易。 Examples in the other Answer are:另一个答案中的示例是:

    • § 5/2 Charge Monthly Fee (pseudo-code) § 5/2 收取月费(伪代码)
      Imagine a BEGIN TRAN/COMMIT TRAN bracketing that INSERT想象一下BEGIN TRAN/COMMIT TRAN括号内的INSERT
    • § 6.5. § 6.5。 SQL Batch Task • Account Month End SQL 批处理任务 • 帐户月末
      It specifically advises SQL Transactions to be executed in batches .它特别建议批量执行 SQL 事务。 That means a `COMMIT TRAN/BEGIN TRAN every 100 or 200 business transactions.这意味着每 100 或 200 个业务交易就有一次“COMMIT TRAN/BEGIN TRAN”。 Usually one would have restart control, etc. (If you do not understand that, please ask.)通常会有重启控制等(如果您不明白,请询问。)

I am thinking about generic Operation table with OperationType Discriminator and many specific tables for each Operation.Type.我正在考虑带有 OperationType Discriminator 的通用操作表和每个 Operation.Type 的许多特定表。

(No comment on the Operation table.) (对操作表没有评论。)

An ordinary Exclusive Subtype cluster in Relational or IDEF1X terms. Relational 或 IDEF1X 术语中的普通 Exclusive Subtype 集群。

... so we can add constraints. ...所以我们可以添加约束。 I am not sure where its place though, perhaps application code.我不确定它的位置,也许是应用程序代码。

  • Never place constraints or anything that constrains the logic (Consistency) of the data anywhere other than in the database.永远不要在数据库以外的任何地方放置约束或任何限制数据逻辑(一致性)的东西。

  • The database is a single recovery unit.数据库是单个恢复单元。 It must contain它必须包含

    • all constraints (there is no logical limit; anything and everything in a Relational database can be declared in terms of FOPC Predicates), and所有约束(没有逻辑限制;关系数据库中的任何事物都可以根据 FOPC 谓词声明),以及
    • all Transactions, in stored procs.所有交易,在存储过程中。
  • All tables are GRANTED SELECT permission only, never GRANTED INSERT, UPDATE, DELETE .所有表都只有GRANTED SELECT权限,从不GRANTED INSERT, UPDATE, DELETE That means no direct writes to tables.这意味着不能直接写入表。

  • The Transactions (list of stored procs) are the Database API .事务(存储过程列表)是数据库 API GRANT EXEC permission to the carefully chosen Roles , and thus to specific Users .为精心选择的Roles授予GRANT EXEC权限,从而授予特定Users

  • All app code, which in either in the client, or in some middleware tier, executes Transactions only.在客户端或某些中间件层中的所有应用程序代码仅执行事务。 Still only by permitted Users仍然只由允许的Users

Otherwise, you do not have a database, you will have an unsecured data mess.否则,您没有数据库,您将拥有不安全的数据。 Refer to Open Architecture Standards .请参阅开放架构标准 (That is the simple definition, for public consumption.) (这是一个简单的定义,供公众消费。)


Problem • Application问题 • 应用

The simple example of Operation is a Bet which consist of several Pledges when you take some collateral from each participant.操作的简单示例是一个赌注,当您从每个参与者那里获取一些抵押品时,该赌注由多个质押组成。 Each participant even has different assets at stake and House can take many of them to satisfy some requirement.每个参与者甚至有不同的资产,House 可以使用其中的许多来满足某些要求。

These directions are based on implementing an Accounting System, with Double-Entry on every Accounting transaction, wherein no money (or asset) get lost, and any discrepancy can be easily traced ... which makes it Audit-able.这些方向基于实施会计系统,对每笔会计交易进行复式记账,其中不会丢失任何资金(或资产),并且可以轻松追踪任何差异......这使其可审计。

  1. Each betting person will have a separate external Account .每个投注人都会有一个单独的外部Account

  2. There will be an AssetType table that defines the different types of asset, what you call "collateral".将有一个AssetType表来定义不同类型的资产,您称之为“抵押品”。 Think in terms of "money" in different "currencies" (hence DEA is feasible).考虑不同“货币”中的“钱”(因此 DEA 是可行的)。

  3. The Account will be qualified by AssetType , giving the AccountAsset table. Account将通过AssetType进行限定,给出AccountAsset表。 AccountAsset (and not Account ) will be transacted against. AccountAsset (而不是Account )将被交易。 We are transacting assets per AccountAsset , not money, not the overall value in the Account .我们按AccountAsset交易资产,而不是金钱,而不是Account的整体价值。

  4. On the Ledger side, first there will be a Suspense or Pending Account.在 Ledger 方面,首先会有一个SuspensePending Account。

  5. Next, What you call a "state" is an entry in the Ledger under Suspense .接下来,您所说的“状态”是分类帐中Suspense下的一个条目。 But then, even your notion of "state" has to be tightened up to conform to the notion of a Suspense or Pending Account.但是,即使您的“状态”概念也必须收紧以符合暂记或待处理帐户的概念。 Therefore I cannot use your examples directly, I will give what I can determine (feel free to clarify or add more).因此我不能直接使用你的例子,我会给出我能确定的(随意澄清或添加更多)。 Tentatively, I will call this SuspenseState .暂时,我将其称为SuspenseState The Values are:这些值是:

    • Open Bet (pending, not closed)公开投注(待定,未关闭)

    • Insufficient Funds (Bet closed, asset not collected)资金不足(投注结束,资产未收回)

      • There is a further refinement, to ensure that that is prevented.有进一步的改进,以确保防止这种情况发生。 After the SuspenseStates have been correctly determined, and not before, this can be discussed.在正确确定SuspenseStates之后,而不是之前,可以讨论这一点。
  6. Next, under each SuspenseState , there will be one entry per AssetType .接下来,在每个SuspenseState ,每个AssetType将有一个条目。 These are LedgerAccounts , transacting against all external Accounts .这些是LedgerAccounts ,针对所有外部Accounts交易。 [4][5] are not transactional, they are aggregate LedgerIntermediates . [4][5] 不是事务性的,它们是聚合LedgerIntermediates

Your Data Model你的数据模型

Great graphic, by the way.顺便说一句,很棒的图形。 And thank you for expressing your question clearly, in data model (graphical) terms.感谢您以数据模型(图形)术语清楚地表达您的问题。

I have answered above per the requirements that I have quoted, which I understand somewhat.我已经根据我引用的要求回答了上面的问题,我对此有所了解。 I cannot see how that relates to the data model (requirement: collateral vs data model: lottery).我看不出这与数据模型有什么关系(要求:抵押品与数据模型:彩票)。 And I cannot make sense of what Operation is doing.我无法理解Operation正在做什么。 You are deeply into the how to do what you need, but we do not yet understand what we need.您已深入了解如何做您需要的事情,但我们还不了解我们需要什么 The order is, first define the what , then define the how to .顺序是,首先定义what ,然后定义how to

  1. Please explain in technical terms in English (edit your question), the Lottery & Trade (I understand that that is equivalent to transferring money between external bank Accounts ... but why the delay, why not immediate ?).请用英语(编辑您的问题),彩票和贸易(我知道这相当于在外部银行账户之间转账......但为什么延迟,为什么不立即?)用技术术语解释。

  2. Please explain what each of the "states" mean (one sentence identifying the action taken, and each side):请解释每个“状态”的含义(用一个句子标识所采取的行动,以及每一方):

    • AAA: New; AAA:新; Completed;完全的; Cancelled取消

    • BBB: Pending; BBB:待定; Conflict;冲突; Resolved解决

    • CCC: New; CCC:新; Complete;完全的; Rollback 回滚

  3. Why does your model not have "collateral" types ( my AssetType ) ?为什么您的模型没有“抵押品”类型( my AssetType )?

  4. Caveat.警告。 Stamping an ID field on every file will severely cripple the modelling exercise.在每个文件上标记ID字段将严重削弱建模练习。 Why ?为什么 ? Because you are assuming that the file is correct, but it is not.因为您假设文件是​​正确的,但事实并非如此。 You are fixing the "entity", and the "entity" has not been modelled yet.您正在修复“实体”,而“实体”尚未建模。 The purpose of modelling is to model the data, only the data, and nothing but the data (the ID field is not data, but an addition) ... such that the "entities" are exposed, distilled, determined.建模的目的是对数据进行建模,只对数据进行建模,而仅对数据进行建模( ID字段不是数据,而是一个附加项)……这样“实体”就被暴露、提炼、确定了。

    Therefore, in order to do some genuine data modelling, remove the ID fields.因此,为了做一些真正的数据建模,删除ID字段。 Which means, you have to choose a logical Identifier for each corrected file, which action will elevate it to the status of a table.这意味着,您必须为每个更正的文件选择一个逻辑标识符,该操作会将其提升为表的状态。 The Relational Model demands that the Key is "made up from the data".关系模型要求密钥“由数据组成”。

    If ID fields remain, there are further caveats, which I won't detail, because if they are removed, the caveats too, will disappear.如果ID字段仍然存在,还有更多的警告,我不会详细说明,因为如果删除它们,警告也会消失。 (These are common problems. If interested, you can read some of my other Answers, wherein I detail each problem and give the solution.) (这些都是常见的问题,有兴趣的可以看我其他的一些回答,我详细介绍了每个问题并给出了解决方案。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM