Wie gestalte ich die Datenbank, um den Kontostand zu berechnen?
1) Derzeit berechne ich den Kontostand aus der Transaktionstabelle. In meiner Transaktionstabelle habe ich "Beschreibung" und "Betrag" usw.
Ich würde dann alle "Betrag" -Werte addieren und das würde den Kontostand des Benutzers berechnen.
Ich habe dies meinem Freund gezeigt und er sagte, dass dies keine gute Lösung ist, wenn meine Datenbank wächst, wird sie langsamer ???? Er sagte, ich sollte eine separate Tabelle erstellen, um den berechneten Kontostand zu speichern. In diesem Fall muss ich zwei Tabellen pflegen, und es ist riskant, dass die Kontostandstabelle nicht mehr synchron ist.
Irgendein Vorschlag?
EDIT : OPTION 2: Sollte ich meiner Transaktionstabelle "Balance" eine zusätzliche Spalte hinzufügen? Jetzt muss ich nicht mehr viele Datenzeilen durchgehen, um meine Berechnung durchzuführen.
Beispiel John kauft einen Kredit von 100 USD, er verschuldet 60 USD und fügt dann einen Kredit von 200 USD hinzu.
Betrag 100 $, Restbetrag 100 $.
Betrag - 60 USD, Restbetrag 40 USD.
Betrag $ 200, Restbetrag $ 240.
Antworten:
Ein uraltes Problem, das nie elegant gelöst wurde.
Alle Bankpakete, mit denen ich gearbeitet habe, speichern den Kontostand bei der Konteneinheit. Eine schnelle Berechnung aus dem Bewegungsverlauf ist undenkbar.
Der richtige Weg ist:
Einige Systeme speichern alle Bewegungen als positive Zahlen und drücken die Gutschrift / Lastschrift durch Invertieren der Felder von / nach oder mit einem Flag aus. Persönlich bevorzuge ich ein Kreditfeld, ein Lastschriftfeld und einen signierten Betrag. Dies erleichtert die Nachverfolgung erheblich.
Beachten Sie, dass diese Methoden sowohl für Bargeld als auch für Wertpapiere gelten.
Wertpapiertransaktionen können sehr viel schwieriger sein, insbesondere bei Kapitalmaßnahmen. Sie müssen eine einzelne Transaktion durchführen, bei der ein oder mehrere Kassenguthaben von Käufern und Verkäufern, ihre Sicherheitsguthaben und möglicherweise der Broker / Verwahrer aktualisiert werden.
quelle
Sie sollten den aktuellen Kontostand speichern und jederzeit auf dem neuesten Stand halten. Die Transaktionstabelle ist nur eine Aufzeichnung dessen, was in der Vergangenheit passiert ist, und sollte nicht mit hoher Häufigkeit verwendet werden, um nur den aktuellen Kontostand abzurufen. Bedenken Sie, dass viele Abfragen nicht nur Salden wünschen, sondern auch nach ihnen filtern, sortieren und gruppieren möchten usw. Der Leistungsverlust beim Summieren jeder Transaktion, die Sie jemals inmitten komplexer Abfragen erstellt haben, würde sogar eine Datenbank von bescheidener Größe lahm legen .
Alle Aktualisierungen dieses Tabellenpaars sollten sich in einer Transaktion befinden und sicherstellen, dass entweder alles synchron bleibt (und das Konto niemals über sein Limit hinaus gezogen wird) oder die Transaktion zurückgesetzt wird. Als zusätzliche Maßnahme können Sie Überwachungsabfragen ausführen, die dies regelmäßig überprüfen.
quelle
Dies ist ein Datenbankdesign, das ich mit nur einer Tabelle zum Speichern einer Historie von Operationen / Transaktionen erhalten habe. Derzeit arbeitet er als Charme an vielen kleinen Projekten.
Dies ersetzt kein bestimmtes Design. Dies ist eine generische Lösung, die für die meisten Apps geeignet ist.
id : int Standardzeilen-ID
Operationstyp : int Operationstyp. zahlen, sammeln, verzinsen usw.
source_type : int, von wo aus die Operation fortgesetzt wird . Zieltabelle oder -kategorie: Benutzer, Bank, Anbieter usw.
source_id : int id der Quelle in der Datenbank
Zieltyp : int, auf was die Operation angewendet wird. Zieltabelle oder Kategorie: Benutzer, Bank, Anbieter usw.
target_id : int id des Ziels in der Datenbank
Betrag : Dezimal (19,2 signiert) Preiswert positiv oder negativ bis summiert
account_balance : Dezimal (19,2 signiert) resultierender Saldo
extra_value_a : decimal (19,2 signiert) [dies war die vielseitigste Option ohne Verwendung des String-Speichers] Sie können eine zusätzliche Zahl speichern: Zinsprozentsatz, Rabatt, Ermäßigung usw.
created_at : Zeitstempel
Für den Quelltyp und den Zieltyp ist es besser, eine Aufzählung oder ein Tabellen-Appart zu verwenden.
Wenn Sie einen bestimmten Kontostand wünschen, können Sie einfach die letzte Operation abfragen, sortiert nach dem absteigenden Grenzwert von created_at auf 1. Sie können nach Quelle, Ziel, Operationstyp usw. abfragen.
Für eine bessere Leistung wird empfohlen, den aktuellen Kontostand im erforderlichen Zielobjekt zu speichern.
quelle
Eine übliche Lösung für dieses Problem besteht darin, ein (etwa) monatliches Eröffnungsguthaben in einem Snapshot-Schema beizubehalten. Die Berechnung des aktuellen Kontostands kann durch Hinzufügen von Transaktionsdaten für den Monat zum monatlichen Eröffnungssaldo erfolgen. Dieser Ansatz wird häufig in Kontopaketen verwendet, insbesondere wenn Sie möglicherweise Währungsumrechnungen und Neubewertungen vornehmen.
Wenn Sie Probleme mit dem Datenvolumen haben, können Sie die älteren Salden archivieren.
Die Salden können auch für die Berichterstellung hilfreich sein, wenn Sie kein dediziertes externes Data Warehouse oder keine Management-Berichtsfunktion im System haben.
quelle
Natürlich müssen Sie Ihr aktuelles Guthaben in jeder Zeile speichern, sonst ist es zu langsam. Um die Entwicklung zu vereinfachen, können Sie Einschränkungen verwenden, sodass Sie keine Auslöser und regelmäßigen Überprüfungen der Datenintegrität benötigen. Ich habe es hier beschrieben. Denormalisieren, um Geschäftsregeln durchzusetzen: Ausführen von Summen
quelle
Ihr Freund liegt falsch und Sie haben Recht, und ich würde Ihnen raten, die Dinge jetzt nicht zu ändern.
Wenn Ihre Datenbank aus diesem Grund jemals langsam wird und Sie den Rest überprüft haben (ordnungsgemäße Indizierung), kann eine gewisse Denormalisierung hilfreich sein.
Sie können dann ein BalanceAtStartOfYear-Feld in die Konten-Tabelle einfügen und nur die diesjährigen Datensätze (oder einen ähnlichen Ansatz) zusammenfassen.
Aber ich würde diesen Ansatz sicherlich nicht im Voraus empfehlen.
quelle
Hier möchten wir Ihnen vorschlagen, wie Sie Ihr Eröffnungsguthaben auf sehr einfache Weise speichern können:
Erstellen Sie eine Triggerfunktion für die Transaktionstabelle, die erst nach dem Aktualisieren oder Einfügen aufgerufen werden soll.
Erstellen Sie eine Spalte mit Namen in der Haupttabelle des Kontonamens Eröffnungssaldo.
Speichern Sie Ihren Eröffnungssaldo im Array in der Spalte Eröffnungssaldo in der Mastertabelle.
Sie müssen nicht einmal die serverseitige Sprache verwenden. Verwenden Sie dieses Speicherarray. Sie können einfach Datenbankarrayfunktionen verwenden, wie sie in PostgreSQL verfügbar sind.
Wenn Sie den Eröffnungssaldo im Array neu berechnen möchten, gruppieren Sie einfach Ihre Transaktionstabelle mit der Array-Funktion und aktualisieren Sie die gesamten Daten in der Mastertabelle.
Ich habe dies in PostgreSQL getan und funktioniert gut.
Während des Zeitraums, in dem Ihre Transaktionstabelle schwer wird, können Sie Ihre Transaktionstabelle anhand des Datums partitionieren, um die Leistung zu beschleunigen. Dieser Ansatz ist sehr einfach und es muss keine zusätzliche Tabelle verwendet werden, die die Leistung beim Verbinden von Tabellen beeinträchtigen kann, da eine geringere Tabelle beim Verbinden eine hohe Leistung bietet.
quelle
Mein Ansatz besteht darin, die Belastungen in einer Belastungsspalte und das Guthaben in der Guthabenspalte zu speichern und beim Abrufen der Daten zwei Arrays zu erstellen, das Belastungs- und das Guthabenarray. Hängen Sie dann die ausgewählten Daten weiter an das Array an und führen Sie dies für Python aus:
dann
quelle
Einfache Antwort: Mach alle drei.
Speichern Sie den aktuellen Kontostand. und in jeder Transaktion die Bewegung und eine Momentaufnahme des aktuellen Kontostands zu diesem Zeitpunkt speichern. Dies würde etwas Besonderes geben , das bei jeder Prüfung in Einklang gebracht werden kann.
Ich habe noch nie an Kernbankensystemen gearbeitet, aber ich habe an Anlageverwaltungssystemen gearbeitet, und meiner Erfahrung nach ist dies so.
quelle