Erzwingen eindeutige Zeilen in MySQL
-
01-07-2019 - |
Frage
Ich habe eine Tabelle in MySQL
, die drei Felder haben, und ich möchte auf zwei der Felder Eindeutigkeit erzwingen. Hier ist die Tabelle DDL
:
CREATE TABLE `CLIENT_NAMES` (
`ID` int(11) NOT NULL auto_increment,
`CLIENT_NAME` varchar(500) NOT NULL,
`OWNER_ID` int(11) NOT NULL,
PRIMARY KEY (`ID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Das ID
Feld ist ein Ersatzschlüssel (diese Tabelle mit ETL geladen wird).
Die CLIENT_NAME
ist ein Feld, den Namen von Kunden enthält
Die OWNER_ID
ist eine ID eines Clients Besitzer angibt.
Ich dachte, ich dies mit einem eindeutigen Index für CLIENT_NAME
und OWNER_ID
erzwingen könnte,
ALTER TABLE `DW`.`CLIENT_NAMES`
ADD UNIQUE INDEX enforce_unique_idx(`CLIENT_NAME`, `OWNER_ID`);
aber MySQL gibt mir eine Fehlermeldung:
Fehler beim Ausführen von SQL-Befehlen Tabelle zu aktualisieren. Angegebener Schlüssel war zu lang; max Schlüssellänge ist 765 Bytes (Fehler 1071)
Noch jemand irgendwelche Ideen?
Lösung
MySQL kann keine Eindeutigkeit auf Schlüssel erzwingen, die länger als 765 Bytes (und anscheinend 500 UTF8-Zeichen kann diese Grenze übertreffen).
- Ist CLIENT_NAME wirklich brauchen lange 500 Zeichen sein? Scheint ein wenig übertrieben.
- Fügen Sie eine neue (kürzere) Spalte, die Hash (CLIENT_NAME). Erhalten Sie MySQL zu erzwingen Eindeutigkeit an diesem Hash statt.
Andere Tipps
Haben Sie bei CONSTRAINT sehen ... UNIQUE?
Etwas scheint ein wenig seltsam zu dieser Tabelle; Ich würde denken, tatsächlich darüber Refactoring. Worauf beziehen ID und OWNER_ID, und was ist die Beziehung zwischen ihnen?
Wäre es sinnvoll haben
CREATE TABLE `CLIENTS` (
`ID` int(11) NOT NULL auto_increment,
`CLIENT_NAME` varchar(500) NOT NULL,
# other client fields - address, phone, whatever
PRIMARY KEY (`ID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `CLIENTS_OWNERS` (
`CLIENT_ID` int(11) NOT NULL,
`OWNER_ID` int(11) NOT NULL,
PRIMARY KEY (`CLIENT_ID`,`OWNER_ID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Ich mag vermeiden, wirklich einen eindeutigen Schlüssel wie das auf einer 500-Zeichenfolge hinzufügen. Es ist viel effizienter auf zwei Ints Eindeutigkeit zu erzwingen, plus eine ID in einer Tabelle sollte wirklich bezieht sich auf etwas, das eine ID benötigt; in Ihrer Version scheint das ID
Feld nur den Client / Besitzer Beziehung zu identifizieren, die wirklich keine separate ID benötigt, da es nur eine Zuordnung.
Hier . Für den UTF8-Zeichensatz kann MySQL bis zu 3 Bytes pro Zeichen verwenden. CLIENT_NAME ist 3 x 500 = 1500 Bytes. Kürzen CLIENT_NAME
bis 250.
später. +1, um einen Hash-Wert des Namens zu schaffen und die Verwendung dieser als Schlüssel