Zusammengesetzten FS auf mehr als 1 Tabelle referenzieren
-
Kann mann einen Zusammengesetzten Fremdschlüssel auf mehr als 1 Tabelle referenzieren lassen so das dabei die referenziele Intigrität gewehrleistet ist?
Wäre dies nach dem SQL Standard möglich ?Ich habe mal ein kleines Bsp es ist ein Auszug aus einer "Medien-Datenbank" in ihr sollen verschiedene Medien
(CD,Buch,...) gespeichert werden.
Für jedes Medium existiert eine eigene Tabelle und es existiert eine Tabelle Inventar,welche alle Medien-Datensätze mit ihrem zusammengesetzten Primärschlüssel(id,mediumid) über den zusammengesetzten Fremdschlüssel(fid,fmediumid) referenziert.ERM(dient nur der Visualisierung)
http://codemax.de/upl/ERM-BSP-ZFK.jpgSQL Script
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL'; CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ; USE `mydb`; -- ----------------------------------------------------- -- Table `mydb`.`Medium_Buch` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `mydb`.`Medium_Buch` ( `id` INT NULL AUTO_INCREMENT , `mediumid` TINYINT NOT NULL DEFAULT 1 , `Seitenzahl` INT NULL , `isbn` VARCHAR(13) NOT NULL , `titel` VARCHAR(128) NOT NULL , PRIMARY KEY (`id`, `mediumid`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `mydb`.`Medium_Cd` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `mydb`.`Medium_Cd` ( `id` INT NULL AUTO_INCREMENT , `medienid` TINYINT NOT NULL DEFAULT 2 , `titel` VARCHAR(128) NOT NULL , `anzahl_mb` INT NOT NULL , PRIMARY KEY (`id`, `medienid`) ) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `mydb`.`Inventar` --- CREATE TABLE IF NOT EXISTS `mydb`.`Inventar` ( `inventar_nr` INT NULL AUTO_INCREMENT , `fmedium_id` INT NOT NULL , `fmedium_mediumid` TINYINT NOT NULL , PRIMARY KEY (`inventar_nr`) , INDEX `fBUCH` (`fmedium_id` ASC, `fmedium_mediumid` ASC) , INDEX `fCD` (`fmedium_id` ASC, `fmedium_mediumid` ASC) , CONSTRAINT `fBUCH` FOREIGN KEY (`fmedium_id` , `fmedium_mediumid` ) REFERENCES `mydb`.`Medium_Buch` (`id` , `mediumid` ) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT `fCD` FOREIGN KEY (`fmedium_id` , `fmedium_mediumid` ) REFERENCES `mydb`.`Medium_Cd` (`id` , `medienid` ) ON DELETE RESTRICT ON UPDATE CASCADE) ENGINE = InnoDB; SET SQL_MODE=@OLD_SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
-
Was willst du abbilden. Soll Inventar eine abstrakte Basisklasse sein, Medium_* konkrete Ableitungen? Du kannst Dir mal anschauen wie objektrelationale Mapper "Table per Type" oder "Tabelle pro Unterklasse" implementieren.
-
In dem Beispiel geht es darum: das eine Inventar-Liste für verschieden Medien dargestellt wird.Da Medien ja unterschiedliche eigenschaften haben ist eine Tabelle pro Medium angebracht.
Das dient nur als Beispiel ich möchte nur die Frage beantwortet haben ob es möglich ist einen Zusammengesetzten "Fremdschlüssel auf mehr als 1 Tabelle zu referenzieren"!Danke für die Antwort aber die Frage ist auf Relationale Datenbanken bezogen
-
also in deinem beispiel ist es nicht möglich, referenziell integer zu bleiben wenn die medienid nicht für jeden medientyp(buch,cd) anders ist.
grund:
denn dann kannst nicht garantieren, das eine kombination id+mediumid von tabelle "medium_buch" nicht auch mal in der tabelle "medium cd" auftreten kann.
beide tabellen sind ja unabhängig und generieren ihre primärschlüssel selbst,
so das theoretisch auch mal eine kombination in beiden tabellen vorkommen kann.
wenn dann die beiden tabellen ihre schlüssel in deiner "inventar"-tabelle ablegen, kann es da zu duplikaten kommen.aber wenn bei dir bücher z.b. immer medienid 1 haben und cdroms 2, dann klappt das, weil die kombinationen, die in den n tabellen(n=anzahl verschiedener medientypen) auftreten, immer insgesamt einmalig sind(autoincrement-pk der jeweiligen tabelle und medienid).