Ich habe einige Tabellen und möchte eine Spalte aus der Tabelle PDF auf mehrere andere Tabellen verweisen.
zum Beispiel, wenn die Ausgabe von PDF -Tabelle select
folgendermaßen aussieht:
ITEM_TYPE ITEM_ID QUANTITY
1 23 3
2 12 1
es sagt mir:
PDF hat 3 Autorad-Produkte und 1 Car-Vorlagenkopf oben;
Ich habe SQL-Code geschrieben, funktioniert aber nicht richtig:
CREATE TABLE `pdf_created` (
`id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT,
`pdf_id` INT(10) NOT NULL,
`item_type` INT(3) UNSIGNED NOT NULL,
`item_id` INT(10) UNSIGNED NOT NULL,
`quantity` INT(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_pdf_id` (`pdf_id`),
CONSTRAINT `FK_pdf_id` FOREIGN KEY (`pdf_id`) REFERENCES `pdf` (`id`),
KEY `FK_item_type` (`item_type`),
CONSTRAINT `FK_item_type` FOREIGN KEY (`item_type`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
KEY `FK_item_id` (`item_id`),
CONSTRAINT `FK_item_id` FOREIGN KEY (`item_id`) REFERENCES `product` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_item_id` FOREIGN KEY (`item_id`) REFERENCES `service` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_item_id` FOREIGN KEY (`item_id`) REFERENCES `header` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `header` (
`id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT,
`title` VARCHAR(255),
`desc` VARCHAR(65535),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `service` (
`id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT,
`desc` VARCHAR(65535) NOT NULL,
`price` DECIMAL(5,2) NOT NULL,
`active` INT(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `product` (
`id` INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT,
`category_id` INT(3) UNSIGNED NOT NULL,
`symbol` VARCHAR(255),
`desc` VARCHAR(65535),
`price` DECIMAL(5,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ist es möglich, es zu erstellen?
Nein.
Das heißt, Sie können auf diese Weise keine Fremdschlüsseleinschränkung erstellen. Sie können jedoch einen Fremdschlüssel ohne eine Fremdschlüsseleinschränkung verwenden.
Ein Fremdschlüssel ist nur der Wert des Primärschlüssels einer anderen Tabelle (oder eines anderen Datensatzes in derselben Tabelle), der in Joins verwendet werden kann. Sie können auch andere Felder als den Primärschlüssel referenzieren, wenn Sie nur den Wert für Joins verwenden müssen.
Eine Fremdschlüsseleinschränkung weist die Datenbank jedoch an, die Regel zu erzwingen, dass die referenzierte Tabelle für jeden Fremdschlüsselwert in einer Tabelle einen Datensatz mit dem Primärschlüssel enthält. Das Erzwingen, dass jeder Fremdschlüssel in der Tabelle PDF einen Primärschlüssel IN ALL VIER TABLES hat, funktioniert für Sie nicht. Fahren Sie also fort und verwenden Sie das Feld, um auf andere Datensätze zu verweisen, erstellen Sie jedoch einfach keine Fremdschlüsseleinschränkung.
Das Problem, das Sie gefunden haben, heißt Polymorphic Associations
Bitte stellen Sie diese Frage: MySQL - Bedingte Fremdschlüsseleinschränkungen
Es sollte möglich sein. Ein mögliches Problem ist, dass Ihre drei Fremdschlüsseleinschränkungen denselben Namen haben.
Nein, ein Fremdschlüsselfeld soll auf eine Tabelle verweisen.
Wenn Sie die FK-Einschränkungen wie beschrieben hatten, referenziert ein item_id-Feld in allen drei Tabellen auf denselben Primärschlüsselwert. Es ist sehr wahrscheinlich, dass der gewünschte Primärschlüssel in den drei verschiedenen Tabellen unterschiedliche Primärschlüssel hat.
Sie möchten, dass ein Datensatz (Zeile) auf Datensätze in den Tabellen Product, Header und Service verweist. Dazu verwenden Sie drei verschiedene Felder, eines für jeden Fremdschlüssel.
Ich bemerke auch, dass die Artikeltabelle die drei Fremdschlüssel benötigt hat. Die Tabelle PDF könnte ein Feld enthalten, das auf Artikel verweist, und der Datensatz in Artikel verweist auf die drei anderen Tabellen.
ihr möglicher Fremdschlüsseleinschränkungsname sollte sich wie folgt unterscheiden: __. Primärschlüssel- und Fremdschlüsseltabellenspalte sollten denselben Datentyp wie folgt haben.
CREATE TABLE `neo_address_t` (
`address_id` varchar(8) NOT NULL,
`address_line_1` varchar(45) NOT NULL,
`address_line_2` varchar(45) NOT NULL,
`address_line_3` varchar(45) NOT NULL,
`address_city` varchar(45) NOT NULL,
`address_zipcode` varchar(45) NOT NULL,
`address_state` varchar(45) NOT NULL DEFAULT 'Karnataka',
`address_country` varchar(45) NOT NULL DEFAULT 'INDIA',
`created_by` varchar(8) DEFAULT NULL,
`created_on` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`last_modified_by` varchar(8) DEFAULT NULL,
`last_modified_date` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`Refer_ID` int(11) DEFAULT NULL,
`a_id` varchar(255) DEFAULT NULL,
`referenceid` varchar(255) DEFAULT NULL,
PRIMARY KEY (`address_id`),
KEY `hospital_ID_FK_idx` (`Refer_ID`),
CONSTRAINT `Patient_ID_FK` FOREIGN KEY (`Refer_ID`) REFERENCES `neo_patient_t` (`patient_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `hospital_ID_FK` FOREIGN KEY (`Refer_ID`) REFERENCES `neo_hospital_t` (`hospital_id`) ON DELETE NO ACTION ON UPDATE CASCADE,
CONSTRAINT `staff_ID_FK` FOREIGN KEY (`Refer_ID`) REFERENCES `neo_staff_t` (`staff_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
ENGINE=InnoDB DEFAULT CHARSET=utf8$$
Theoretisch können Sie nicht mehrere Fremdschlüssel für eine einzelne Spalte erzwingen. Alternativ können Sie dies auch mithilfe von Prozeduren erzwingen, bei denen Sie die in mehreren Tabellen vorhandenen Eingaben überprüfen und die erforderliche Operation ausführen Die Tabelle sollte von den Prozeduren durchgeführt werden, die die erforderliche Bedingung validieren, andernfalls würde dies zu einer Verletzung der Integrität führen.
Ja es ist möglich. Auch wenn es ein bisschen seltsam erscheint.
Zuerst möchte ich einen Screenshot meiner MySQL Workbench zeigen, um zu beweisen, dass es funktioniert.
... und für diejenigen, die sagen "Vielleicht haben Sie vergessen, die Änderungen anzuwenden" ... Hier ist der Screenshot des Schemabrowsers:
und schließlich der exportierte Dump mit einigen Beispieldaten:
-- MySQL dump 10.13 Distrib 5.7.12, for Win64 (x86_64)
--
-- Host: localhost Database: multiple_foreign_keys
-- ------------------------------------------------------
-- Server version 5.7.17-log
/*!40101 SET @[email protected]@CHARACTER_SET_CLIENT */;
/*!40101 SET @[email protected]@CHARACTER_SET_RESULTS */;
/*!40101 SET @[email protected]@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @[email protected]@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @[email protected]@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `header`
--
DROP TABLE IF EXISTS `header`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `header` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`desc` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `header`
--
LOCK TABLES `header` WRITE;
/*!40000 ALTER TABLE `header` DISABLE KEYS */;
INSERT INTO `header` VALUES (42,'Header','Test Header');
/*!40000 ALTER TABLE `header` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `pdf_created`
--
DROP TABLE IF EXISTS `pdf_created`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `pdf_created` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pdf_id` int(10) NOT NULL,
`item_type` int(3) unsigned NOT NULL,
`item_id` int(10) unsigned NOT NULL,
`quantity` int(3) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `fk_item_to_product_idx` (`item_id`),
CONSTRAINT `fk_item_to_header` FOREIGN KEY (`item_id`) REFERENCES `header` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_item_to_product` FOREIGN KEY (`item_id`) REFERENCES `product` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_item_to_service` FOREIGN KEY (`item_id`) REFERENCES `service` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `pdf_created`
--
LOCK TABLES `pdf_created` WRITE;
/*!40000 ALTER TABLE `pdf_created` DISABLE KEYS */;
INSERT INTO `pdf_created` VALUES (1,2,5,42,1);
/*!40000 ALTER TABLE `pdf_created` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `product`
--
DROP TABLE IF EXISTS `product`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `product` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(3) unsigned NOT NULL,
`symbol` varchar(255) DEFAULT NULL,
`desc` varchar(255) DEFAULT NULL,
`price` decimal(5,2) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `product`
--
LOCK TABLES `product` WRITE;
/*!40000 ALTER TABLE `product` DISABLE KEYS */;
INSERT INTO `product` VALUES (42,13,'product','desc',10.00);
/*!40000 ALTER TABLE `product` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `service`
--
DROP TABLE IF EXISTS `service`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `service` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`desc` varchar(255) NOT NULL,
`price` decimal(5,2) NOT NULL,
`active` int(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `service`
--
LOCK TABLES `service` WRITE;
/*!40000 ALTER TABLE `service` DISABLE KEYS */;
INSERT INTO `service` VALUES (42,'some service',5.00,1);
/*!40000 ALTER TABLE `service` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET [email protected]_TIME_ZONE */;
/*!40101 SET [email protected]_SQL_MODE */;
/*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */;
/*!40014 SET [email protected]_UNIQUE_CHECKS */;
/*!40101 SET [email protected]_CHARACTER_SET_CLIENT */;
/*!40101 SET [email protected]_CHARACTER_SET_RESULTS */;
/*!40101 SET [email protected]_COLLATION_CONNECTION */;
/*!40111 SET [email protected]_SQL_NOTES */;
-- Dump completed on 2018-08-27 10:31:41
Verwenden Sie 'Data Import/Restore' in MySQL Workbench, wenn Sie es anstelle eines SQL-Skript-Editors testen möchten.
, ABER Sie sollten kein Auto-Inkrement für die product
-, header
- und service
-Tabellen verwenden, auf die mit pdf_created.item_id
verwiesen wird, da dies ein glücklicher Zufall wäre, wenn alle drei dieselbe ID erhalten. Sie sollten die ID (die ID des Elements) zuweisen.