2009-06-24 14 views
3

Zuerst habe ich this StackOverflow question gelesen, also brauche ich nicht darauf hinzuweisen.Table-agnostic Foreign Keys?

Ich arbeite gerade an einem ähnlichen Problem. Insbesondere habe ich eine Datenbank mit einer Überwachungstabelle, die verwendet wird, um Überwachungsinformationen über andere Tabellen innerhalb der Datenbank zu speichern. Die Grundform dieser Tabelle ist:

ID, EntityID, EntityTypeID, ActionTypeID, Datetime

Nun, wie Sie sich vorstellen können, die generische Natur der EntityID bedeutet, dass Fremdschlüsselbeziehungen zu und von dieser Tabelle heikel sind Verwalten Sie, vor allem mit Ihnen durch ein ORM-System in den Mix.

Natürlich ist die Grunt-Work-Lösung, die erforderlichen Abfragen manuell zu tun und verwenden Sie die ORM-Sachen, wo es funktioniert, was mir gut geht.

Das Problem warf jedoch die Frage auf, ob es gibt RDBMS da draußen, die eine Fremdschlüssel-Beziehung des Formulars ermöglicht: Tabelle: ID definiert werden.

Mit anderen Worten, in einer solchen RDBMS enthält die EntityTypeID Spalte könnte Werte wie

'TableA: 1' und 'TableB: somekey'

So ...

Gibt es irgendein RDBMS, das das tut?

Antwort

0

Sie könnten sich die Option ansehen, das Audit in einer separaten Datenbank zu speichern, vielleicht in einer objektorientierten Datenbank wie db4o. Dadurch erhalten Sie möglicherweise zusätzliche Flexibilität in Bezug auf den Speicher

5

Audit-Tabellen können normalerweise keine referenziellen Integritätsbedingungen für sie haben. Eine Audit-Tabelle A zeichnet Informationen über eine Reihe von Daten R in einer Tabelle T auf und enthält eine Reihe von Datensätzen für R, die jeweils zu einem anderen Zeitpunkt R repräsentieren. Wenn R anschließend modifiziert wird, ändert sich die Information in A nicht und darf keine Änderungen an R verhindern. Wenn R anschließend gelöscht wird, darf das Vorhandensein der Audit-Datensätze in A diese Löschung nicht stoppen.

+0

Sie haben Recht - Audit bedeutet normalerweise "historisch". FKs können also nicht erstellt werden. –

+0

Ich sehe die Logik dessen, was Sie damit sagen. Allerdings würde ich Ihnen in Bezug auf die Löschung nicht zustimmen. In den meisten, wenn nicht allen der Datenbanken, mit denen ich gearbeitet habe, gibt es so viele Beziehungen zwischen den verschiedenen Tabellen innerhalb des Systems, dass das Löschen eines Datensatzes das Löschen über eine boolesche Wertspalte bedeutet, anstatt sie tatsächlich zu löschen. Dieser Ansatz entspricht auch meiner Einstellung, dass in einem RDB Daten nie wirklich entfernt werden sollten. – OOPMan

+0

@OOPMan: Ich habe beträchtliches Mitgefühl mit dem Standpunkt "Nichts löschen". Temporale Datenbanken unterstützen dies explizit (oder können dies). Allerdings benutzte ich die konventionelle Definition des Begriffs DELETE, was bedeutet, dass der Datensatz wirklich verschwindet. –

0

Ich denke, dass keine RDBMS ähnliche Funktion unterstützen. Beziehungsstruktur ist, was Sie zuerst für sie bereitstellen müssen, und normalerweise helfen sie Ihnen nicht, es zu etablieren.

Auf der anderen Seite kann ich eine nette Eigenschaft von DataObjects.Net beschreiben, die ziemlich zu dieser Frage verwandt ist: automatische Registrierung von generischen Instanzen.

Stellen Sie sich 3 persistenten Typen haben:

[HierarchyRoot] 
public class A : Entity 
{ 
    [Field, Key] 
    long Id { get; set; } 

    // ... 
} 

[HierarchyRoot] 
public class B : Entity 
{ 
    [Field, Key] 
    int Id { get; set; } 

    // ... 
} 

// Note: it is a descendant of B 
public class C : B 
{ 
    // ... 
} 

Und noch eine persistente Klasse hinzufügen:

[HierarchyRoot] 
public class AuditData<T> : Entity 
    where T: Entity 
{ 
    [Field] 
    [Association(OnTargetRemove = OnRemoveAction.None)] // This ensures 
    // FK won't be created 
    T Source { get; set; } 

    // ... 
} 

Datenobjekte.Net wird automatisch Persistenz für zwei Fälle dieser Art bieten:

  • Auditdata (Of A)
  • Auditdata (B)

Aber es wird nicht zulassen, dass Sie Auditdata erstellen (Of C), da es AuditData (Of B) gibt. Es trifft also die Entscheidung, was auf der Grundlage generischer Typeinschränkungen zu registrieren ist. Es wird auch gezeigt, dass es leicht ist, die Erzeugung eines Fremdschlüssels zu vermeiden.

1

Btw, natürlich, können Sie ähnliche Funktion mit nur einem RDBMS implementieren - durch die Implementierung einiger Logik, die Struktur der Audit-Tabellen durch die Struktur aller anderen Tabellen zu aktualisieren. Sie müssen:

  1. Extract die Struktur aller Tabellen, die Sie
  2. Finden Sie die „Hierarchie roots“ zwischen ihnen prüfen gehen: in der Tat, müssen Sie halten nur die Tabellen, die Primärschlüssel isn‘ t als Fremdschlüssel in eine andere Tabelle markiert.
  3. Erstellen Sie die Überwachungstabellen für jede der Hierarchiewurzeln (oder restrukturieren Sie sie). Hier benötigen Sie eine Vorlage mit austauschbaren Spalten, die den Quellentabellenschlüssel enthalten.

Also im Allgemeinen ist dies keine leichte Aufgabe. Selbst wenn Sie ein Werkzeug wie SQL haben, ist DOM in der Lage, das Schema zu extrahieren und seine Teile zu erstellen.