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:
Gehalt von Ihrem Arbeitgeber: Kredit
Salary
, LastschriftBank Account
- das Geld kam von Ihrem Gehalt und ging auf Ihr Bankkonto.Mietzahlung: Gutschrift
Bank Account
, LastschriftRent
- 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 JournalDB
Haupttabelle zu haben, in der die Haupteinträge gespeichert sind. In der Tabelle wird JournalTx
jedes 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 JournalDB
und zwei (oder mehr) Transaktionen vorhanden sind JournalTx
. Jeder Eintrag kann ein cost_center
, ein project
und 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_second
als 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_center
oder 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.
Meine Hauptzweifel
Ich fange gerade erst an, etwas über DB / Programmierung zu lernen. Nehmen Sie also offensichtliche Fehler mit.
- Ist dieses Design aus Sicht der Programmierung / Leistung / Funktion solide?
- 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)
- Was könnte mir fehlen?
quelle
Antworten:
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_adress
die hatadress1
,adress2
undadress3
als 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ürjournal_bills
(detail1
,detail2
) und deraccounts
Tisch: Stattparent_imediate
,parent_second
undparent_third
ein einzigesparent
Attribut 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.
quelle