webentwicklung-frage-antwort-db.com.de

Datenbankentwurf: Berechnung des Kontostands

Wie gestalte ich die Datenbank, um den Kontostand zu berechnen?

1) Zur Zeit 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 ausrechnen.


Ich habe dies meinem Freund gezeigt und er sagte, das ist keine gute Lösung, wenn meine Datenbank wächst, wird es langsamer ???? Er sagte, ich sollte eine separate Tabelle erstellen, um den berechneten Kontostand zu speichern. Wenn dies der Fall ist, muss ich zwei Tabellen führen, und es ist riskant, dass die Kontostandtabelle nicht mehr synchron ist.

Irgendein Vorschlag?

EDIT: OPTION 2: Sollte ich zu meinen Transaktionstabellen "Saldo" ..__ eine zusätzliche Spalte hinzufügen?.

Beispiel John kauft einen Kredit von 100 $, er schuldet 60 $, dann addiert er 200 $.

Betrag 100 $, Restbetrag 100 $.

Betrag - 60 USD, Restbetrag 40 USD.

Betrag $ 200, Restbetrag $ 240.

56
001

Ein uraltes Problem, das niemals elegant gelöst wurde.

Alle Bankpakete, mit denen ich gearbeitet habe, speichern den Kontostand bei der Kontoeinheit. Es ist undenkbar, es aus der Bewegungshistorie zu berechnen.

Der richtige Weg ist:

  • Die Bewegungstabelle hat für jedes Konto eine "Eröffnungsbilanz". Dies wird in einigen Jahren erforderlich sein, wenn Sie alte Bewegungen aus der aktiven Bewegungstabelle in eine Verlaufstabelle verschieben müssen.
  • Die Kontoentität verfügt über ein Saldofeld .__
  • Es gibt einen Auslöser in der Bewegungstabelle , Der die Konto-Salden für die gutgeschriebenen und belasteten Konten aktualisiert. Offensichtlich hat es die Kontrolle. Wenn Sie keinen Auslöser haben können, muss ein unique - Modul vorhanden sein, das Bewegungen unter Commit Control schreibt 
  • Sie haben ein "Sicherheitsnetz" -Programm, mit dem Sie Offline laufen können, das alle Waagen neu berechnet Alle Waagen neu berechnet und (und Korrigiert optional) fehlerhafte Waagen. Dies ist sehr nützlich für das Testen von

Einige Systeme speichern alle Bewegungen als positive Zahlen und drücken die Gutschrift/Abbuchung aus, indem sie die Von/Bis-Felder oder ein Flag setzen. Ich persönlich bevorzuge ein Kreditfeld, ein Lastschriftfeld und einen unterzeichneten Betrag. Dies macht es einfacher, Stornierungen zu verfolgen.

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 einzige Transaktion abwickeln, bei der ein oder mehrere Kassenbestände von Käufern und Verkäufern, deren Wertpapierbestände und möglicherweise der Broker/die Verwahrstelle aktualisiert werden.

55
smirkingman

Sie sollten den aktuellen Kontostand speichern und jederzeit auf dem neuesten Stand halten. Die Transaktionstabelle ist nur eine Aufzeichnung der Vorgänge in der Vergangenheit und sollte nicht häufig verwendet werden, um den aktuellen Kontostand abzurufen. Bedenken Sie, dass viele Abfragen nicht nur ein Gleichgewicht wünschen, sondern sie auch filtern, sortieren und gruppieren möchten. Der Performance-Nachteil des Summierens jeder Transaktion, die Sie je in komplexen Abfragen erstellt haben, würde selbst eine Datenbank von bescheidener Größe lähmen .

Alle Aktualisierungen für dieses Tabellenpaar sollten sich in einer Transaktion befinden und sollten sicherstellen, dass entweder alles synchron bleibt (und das Konto niemals sein Limit überschreitet) oder die Transaktion rückgängig gemacht wird. Als zusätzliche Maßnahme können Sie Prüfabfragen ausführen, die dies regelmäßig überprüfen.

3
Marcelo Cantos

Eine übliche Lösung für dieses Problem besteht darin, einen monatlichen Eröffnungssaldo in einem Snapshot-Schema zu halten. 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 Währungsumrechnung und Neubewertungen haben.

Wenn Sie Probleme mit dem Datenvolumen haben, können Sie die älteren Waagen archivieren.

Die Salden können auch für die Berichterstellung hilfreich sein, wenn Sie kein dediziertes externes Data Warehouse oder keine Managementberichterstellungsfunktion im System haben.

Natürlich müssen Sie Ihren aktuellen Kontostand in jeder Zeile speichern, sonst ist er zu langsam. Um die Entwicklung zu vereinfachen, können Sie Einschränkungen verwenden, so dass Sie keine Auslöser und regelmäßige Überprüfungen der Datenintegrität benötigen. Ich habe es hier beschrieben Denormalisieren, um Geschäftsregeln durchzusetzen: Laufende Summen

