Double Entry Accounting Schema

9

Einrichtung eines doppelten Buchführungssystems für den persönlichen Gebrauch und zur Verwaltung eines wirklich kleinen Unternehmens. Ich versuche ein paar Funktionen zu platzieren, die jetzt relevant erscheinen.

Geschäftsregeln

Die Logik für diejenigen, die mit der Buchhaltung nicht vertraut sind, lautet: Geld wird weder geschaffen noch zerstört, es wird nur von einem Konto auf ein anderes übertragen. Jede Transaktion hat eine Debit- und eine Credit-Seite. Einige Beispiele:

  1. Gehalt von Ihrem Arbeitgeber: Kredit Salary, Lastschrift Bank Account- das Geld kam von Ihrem Gehalt und ging auf Ihr Bankkonto.

  2. Mietzahlung: Gutschrift Bank Account, Lastschrift Rent- das Geld kam von Ihrem Bankkonto und ging auf Ihr Mietkonto.

Konten können Aktienkonten sein, in dem Sinne, dass der Kontostand kumulativ ist (Bankkonten sind ein gutes Beispiel), oder Fluss- / Flusskonten sein, in dem Sinne, dass der Kontostand nicht kumulativ ist (Miete ist ein gutes Beispiel).

Die Logik hinter dem Design

Die Idee ist, eine JournalDBHaupttabelle zu haben, in der die Haupteinträge gespeichert sind. In der Tabelle wird JournalTxjedes an der Transaktion beteiligte Konto gespeichert. Jeder Eintrag (von JournalDB) hat eine ID, und jede Transaktion (von JournalTx) ist mit einem Journaleintrag verknüpft. Das Basisszenario besteht darin, dass 1 Eintrag JournalDBund zwei (oder mehr) Transaktionen vorhanden sind JournalTx. Jeder Eintrag kann ein cost_center, ein projectund einige andere Attribute haben.

Grundsätzlich gibt es zwei Möglichkeiten, dies zu entwerfen (gemäß dieser Frage ) - als eine Zeile pro Transaktionsstil und als zwei Zeilen pro Transaktion. In der ersten hätte ich eine Zeile mit dem Kreditkonto und dem Debitkonto, in der zweiten (dieser) gibt es n Zeilen, eine für jedes betroffene Konto.

Konten

Die Konten-Tabelle ist der Kontenplan (in der Fachsprache des Buchhalters). Is hat eine hierarchische Struktur - ich habe den Adjazenzlistenstil verwendet. Obwohl nicht sehr häufig, haben Konten CRUD-Operationen. Ich fügte hinzu parent_imediate, parent_secondals eine wirklich hässliche Lösung, um Aggregationen zu erstellen (z. B. die Summe des Assets-Kontos berechnen), aber angesichts der Herausforderung (keine Ahnung, wie man das nach langer Recherche macht) schien es ein einfacher Ausweg zu sein - Jede Eingabe oder Anregung zu diesem Thema ist ebenfalls willkommen.

Hauptabfragen

Holen Sie sich die Berichte, in der Regel montlhy: Grundsätzlich alle Konten mit den aggregierten Transaktionen, die jeweils betroffen waren. Das beste Szenario wäre eine Pivot-Tabelle (Spalten als Datumsangaben), wobei jede Zeile ein Konto ist. Ich denke, eine "gestapelte" Version davon würde auch gut funktionieren.

Konten sind nur eine Dimension - ich möchte zum Beispiel nach cost_centeroder nach abfragen project.

Andere Eigenschaften

Ich möchte die Möglichkeit haben, Konten zu budgetieren (daher die Budget-Tabelle) sowie 'Ziele' zu haben (ich möchte Urlaub machen, der mich 1.000 US-Dollar kostet). Ich möchte auch Tags haben und wiederkehrende Rechnungen einrichten können (die "erwartete" Transaktionen sind).

Grundlegende Beziehungen

Ein Eintrag (journal_db) hat viele Transaktionen (journal_tx). Ein cost_center, ein Projekt usw. hat viele Einträge. Ein Konto hat viele Transaktionen. Ein Kontakt hat viele Einträge.

Geben Sie hier die Bildbeschreibung ein

Meine Hauptzweifel

