2016-12-08 6 views
5

Ich habe die folgenden Tabellenspalten in MySQL.Bidirektionale eindeutige Schlüsseleinschränkung für die Kombination von zwei Spalten

id 
user_primary_email 
user_secondary_email 

Ich mag die Kombination von Spalten user_primary_email und user_secondary_email einzigartig machen, die ich unter Verwendung UNIQUE KEY unique_key_name (user_primary_email, user_secondary_email)

Die obige Zugabe von eindeutiger Schlüsselbedingung wird dazu beitragen, erreichen kann mir das unten stehende Szenario zu erreichen oder vielmehr nur durch eine Zugabe eindeutiger Schlüssel für die einzelne Spalte selbst.

Jetzt ist das Problem, mit dem ich konfrontiert bin, die gleiche Kombination sollte nicht in umgekehrter Weise hinzugefügt werden, wie unten erwähnt.

user_primary_email = '[email protected]' AND user_secondary_email = '[email protected]' //This should not be allowed to add since already same email id combination added once 

id | user_primary_email | user_secondary_email 
------------------------------------------------------- 
1  | [email protected]  | [email protected] 
------------------------------------------------------- 
2  | [email protected]  | [email protected]  
------------------------------------------------------- 

Im obigen Fall während des Einsatzes der Reihe ID 2 es Fehler, da sowohl die E-Mail-ID-Kombination in Reihe ID1 verwendet wird bereits werfen soll.

Jede Hilfe wäre großartig.

+0

Bedingungsprüfung? http://www.w3schools.com/sql/sql_check.asp – Kritner

+0

Dies wird in diesem Szenario nicht funktionieren. – user850234

+0

ah, sorry ich bin mir nicht sicher über mysql. Ich weiß, in SQL-Server können Sie eine Funktion schreiben, die eine Abfrage innerhalb hat, die in eine Check-Constraint platziert werden kann ... ich denke, das gleiche existiert nicht für MySQL? – Kritner

Antwort

4

In jedem MariaDB:

CREATE TABLE `t` (
    `id` int(11) NOT NULL, 
    `user_primary_email` varchar(64) DEFAULT NULL, 
    `user_secondary_email` varchar(64) DEFAULT NULL, 
    `mycheck` varchar(128) AS (IF(user_primary_email<user_secondary_email,CONCAT(user_primary_email,user_secondary_email),CONCAT(user_secondary_email,user_primary_email))) PERSISTENT, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `mycheck` (`mycheck`) 
); 

MariaDB [test]> insert into t values (1,'a','b',null); 
Query OK, 1 row affected (0.03 sec) 

MariaDB [test]> insert into t values (2,'b','a',null); 
ERROR 1062 (23000): Duplicate entry 'ab' for key 'mycheck' 
3

Es gibt keine direkte Unterstützung dafür, aber Sie können eine Problemumgehung verwenden, um Ihren bidirektionalen Schlüssel zu erstellen: Sie benötigen einen eindeutigen Schlüssel für eine geordnete Version Ihrer zwei Spalten.

Glücklicherweise können Sie das sehr leicht tun. MySQL 5.7.6+ unterstützt generierte Spalten und eindeutige Indizes für sie, mit denen Sie Ihre zwei Werte ordnen und die Eindeutigkeit erzwingen können.

create table testBiDirKey (
    a varchar(100), 
    b varchar(100), 
    a_ordered varchar(100) as (least(a, b)) STORED, 
    b_ordered varchar(100) as (greatest(a, b)) STORED, 
    unique key unqBi_test_ab (a_ordered, b_ordered) 
); 

insert into testBiDirKey(a,b) values('a', 'b'); 
insert into testBiDirKey(a,b) values('b', 'a'); 
Error Code: 1062. Duplicate entry 'a-b' for key 'unqBi_test_ab' 

Dieses null genau wie Ihre aktuelle normalen eindeutigen Schlüssel behandeln, so

insert into testBiDirKey(a,b) values('a', null); 
insert into testBiDirKey(a,b) values('a', null); 
insert into testBiDirKey(a,b) values(null, 'a'); 

alle sind erlaubt. Sie können coalesce(x,'') hinzufügen, um nur einen leeren Wert zuzulassen (entweder null ODER ''), wenn Sie möchten. Wenn Sie Ihre Werte überprüfen, bevor Sie sie hinzufügen (z. B. wenn sie keine , enthalten), können Sie die beiden Spalten mit nur einer verknüpfen, die mit einer , verkettet ist - allerdings mit nur wenigen zusätzlichen Spalten.

Für 5.7.8+ brauchen Sie das Schlüsselwort STORED nicht mehr, um diese Spalten in einem Index verwenden zu können. Dieses Schlüsselwort wirkt sich aus, wenn die Werte gespeichert (mit Speicherplatz) oder bei Bedarf berechnet werden (Standard).

Vor MySQL 5.7.6, können Sie einen Trigger verwenden (auf update und insert), um die zwei Spalten mit diesen Werten zu aktualisieren, die gleiche Logik gilt, es ist nur ein wenig mehr Code.

+0

Große Antwort zusammen mit klarer Erklärung ... Ich benutze MariaDB und akzeptiere die obige Antwort ... Aber auch deine Antwort zu verbessern, da dies für andere sehr hilfreich sein wird ... danke – user850234

Verwandte Themen