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?

War es hilfreich?

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 UPDATEd oder INSERTed, 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 KEYs 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.

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