Frage

Wie kann ich effizient einen eindeutigen Index für zwei Felder in einer Tabelle wie folgt erstellen: create table t (eine ganze Zahl ist, b ganze Zahl ist);

wobei jede einzigartige Kombination von zwei verschiedenen Nummern kann nicht mehr als einmal in der gleichen Zeile in der Tabelle angezeigt werden.

Mit anderen Worten, wenn eine Zeile existiert, so daß a = 1 und b = 2 ist, können eine weitere Zeile nicht vorhanden, wenn a = 2 und b = 1 oder a = 1 und b = 2. Mit anderen Worten: zwei Zahlen erscheinen können nicht zusammen mehr als einmal in beliebiger Reihenfolge.

Ich habe keine Ahnung, was eine solche Beschränkung genannt wird, daher der ‚zweiseitige eindeutigen Index‘ Name im Titel.

Aktualisieren : Wenn ich einen zusammengesetzten Schlüssel auf Spalten (a, b), und eine Reihe (1,2) in der Datenbank vorhanden, ist es möglich, eine andere Reihe (2,1 einfügen ) ohne einen Fehler. Was ich suche ist eine Möglichkeit, das gleiche Paar von Zahlen zu verhindern, dass mehr als einmal verwendet werden in beliebiger Reihenfolge ...

War es hilfreich?

Lösung

Wie wäre es kontrollieren, was in der Tabelle geht, so dass Sie immer die kleinste Zahl in der ersten Spalte speichern und die größte in der zweiten? Solange es die gleiche Sache natürlich ‚bedeutet‘. Es ist wahrscheinlich weniger teuer, es zu tun, bevor es sogar in die Datenbank wird.

Wenn dies nicht möglich ist, können Sie die Felder speichern wie aber haben sie in numerischer Reihenfolge in zwei anderen Bereichen dupliziert, auf dem Sie den Primärschlüssel (Pseudo-Code-ish) erzeugen würde:

COLUMN A : 2
COLUMN B : 1

COLUMN A_PK : 1  ( if new.a < new.b then new.a else new.b )
COLUMN B_PK : 2  ( if new.b > new.a then new.b else new.a )

Dies leicht mit einem Trigger (wie in Ronald Antwort) oder gehandhabt höher, in der Anwendung durchgeführt werden kann.

Andere Tipps

Ich denke, dies kann nur für INSERT-Trigger erfolgen (in Kombination mit einer einzigartigen Einschränkung auf den beiden Säulen) mit a. Ich bin nicht wirklich fließend in MySql Syntax (mein T-SQL ist besser), so dass ich denke, die folgenden werden einige Fehler enthalten:

Edit: die Syntax Aufgeräumt, so dass es für MySQL funktioniert. Beachten Sie auch, Sie werden wahrscheinlich diese als BEFORE UPDATE Trigger setzen wollen auch (mit einem anderen Namen natürlich).

Auch setzt dieses Verfahren einen primären oder sonst eindeutige Schlüssel auf den beiden Felder auf (dh. Diese Trigger überprüfen nur das Gegenteil nicht existiert bereits.) Es gibt keine Art und Weise zu werfen, einen Fehler zu sein scheint aus ein Auslöser, so wage ich zu sagen, dass dies so gut ist, wie es geht.

CREATE TRIGGER tr_CheckDuplicates_insert
BEFORE INSERT ON t
FOR EACH ROW
BEGIN
    DECLARE rowCount INT;
    SELECT COUNT(*) INTO rowCount
                   FROM t
                   WHERE a = NEW.b AND b = NEW.a;

    IF rowCount > 0 THEN
        -- Oops, we need a temporary variable here. Oh well.
        -- Switch the values so that the key will cause the insert to fail.
        SET rowCount = NEW.a, NEW.a = NEW.b, NEW.b = rowCount;
    END IF;
END;

In Oracle Sie eine funktionsbasierte Index wie folgt verwenden können:

create unique index mytab_idx on mytab (least(a,b), greatest(a,b));

Ich weiß nicht, mySQL, aber vielleicht etwas Ähnliches ist möglich? Zum Beispiel könnten Sie zwei neue Spalten leastab hinzufügen und greatestab auf den Tisch, mit einem Trigger mit den Werten von mindestens beizubehalten (a, b) und größten (a, b) ist, und erstellen Sie dann einen eindeutigen Index für (leastab , greatestab).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top