1
A-K

Dies ist ein Datenbankentwurf, den ich mit nur einer Tabelle zum Speichern einer Historie von Vorgängen/Transaktionen erhalten habe. Derzeit arbeitet man an vielen kleinen Projekten als Charme.

Dies ersetzt kein bestimmtes Design. Dies ist eine generische Lösung, die für die meisten Apps geeignet ist.

id : int Standard-Zeilen-ID

operation_type : int Vorgangstyp. zahlen, sammeln, verzinsen usw

quellentyp : int von wo die Operation abläuft . 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 : Dezimalzahl (19,2 signiert) Preiswert positiv oder negativ bis summiert

account_balance : dezimal (19,2 signiert) daraus resultierendes Gleichgewicht

extra_value_a : dezimal (19,2 signiert) [Dies war die vielseitigste Option, ohne Stringspeicher zu verwenden. Sie können eine zusätzliche Zahl speichern: Zinssatz, Rabatt, Ermäßigung usw.

created_at : Zeitstempel

Für source_type und target_type ist es besser, ein Enum oder Tabellen-Appart zu verwenden.

Wenn Sie einen bestimmten Kontostand wünschen, können Sie einfach die letzte Operation abfragen, die nach create_at absteigend nach 1 sortiert ist.

Für eine bessere Leistung wird empfohlen, den aktuellen Kontostand im erforderlichen Zielobjekt zu speichern.

1
Heroselohim

Mein Ansatz ist es, die Lastschriften in einer Lastschriftspalte zu speichern, die Gutschrift in der Gutschriftspalte zu speichern und beim Abrufen der Daten zwei Arrays, Lastschrift und Kreditarray zu erstellen. Hängen Sie dann die ausgewählten Daten an das Array an und führen Sie dies für Python aus:

def real_insert(arr, index, value):
    try:
        arr[index] = value
    except IndexError:
        arr.insert(index, value)


def add_array(args=[], index=0):
    total = 0
    if index:
        for a in args[: index]:
            total += a
    else:
        for a in args:
            total += a
    return total

dann 

for n in range(0, len(array), 1):
    self.store.clear()
    self.store.append([str(array[n][4])])
    real_insert(self.row_id, n, array[n][0])
    real_insert(self.debit_array, n, array[n][7])
    real_insert(self.credit_array, n, array[n][8])
    if self.category in ["Assets", "Expenses"]:
        balance = add_array(self.debit_array) - add_array(self.credit_array)
    else:
        balance = add_array(self.credit_array) - add_array(self.debit_array)
0
kafeero

Ihr Freund hat Unrecht und Sie haben Recht, und ich würde Ihnen raten, die Dinge jetzt nicht zu ändern.
Wenn Ihre Datenbank aufgrund dessen langsam wird und Sie den Rest (korrekte Indexierung) überprüft haben, kann eine Denormalisierung von Nutzen sein.
Sie könnten dann ein BalanceAtStartOfYear-Feld in die Konten-Tabelle einfügen und nur die Datensätze dieses Jahres (oder einen ähnlichen Ansatz) zusammenfassen.
Aber ich würde diesen Ansatz sicherlich nicht im Vorfeld empfehlen. 

0
Patrick Honorez

Hier möchten wir Ihnen vorschlagen, wie Sie Ihr Eröffnungsguthaben auf eine sehr einfache Art und Weise speichern können: -

  1. Erstellen Sie eine Triggerfunktion für die Transaktionstabelle, die nur nach dem Aktualisieren oder Einfügen aufgerufen werden soll.

  2. Erstellen Sie eine Spalte mit Namen in der Haupttabelle der Kontennamen Eröffnungsbilanz.

  3. speichern Sie Ihren Eröffnungssaldo in Array in der Eröffnungssaldo-Spalte in der Master-Tabelle.

  4. sie müssen auch keine serverseitige Sprache verwenden. Verwenden Sie dieses Store-Array. Sie können einfach Datenbank-Array-Funktionen wie in PostgreSQL verwenden.

  5. wenn Sie den Eröffnungssaldo im Array neu berechnen möchten, gruppieren Sie Ihre Transaktionstabelle einfach mit der Array-Funktion und aktualisieren Sie die gesamten Daten in der Haupttabelle.

Ich habe dies in PostgreSQL gemacht und funktioniert gut.

Über den Zeitraum, in dem Ihre Transaktionstabelle stark wird, können Sie Ihre Transaktionstabelle auf der Basis des Datums partitionieren, um die Leistung zu beschleunigen. Dieser Ansatz ist sehr einfach und muss nicht mit zusätzlichen Tabellen verwendet werden, die langsamer werden können Leistung beim Verbinden von Tisch, weil weniger Tisch beim Fügen eine hohe Leistung bringt.

0
Ranjeet