Ich fange gerade erst an, etwas über DB / Programmierung zu lernen. Nehmen Sie also offensichtliche Fehler mit.

  1. Ist dieses Design aus Sicht der Programmierung / Leistung / Funktion solide?
  2. Wie implementiere ich die Berichterstellung? Abfragen der Datenbank (abgeleitete Tabelle) oder Erstellen einer neuen Tabelle (wie journal_reports) und Erstellen von Triggern zum Aktualisieren des Kontostands für jeden Eintrag? (Lesen Sie in dieser Frage, dass das keine so gute Idee ist)
  3. Was könnte mir fehlen?
Kleinbuchstaben00
quelle
Ich kann die Leistung nicht diskutieren, ohne die Abfragen zu sehen. Und zu wissen, wie groß der größte Tisch sein wird.
Rick James
Vielen Dank. Leistung ist im Moment wahrscheinlich meine letzte Sorge. Es sollte nicht zu groß sein, vielleicht ungefähr 15-20k Zeilen für die größte Tabelle ... Ich sollte so ziemlich alle Tabellen abfragen, die meisten Abfragen sollten 2 oder mehr Tabellen zusammenfügen, aber ich habe keine der Tabellen geschrieben Fragen noch ..
Kleinbuchstaben00

Antworten:

1

Ich denke, Ihre Frage ist ziemlich weit gefasst und in ihrer Gesamtheit schwer zu beantworten. Aber hier sind einige Dinge, die mir an Ihrem Design aufgefallen sind:

Allgemeines Design

Einige Tabellen in Ihrem Design verletzen die erste normale Form. Ein gutes Beispiel ist contact_adressdie hat adress1, adress2und adress3als Spalten. Normalerweise hat ein Ort nur eine Adresse und dann reicht eine Adressenspalte aus. Wenn Sie jedoch wirklich mehrere Straßenadressen zu einem Ort hinzufügen möchten, sollten Sie diese Adressen in eine andere Tabelle verschieben ( contact_adress, street_adress). Das gleiche gilt für journal_bills( detail1, detail2) und der accountsTisch: Statt parent_imediate, parent_secondund parent_thirdein einziges parentAttribut soll genug sein. Um das zweite oder dritte übergeordnete Element zu erhalten, können Sie stattdessen rekursive CTEs verwenden.

Ich kenne nicht alle Ihre Geschäftsanforderungen, aber Sie sollten prüfen, ob Ihr Design die Eingabe unsinniger Daten ermöglicht: Kann ein Konto sowohl Bargeld als auch Guthaben sein? Wenn Sie Währungen haben, wie hoch sind die Wechselkurse? Kann eine Postleitzahl mit einer oder mehreren Nullen beginnen? Was ist mit den Telefonnummern? Für einige Dinge gibt es Best Practices, z. B. den Umgang mit wiederkehrenden Ereignissen .

Benennung

Einige Spaltennamen schwer zu verstehen sind ( ag, acc, pmt), die Wartbarkeit Problemen führen kann , wenn jemand anderes die Arbeit mit der Datenbank hat. Verwenden Sie einen Styleguide, wenn Sie sich nicht sicher sind, wie Sie die Dinge benennen sollen. Im Allgemeinen ist es eine gute Idee, sich an ein einheitliches Namensschema zu halten, z. B. jeder Tabelle einen Pluralnamen zu geben.

Wie implementiere ich die Berichterstellung?

Ich würde mich an einfache SQL-Abfragen halten und versuchen, mich von anspruchsvollen Funktionen wie Triggern fernzuhalten, es sei denn, Sie müssen dies wirklich tun, was bei einer einfachen Anwendung wahrscheinlich nie der Fall ist.

Taffer
quelle
Vielen Dank für Ihre Beiträge. Für Teile: Ich habe mich entschieden, mich zu trennen, um Straßennamen, Straßennummer, Wohnungsnummer und alles zu haben, aber die Namen machen es verwirrend, guter Punkt. Ich werde versuchen, das Design zu verbessern, um es detaillierter zu gestalten. In Bezug auf die Geschäftsanforderungen mache ich Validierungen für Code, da einige auf der DB-Ebene etwas zu komplex erscheinen. Rekursive CTEs scheinen eine großartige Option zu sein. Ich werde sie etwas genauer untersuchen, um zu sehen, ob ich sie implementieren kann. Was die Benennung betrifft - Sie haben Recht, ich hätte sie auch für Dritte besser lesbar machen sollen, um sie zu verstehen. Ich werde versuchen, sie zu verbessern.
Kleinbuchstaben00