2008-09-19 11 views
18

OK, so dass praktisch jede datenbankbasierte Anwendung mit "nicht aktiven" Datensätzen umgehen muss. Entweder Soft-Deletionen oder Markieren von etwas als "ignoriert werden". Ich bin gespannt, ob es radikale Alternativen zu einer `active'-Spalte (oder einer Statusspalte) gibt.`aktive 'Flagge oder nicht?

Zum Beispiel, wenn ich eine Liste von Personen hatte

CREATE TABLE people (
    id  INTEGER PRIMARY KEY, 
    name  VARCHAR(100), 
    active BOOLEAN, 
    ... 
); 

Das bedeutet, eine Liste der aktiven Menschen zu erhalten, müssen Sie

SELECT * FROM people WHERE active=True; 

Hat jemand verwenden, lassen vermuten, dass nicht aktive Datensätze würde zu einem separaten Tisch gebracht werden und wo eine UNION ist, um die beiden zu verbinden?

Neugierde auffällig ...

EDIT: ich sollte klar machen, ich bin von einem puristischen Perspektive auf das kommende. Ich kann sehen, wie Datenarchivierung für große Datenmengen notwendig sein kann, aber das ist nicht, wo ich herkomme. Wenn Sie eine SELECT * FROM Menschen tun würde es Sinn für mich, dass die Einträge in einem gewissen Sinne „aktiv“ sind

Dank

Antwort

18

Sie die Tabelle auf dem Aktivflag partitionieren, so dass Aktive Datensätze befinden sich in einer Partition und inaktive Datensätze befinden sich in der anderen Partition. Dann erstellen Sie für jede Tabelle eine aktive Ansicht, die automatisch den aktiven Filter enthält. Die Datenbank-Abfrage-Engine beschränkt die Abfrage automatisch auf die Partition, in der sich die aktiven Datensätze befinden. Dies ist viel schneller als die Verwendung eines Index für dieses Flag.

Hier ist ein Beispiel für das Erstellen einer partitionierten Tabelle in Oracle. Oracle hat keine booleschen Spaltentypen. Daher habe ich Ihre Tabellenstruktur für Oracle-Zwecke geändert.

CREATE TABLE people 
(
    id  NUMBER(10), 
    name  VARCHAR2(100), 
    active NUMBER(1) 
) 
PARTITION BY LIST(active) 
(
    PARTITION active_records VALUES (0) 
    PARTITION inactive_records VALUES (1) 
); 

Wenn Sie wollten, könnten Sie jede Partition in verschiedene Tablespaces setzen. Sie können Ihre Indizes auch partitionieren.

Übrigens scheint dies eine Wiederholung von this Frage, als ein Neuling muss ich fragen, was ist das Verfahren im Umgang mit unbeabsichtigten Duplikaten?

Edit: Wie in den Kommentaren aufgefordert, ein Beispiel zur Aufnahme einer partitionierten Tabelle in Oracle Erstellen

+0

Können Sie genauer darüber sein, wie Sie die Tabelle "partitionieren". Ich meine den Code für jede RDBM, die du magst. –

+2

Wie gewünscht, wurde ein Beispiel für eine partitionierte Tabelle hinzugefügt. Sehen Sie sich das Concepts-Handbuch von Oracle für detaillierte Informationen zur Tabellen- und Indexpartitionierung an. Ich verwende Oracle 10.2 und referenziere die gesamte Dokumentation von hier -> http://www.oracle.com/pls/db102/homepage –

+0

Anstelle einer "aktiven" Flagge würde ich empfehlen, einen anderen Feldnamen wie "gelöscht" zu verwenden . Der Grund ist, dass wenn die nächste Person daran arbeitet, sie verwirrt werden könnten, was "aktiv" bedeutet. Ansonsten, +1 toller Beitrag. – NotMe

0

Wir aktiv Fahnen verwenden ziemlich oft. Wenn Ihre Datenbank sehr groß wird, kann ich den Wert bei der Migration inaktiver Werte in eine separate Tabelle sehen.

Sie würden dann nur eine Vereinigung der Tabellen benötigen, wenn jemand alle Datensätze sehen möchte, aktiv oder inaktiv.

8

Nun, um sicherzustellen, dass Sie in den meisten Situationen nur aktive Datensätze zeichnen, können Sie Ansichten erstellen, die nur die aktiven Datensätze enthalten. Auf diese Weise ist es viel einfacher, den aktiven Teil nicht auszulassen.

1

Die aktive Flagge ist eine Art hässlich, aber es ist einfach und funktioniert gut.

Sie könnten sie in eine andere Tabelle verschieben, wie Sie vorgeschlagen haben. Ich würde vorschlagen, den Prozentsatz der aktiven/inaktiven Aufzeichnungen zu betrachten. Wenn Sie mehr als 20 oder 30% inaktive Datensätze haben, sollten Sie sie möglicherweise anderswo verschieben. Ansonsten ist es keine große Sache.

0

