2017-10-18 1 views
1

Ich habe eine Anwendung, wo Benutzer ihre eigenen benutzerdefinierten privaten Tags erstellen können, aber es gibt auch einige feste systemweite allgemeine Tags. Tags werden in einer Datenbanktabelle gespeichert, in der allgemeine Tags NULL sind.Erzwingen eindeutigen Wert pro Benutzer einschließlich globaler

CREATE TABLE TAG (
    TAG_ID INT IDENTITY(1, 1) NOT NULL, 
    TAG_NAME VARCHAR(40) NOT NULL, 
    USER_ID INT, 

    CONSTRAINT TAG_PK PRIMARY KEY (TAG_ID), 

    CONSTRAINT TAG_FK1 FOREIGN KEY (USER_ID) 
    REFERENCES [USER] (USER_ID) 
); 
CREATE INDEX TAG_IDX1 ON TAG (USER_ID); 

ich auf DB-Ebene durchsetzen will, die Tags für jeden Benutzer eindeutig sind, was bedeutet, dass:

  • Ein Benutzer nur einen Tag mit einem bestimmten Namen hat, aber andere Kunden können auch haben ihre eigenen Tags mit diesem Namen.

  • Häufige Tags sollten ebenfalls gezählt werden, damit Benutzer kein bereits vorhandenes Tag erstellen können.

Ein einfacher Index wie das wird nicht funktionieren, weil es nur Dubletten innerhalb von Gruppen (gemeinsame Tags einen jeden Benutzer) verhindert -e immer noch möglich ist, gemeinsame Tags als Nutzer-Tags neu zu erstellen:

CREATE UNIQUE INDEX TAG_UK1 ON TAG (TAG_NAME, USER_ID); 

ich glaube, dass SQL Server keine Ausdrücke in Indizes erlauben, zB:

-- Incorrect syntax near the keyword 'COALESCE'. 
CREATE UNIQUE INDEX TAG_UK1 ON TAG (TAG_NAME, COALESCE(USER_ID, 'COMMON')); 

können Sie von einem anderen Ansatz denken?

+1

Klingt für mich wie Sie müssen die Architektur ein wenig überdenken. Dies ist eine Beziehung von vielen zu vielen Arten (mit einigen zusätzlichen Vorbehalten), die mit nur zwei Tabellen fast unmöglich ist. –

+0

Die Eindeutigkeit in diesem Fall durch einen Index zu garantieren, ist vielleicht nicht machbar -AFAIK- und es klingt nicht so, als ob Sie aus Performancegründen einen Index nutzen würden. Warum bringst du das nicht in einen gespeicherten Proc oder Trigger? – Icarus

+0

@SeanLange Ich hatte nicht so darüber nachgedacht und es macht Sinn aus DB-Design-Perspektive. Aber wenn ich bedenke, dass ich vielleicht auch das Administrationstool und viele andere Teile der Codebasis bearbeiten muss, ist es vielleicht besser, Duples zu erlauben und die Benutzeroberfläche zu optimieren, um sie separat anzuzeigen - das wäre wahrscheinlich für meinen präzisen Anwendungsfall akzeptabel. –

Antwort

0

Wahrscheinlich brauchen Sie dies mit Triggern zu handhaben.

In der Tag-Tabelle, wenn Sie ein neues globales Tag einfügen oder aktualisieren. Sie müssen für jeden Benutzer überprüfen, ob er dieses Tag bereits hat und es in globale

Zum Beispiel haben Sie Angular als Tag, aber einige Benutzer sind Weg ein Kopf und erstellen Angular4. Wenn Angular4 ein globales Tag wird, müssen Sie es von allen Benutzern entfernen.

Dasselbe gilt für das Erstellen eines Tags für einen Benutzer. Sie können prüfen, ob das globale Tag bereits dieses Tag hat und einen Fehler auslösen.

+0

Häufige Tags sind im ursprünglichen Datensatz fest codiert und können nicht geändert werden. –

+1

Ändert meine Antwort nicht. Das Hinzufügen von Tags für Benutzer kann nur mit Triggern validiert werden. –

+0

Vielen Dank. Ich hatte wahrscheinlich Oracle und seine funktionsbezogenen Indizes im Hinterkopf, als ich mit diesem brillanten Design xD kam –

Verwandte Themen