Einmaligkeit Einschränkungen in MS Access
-
06-09-2019 - |
Frage
In einer Datenbank das ich habe für MS Access zu entwerfen, ich habe eine Tabelle „Messungen“ genannt, der bestimmten Messparameter speichert (Messwert, Standardabweichung etc.) - jede Reihe eine ganze Zahl ID als primäres Taste.
Andere Tabellen verknüpfen Sie dann zu diesem Messtisch Fremdschlüsselbeziehungen verwenden. Einige Tabellen enthalten zwei verschiedene „measurementID“ Felder, die beide Zeiger auf diese eine Messtisch. Allerdings sollte jede Messung immer nur durch verknüpft werden ein diese Felder.
Wie kann ich eine Eindeutigkeitsbedingung über mehrere Felder in mehreren Tabellen erzwingen? Sei es eine Möglichkeit?
Lösung
Solche Beschränkungen können in der Tat in ACE / JET mit CHECK
Einschränkungen implementiert werden.
Die Person, die sagten, dass sie in der Regel Auslöser für diese Art der Sache möglich nutzen würde, ist nicht bekannt, die Differenz zwischen CHECK
Einschränkungen in ACE / Jet und SQL Server jeweils: in SQL Server können sie nicht Unterabfragen enthalten, das heißt, sie nicht verweisen Werte in anderen Zeilen in der gleichen Tabelle oder zu anderen Tabellen, während in ACE / Jet dort kann.
Im Ideal (aber noch AFAIK nicht existent) SQL-92-Produkt, beschrieben die Einzigartigkeit umgesetzt würde eine ASSETION
verwenden, auf dem Schemaebene zu sein. Da CHECK-Einschränkungen auf Tabellenebene und werden nur geprüft, wenn der Tisch, an den sie definiert sind, wird UPDATE
d oder INSERT
ed, müssen Sie entsprechende CHECK
Einschränkungen auf allen verweisenden Tabelle (das gleiche würde gelten für SQL Server-Trigger) setzen. Hier ist ein kleines Beispiel:
CREATE TABLE Parent
(
parent_ID INTEGER NOT NULL IDENTITY UNIQUE,
data_col INTEGER NOT NULL
)
;
CREATE TABLE Child1
(
parent_ID INTEGER NOT NULL
REFERENCES parent (parent_ID),
data_col INTEGER NOT NULL
)
;
CREATE TABLE Child2
(
parent_ID INTEGER NOT NULL
REFERENCES parent (parent_ID),
data_col INTEGER NOT NULL
)
;
ALTER TABLE Child1 ADD
CONSTRAINT child1__no_dups_in_child2
CHECK (NOT EXISTS (
SELECT *
FROM Child1 AS C1
INNER JOIN Child2 AS C2
ON C1.parent_ID = C2.parent_ID
))
;
ALTER TABLE Child2 ADD
CONSTRAINT child2__no_dups_in_child1
CHECK (NOT EXISTS (
SELECT *
FROM Child1 AS C1
INNER JOIN Child2 AS C2
ON C1.parent_ID = C2.parent_ID
))
;
Doch ich frage mich, ob Sie Unterklassen haben (dh die jeweils durch eine ID repräsentiert Einheit kann eingegeben werden), in diesem Fall sollten Sie FOREIGN KEY
s und Zeilenebene CHECK
Einschränkungen (oder Validierungsregeln verwenden können, wenn Sie mehr sind bequem mit der MS Access-Schnittstelle als SQL-DLL, die für CHECK
Einschränkungen erforderlich). Die Logik wird leichter sein, als CHECK
Einschränkungen auf Tabellenebene zu implementieren, nur für Zyklen in CASCADE
referenziellen Aktionen zu beobachten. Hier ist ein weiteres einfaches Beispiel:
CREATE TABLE Parent
(
parent_ID INTEGER NOT NULL IDENTITY,
child_type VARCHAR(4) NOT NULL,
CONSTRAINT child_type__values
CHECK (child_type IN ('Boy', 'Girl')),
UNIQUE (child_type, parent_ID)
)
;
CREATE TABLE Girls
(
parent_ID INTEGER NOT NULL,
child_type VARCHAR(4) DEFAULT 'girl' NOT NULL,
CONSTRAINT girl_child_type__must_be_girl
CHECK (child_type = 'girl'),
FOREIGN KEY (child_type, parent_ID)
REFERENCES Parent (child_type, parent_ID),
data_col INTEGER NOT NULL
)
;
CREATE TABLE Boys
(
parent_ID INTEGER NOT NULL,
child_type VARCHAR(4) DEFAULT 'boy' NOT NULL,
CONSTRAINT boy_child_type__must_be_boy
CHECK (child_type = 'boy'),
FOREIGN KEY (child_type, parent_ID)
REFERENCES Parent (child_type, parent_ID),
data_col INTEGER NOT NULL
)
;
Andere Tipps
Microsoft ACE / Jet-Engine unterstützt keine Trigger, das ist, wie Sie normalerweise diese Art von Funktionalität implementieren.
EDIT:. Wie @onedaywhen wies darauf hin, JET 4.0 ab Prüfen Einschränkungen unterstützen, aber es ist nicht einfach, eine xor Typeinschränkung über zwei Spalten zu implementieren
Wenn Sie Access Forms verwenden, können Sie das vor einem Update-Ereignis des Formulars implementieren könnte und überprüfen Sie Ihre Constraint Kriterien.
Mitch ist direkt über das, was in Access möglich ist. Jedoch vorausgesetzt, Sie BL irgendwo haben, diese in eine dotter was als Business Rule legitim ist. Das ist, was ich würde höchstwahrscheinlich tun.
Da Sie diese Datenbank entwerfen. Sind Sie sicher, dass Ihre Tabellenstrukturen sind folgende Standardnormalisierungsregeln.
Es klingt eine ungewöhnliche Struktur für eine Zeile in Tabelle A der Lage sein, Messungen zu referenzieren zwei Zeilen in der Tabelle in Abhängigkeit von dem A.row Feld Sie suchen auf. Ich habe das Gefühl, dass die Daten in der Tabelle Measurments wirklich in zwei Teile aufgeteilt werden muss oder mehr Tabellen.
Ich bin mir der Auslöser vorsichtig und Einschränkungen überprüfen, vor allem, weil ich die meisten meiner apps ohne sie (Access / Jet und MySQL / MyISAM) entwickelt haben. Ich stimme mit BobClegg, dass das klingt wie ein Supertyp / Subtyp Situation. In diesem Fall würden Sie eine Tabelle mit einem eindeutigen Index für die Fremdschlüssel verbinden verwenden und eine Spalte angibt, welche Art der Messung war es. Der eindeutige Index für die FK würde die Zugabe eines zweiten Typen verhindern. Es würde auch bedeuten, würden Sie nicht leere Felder in dem Hauptsatz haben. Sicherlich ein leeres numerisches Feld ist kein Speicherproblem, sondern zwei Felder, die exklusiv sehen immer wie ein Design-Fehler zu mir.