In den meisten Fällen reicht ein Binärfeld, das das Löschen anzeigt. Oft gibt es einen Bereinigungsmechanismus, der diese gelöschten Datensätze nach einer bestimmten Zeit entfernt, so dass Sie das Schema möglicherweise mit einem gelöschten Zeitstempel starten möchten.

0

Es ist Zeit, sich auf einen separaten Tisch zu begeben und sie wieder hoch zu holen. Abhängig davon, wie viele Datensätze offline sind und wie oft Sie sie zurückholen müssen, ist dies möglicherweise keine gute Idee.

Wenn die meisten nicht zurückkommen, sobald sie begraben sind, und nur für Zusammenfassungen/Berichte/was auch immer verwendet werden, dann wird es Ihren Haupttisch kleiner machen, Abfragen einfacher und wahrscheinlich schneller.

1

Ja, würden wir. Wir haben derzeit die "active = 'T/F'" - Spalte in vielen unserer Tabellen, hauptsächlich um die "neueste" Zeile anzuzeigen. Wenn eine neue Zeile eingefügt wird, wird die vorherige T-Zeile mit F markiert, um sie für Prüfzwecke beizubehalten.

Jetzt wechseln wir zu einem 2-Tabellen-Ansatz. Wenn eine neue Zeile eingefügt wird, wird die vorherige Zeile in eine Verlaufstabelle verschoben. Dies gibt uns in den meisten Fällen eine bessere Leistung - mit Blick auf die aktuellen Daten.

Die Kosten sind ein wenig mehr als die alte Methode, zuvor mussten Sie aktualisieren und einfügen, jetzt müssen Sie einfügen und aktualisieren (dh, anstatt eine neue T-Zeile einzufügen, ändern Sie die vorhandene Zeile mit allen neuen Daten) , so dass die Kosten nur darin bestehen, eine ganze Reihe von Daten zu übergeben, anstatt nur die Änderungen zu übergeben. Das wird kaum Wirkung zeigen.

Der Performance-Vorteil ist, dass Ihre Haupttabelle des Index ist deutlich kleiner, und Sie können Ihre Tablespaces besser optimieren (sie werden nicht ganz so viel wachsen!)

+0

Ich möchte auch zu einem 2-Tabellen-Ansatz wechseln, während ich an einer alten, schlecht entworfenen Datenbank arbeite, in der einige Tabellen eine Spalte "active = 'T/F'" für Prüfzwecke haben und nicht haben Primärschlüssel. Wie haben Sie mit gelöschten Datensätzen verfahren, verwenden Sie ein Flag, um eine Zeile als aktiv/gelöscht zu markieren, oder verschieben Sie den gelöschten Datensatz ebenfalls in die Verlaufstabelle? Verschieben Sie alle zugehörigen Daten auch in die Verlaufstabelle? Vielen Dank! –

+0

nichts wird gelöscht, Sie verschieben alle Datensätze in die Verlaufstabelle und schlagen ihnen ein Flag.Wenn Sie eine Löschung aufzeichnen müssen (anstatt nachträglich geändert zu werden), brauchen Sie nur eine neue Spalte, um sie als gelöscht zu markieren. Eines Tages wird jemand nach den toten Daten fragen, und Sie werden in der Lage sein, sie richtig zu beantworten. Wir kaskadieren keine verwandten Datensätze - wenn sie sich ändern, müssen ihre Daten aktualisiert werden, aber wenn sich die Beziehung nicht ändert, müssen Sie dies nicht tun. Unser Datenschema war jedoch einfach genug, um dies zu ermöglichen, YMMV. – gbjbaanb

+0

Das neue System, mit dem ich arbeite, schreibt eine komplett separate Audit-Tabelle, die einfach alle Änderungen aufzeichnet und automatisch für alle wichtigen (nicht alle) Datenänderungen "Spalte X von Y auf Z geändert" schreibt. – gbjbaanb

0

Wir beiden Methoden verwenden, um mit inaktiven Datensätze zu tun. Die Methode, die wir anwenden, hängt von der Situation ab. Für Datensätze, die im Wesentlichen Nachschlagewerte sind, verwenden wir das Feld Aktives Bit. Dies ermöglicht es uns, Einträge zu deaktivieren, so dass sie nicht verwendet werden, aber es ermöglicht uns auch, die Datenintegrität mit Beziehungen aufrechtzuerhalten.

Wir verwenden die "move to separation table" -Methode, wo die Daten nicht mehr benötigt werden und die Daten nicht Teil einer Relation sind.

0

Die Situation wirklich diktiert die Lösung, methinks:

Wenn die Tabelle Benutzer enthält, dann mehrere „Flag“ Felder verwendet werden könnten. Eine für Gelöscht, Deaktiviert usw. Oder wenn Platz ein Problem ist, dann würde ein Flag für Behinderte ausreichen und dann die Zeile löschen, wenn sie gelöscht wurde.

