2009-08-17 2 views
4

Meine erste Frage hier, also sei nett!Verwenden eines natürlichen Schlüssels oder Verwenden von Ersatzschlüsseln und Audit-Tabelle (n) für Auditing/Änderungsprotokoll

Ich bin ein Junior-Entwickler mit nicht viel Erfahrung und habe Probleme mit diesem Problem.

Ich habe eine Tabelle, die auditierbar sein muss. Nehmen wir an, diese Tabelle zeichnet Telefonanrufe auf, die von einem Call-Center getätigt wurden (das ist es nicht, aber es ist nur ein Beispiel). Ich werde es "CallHistory" nennen.

Ich hatte ursprünglich geplant, eine separate Tabelle namens "Callees" zu führen, die den Namen, die Telefonnummer usw. der Anrufer hat. Diese Tabelle würde einen Ersatz-Primärschlüssel verwenden.

Die CallHistory-Tabelle hätte einen Fremdschlüssel für die Callee-Tabelle.

Ich tat ursprünglich dies, so dass, wenn ich die Telefonnummer eines Anrufers änderte, es im ganzen System propagieren würde und ich die Telefonnummer in mehreren Tabellen nicht ändern müsste.

Das Problem ist, der ganze Punkt der CallHistory-Tabelle ist die Aufzeichnung der Geschichte von Anrufen, einschließlich falsch gewählte Anrufe (sagen, ein Anrufer wählte die falsche Nummer). Die Geschichte würde mit diesem Ersatzschlüssel-Ansatz verloren gehen.

Einer der leitenden Entwickler bei der Arbeit schlug vor, Kopien der Telefonnummer für jedes Wählen eines Anrufers zu diesem bestimmten Zeitpunkt in der CallHistory-Tabelle zu behalten, um den Verlauf zu bewahren.

Ich dachte darüber nach, eine Audit/Change Log-Tabelle für den gleichen Zweck zu halten.

Würde mein Ansatz für diese purposeose ausreichen oder bin ich total vom Weg abgekommen? Welchen Ansatz bevorzugen Sie?

Cheers, Andrew

Antwort

1

Ich stimme Rik. Ja, redundante Daten sind sehr, sehr schlecht, böse, stinkend und ansonsten unerwünscht. Aber nur weil zwei Felder "Telefonnummer" genannt werden, machen sie nicht dasselbe. "Die aktuelle Telefonnummer des Kunden" und "Die Telefonnummer des Kunden zu dem Zeitpunkt, als wir das letzte Mal mit ihm gesprochen haben" sind nicht unbedingt identisch.

Ich arbeite derzeit mit einer Datenbank, die Verkauf und Artikelinformationen hält. Ein Artikeldatensatz enthält Informationen wie Beschreibung, Lagernummer und Preis. Unsere Verkaufsunterlagen enthalten auch Beschreibung, Lagerbestand und Preis. Beschreibung und Lagernummer sind redundant und sollten eliminiert werden. Das war ein schlechtes Design. Aber der Preis muss an beiden Orten enthalten sein. Es gibt einen großen Unterschied zwischen dem aktuellen Preis und dem Preis zum Zeitpunkt eines bestimmten Verkaufs. Dieser Verkauf hätte vor Jahren sein können. Der Preis hat sich seitdem vielleicht ein Dutzend Mal geändert.

Im Allgemeinen in einer Anwendung wie Sie beschreiben würde ich nur Telefonnummer in die Verlaufstabelle und damit fertig sein. Es ist wenig zu gewinnen, wenn man eine "Telefonnummernhistorie" -Tabelle hat und mit dem jeweiligen Telefonnummerneintrag verknüpft ist. Es könnte ein paar Bytes pro Datensatz speichern, aber es würde eine Menge Komplexität hinzufügen. Wenn es jedoch mehrere verwandte Felder gibt, ändert sich die Geschichte. Wenn, sagen wir - und ich erfinde nur ein Beispiel hier, um die Idee zu geben - Sie sind eine Krankenkasse und Ihre Versicherungsbedingungen variieren je nach Standort aufgrund unterschiedlicher Landesgesetze, verfügbarer Ärzte in der Region, etc, Wenn ein Kunde umzieht, muss seine Richtlinie neu geschrieben werden. Jetzt kann die Telefonnummer mit vielen anderen Datenelementen in Beziehung stehen. Daher sollten alle in eine einzelne Tabelle und mit dem entsprechenden Datensatz verknüpft werden. Sonst könnten Sie eine New Jersey Telefonnummer haben, aber Sie sind mit Kalifornien Politik Begriffe usw.

verknüpfen
1

Ihre Frage ist sehr typisches Design Dilemma. Zum Beispiel, wenn Sie eine Datenbank in normaler Form haben und Sie die folgenden Tabellen haben: Verkauf, Manager (wer verkauft) und Regionen (wo Manager arbeiten). Sie erstellen Berichte wie "Jährliche Verkäufe nach Regionen gruppiert", in denen Sie sich mit Verkäufern und Managern mit Regionen in den Vertrieb einklinken. Aber wenn einer der Manager im Laufe des Jahres in ein anderes Büro umzieht, scheint Ihr Bericht falsche Daten zu enthalten, oder?

Was sind 3 Lösungen

1) In einigen Fällen Entwickler und Analytiker entscheiden: gut, unsere Daten nicht sehr korrekt ist, aber es ist jetzt OK, wollen wir mit der normalen Form bleiben und keine Daten duplizieren. Diese Lösung ist weniger komplex. In diesem Fall können Sie Caller und CallHistory-Tabellen in normaler Form erstellen, d. H. Die Telefonnummer befindet sich nur in der Anrufer-Tabelle.

2) Es besteht die Anforderung, keine historischen Änderungen zu verlieren. Und wir möchten, dass unsere Berichte und Abfragen sehr schnell sind (auf Kosten der Datenbankgröße). In diesem Fall entscheiden sich die Leute, alle Felder zu duplizieren. Beispielsweise können Sie eine CallHistory-Tabelle erstellen, die Telefonnummer, Anrufername, Adresse usw. enthält, da Sie davon ausgehen, dass jedes dieser Felder in Zukunft geändert werden kann. Natürlich können Sie auch die Callee-Tabelle erstellen (wahrscheinlich werden Sie sie für andere Zwecke benötigen), aber sie kann von CallHistory erneut eingefangen werden und ist es möglicherweise nicht. Angenommen, Sie denken, dass einige Datensätze aus Callee gelöscht werden müssen, sie aber in CallHistory sein sollen. Dies ist der Fall, wenn Entwickler häufig denken, dass sie die referenzielle Integrität der Daten verletzen können. Erstellen Sie keine Fremdschlüssel aus der CallHistory-Tabelle. Und das ist vernünftig, denn ohne Fremdschlüssel arbeiten Einsätze schneller.

3) Ansatz Ich mag mehr, aber es ist am komplexesten aus Sicht der Implementierung: CallHistory Tabelle sollte auf CalleHistory-Tabelle verweisen. Die CalleeHistory-Tabelle enthält alle Dateien, die die Callee-Tabelle enthält, aber sie hat auch einen Ersatzschlüssel, wie CalleID + DateModified (manchmal verwenden DateModified-Entwickler ModificationVersionNumber). In CallHistory haben wir einen Ersatz-Fremdschlüssel, der auf CalleID + DateModified verweist. In diesem Fall haben Sie normalisierte Daten (d. H. Telefonnummer ist nicht in verschiedenen Tabellen veröffentlicht), und Sie haben auch keine historischen Änderungen verloren.

Soweit ich sagte, gibt es oft einen Kompromiss zwischen Komplexität der Implementierung, Datenbankleistung, Datenbankgröße, Datenintegrität und funktionalen Anforderungen an das System. Wenn Sie ein Junior-Entwickler sind, ist es nett, alle möglichen Lösungen im Auge zu behalten, aber wahrscheinlich sollten Sie einem Senior-Entwickler zuhören, der mehr über Ihr System und Ihre Anforderungen weiß als jeder andere auf Stack Overflow.

p.s.

Wenn Sie über andere Ansätze wissen, lesen Sie hier die Normalformen über etwa langsam veränderliche Dimensionen, zum Beispiel http://en.wikipedia.org/wiki/Slowly_changing_dimension

2

Ich glaube, Sie durch eine Subtilität verleitet sind zu werden. Die Sache ist, die Telefonnummer mit dem Angerufenen verbunden ist nicht das gleiche Stück der Information als die Nummer vom Anrufer gewählt. Sie können im allgemeinen Fall den gleichen Wert haben, aber das ist ein anderes Problem.

Meiner Meinung nach sollte CallHistory sowohl die gewählte Nummer als auch einen Verweis auf die aufgerufene Tabelle haben.

Verwandte Themen