Es hängt auch von Richtlinien zum Speichern von Daten ab. Wenn es Richtlinien gibt, um Daten archiviert zu halten, ist höchstwahrscheinlich nach langer Zeit eine separate Tabelle erforderlich.

0

Nein - das ist ein ziemlich gemeinsame Sache - einige Variationen auf spezifischen Anforderungen abhängig (aber Sie bedeckte sie bereits):

1) Wenn Sie eine ganze Reihe von Daten zu erwarten haben - wie mehrere Terabyte oder mehr - Es ist keine schlechte Idee, gelöschte Datensätze sofort zu archivieren - obwohl Sie möglicherweise einen Kombinationsansatz verwenden, bei dem die Markierung als gelöscht markiert und dann in Archivtabellen kopiert wird.

2) Natürlich besteht die Möglichkeit, einen Datensatz zu löschen - obwohl wir Entwickler Datenpakete sind - Ratten - schlage ich vor, dass Sie den Geschäftsprozess betrachten und entscheiden sollten, ob es jetzt überhaupt notwendig ist, zu behalten die Daten - wenn es soweit ist - tue es ... wenn es nicht ist - solltest du dich wohl frei fühlen, nur um das Zeug wegzuwerfen .....wieder nach dem spezifischen Geschäftsszenario.

3

Wir verwenden eine Enum ('AKTIV', 'INAKTIV', 'DELETED') in den meisten Tabellen, so dass wir tatsächlich eine 3-Wege-Flagge haben. Ich finde es in verschiedenen Situationen gut für uns. Ihre Laufleistung kann variieren.

2

Bewegliches inaktives Zeug ist normalerweise eine dumme Idee. Es ist viel Overhead mit viel Potenzial für Bugs, alles wird komplizierter, wie das Archivieren der Daten usw. Was machen Sie mit verwandten Daten? Wenn Sie all das verschieben, müssen Sie auch jede einzelne Abfrage ändern. Wenn Sie es nicht bewegen, welchen Vorteil haben Sie erhofft?

Das führt zum nächsten Punkt: WARUM würdest du es bewegen? Eine ordnungsgemäß indizierte Tabelle erfordert eine zusätzliche Suche, wenn sich die Größe verdoppelt. Jede Leistungsverbesserung ist zwangsläufig vernachlässigbar. Und warum würdest du überhaupt darüber nachdenken bis in die ferne Zukunft, wenn du tatsächlich Leistungsprobleme hast?

2

Ich denke, es streng als ein Stück Daten dann die Art und Weise, die im ursprünglichen Beitrag gezeigt wird, ist richtig. Der aktive Flag-Teil der Daten hängt direkt vom Primärschlüssel ab und sollte in der Tabelle enthalten sein.

Diese Tabelle enthält Daten zu Personen, unabhängig vom aktuellen Status ihrer Daten.

0

Aus einer 'puristischen Perspektive' unterscheidet das reaktionale Modell nicht zwischen einer Ansicht und einer Tabelle - beides sind Relationen. Daher ist die Verwendung einer Ansicht, die den Diskriminator verwendet, vollkommen sinnvoll und gültig, vorausgesetzt, die Entitäten werden korrekt z. Person/AktivPerson.

Auch aus einer 'puristischen Perspektive' sollte die Tabelle Person, nicht Personen genannt werden, da der Name der Relation ein Tupel widerspiegelt, nicht das gesamte Set.

+0

Benennungsschemata sind eine Präferenz. Ich denke, es ist nur zu empfehlen, bei der Entscheidung für alle Tabellen zu bleiben. Viele betrachten eine Beziehung als sehr gut. –

1

Binäre Flags wie dieses in Ihrem Schema sind eine schlechte Idee. Betrachten Sie die Abfrage

SELECT count(*) FROM users WHERE active=1

Sieht einfach genug aus. Aber was passiert, wenn Sie eine große Anzahl von Benutzern haben, so viele, dass das Hinzufügen eines Indexes zu dieser Tabelle erforderlich wäre. Wieder sieht es direkt aus

ALTER TABLE users ADD INDEX index_users_on_active (active)

AUSSER !! Dieser Index ist nutzlos, da die Kardinalität in dieser Spalte genau zwei ist! Jeder Datenbankabfrageoptimierer ignoriert diesen Index aufgrund seiner geringen Kardinalität und führt einen Tabellenscan durch.

Bevor Sie Ihr Schema mit hilfreichen Flags füllen, überlegen Sie, wie Sie auf diese Daten zugreifen.

https://stackoverflow.com/questions/108503/mysql-advisable-number-of-rows

+3

Die Kardinalität sollte die Verwendung eines Indexes nicht beeinflussen. Selektivität tut es. –

0

die boolean In Bezug auf die Indizierung, warum nicht:

ALTER TABLE users ADD INDEX index_users_on_active (id, active) ; 

lassen, dass die Suche nicht verbessern?
Allerdings weiß ich nicht, wie viel von dieser Antwort von der Plattform abhängt.

Verwandte Themen