복붙노트

[SQL] 그것은 여러 외국 키로 한 열을 참조 할 수 있습니까?

SQL

그것은 여러 외국 키로 한 열을 참조 할 수 있습니까?

나는 몇 테이블을 가지고 있고, 여러 개의 다른 테이블에 PDF 테이블에서 하나의 열을 참조 할.

예를 들어 PDF 테이블은 다음과 같이 출력 모양을 선택하는 경우 :

ITEM_TYPE  ITEM_ID  QUANTITY

1          23       3
2          12       1

그것은 나에게 말한다 :

PDF는 3 자동차 바퀴 제품, 1 차 템플릿 헤더 위있다;

나는 SQL 코드를 작성하지만, 제대로 작동하지 않습니다 :

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;

그것을 만들 수 있습니다?

해결법

  1. ==============================

    1.아니.

    아니.

    즉, 당신은 외래 키 제약 조건이 방법을 만들 수 없습니다. 당신은 그러나, 외래 키 제약 조건없이 외래 키를 사용할 수 있습니다.

    외래 키는 모두, 다른 테이블 (또는 같은 테이블에서 다른 레코드) 조인에서 사용할 수있는 기본 키의 값입니다. 당신이 필요로하는 모든이에 대한 조인 값을 사용하는 경우 사실, 당신은, 기본 키가 아닌 필드를 참조 할 수 있습니다.

    그러나 외래 키 제약 조건은 기본 키의 같은 테이블의 모든 외래 키 값, 참조 된 테이블이 그와 기록을 가지고있는 규칙을 시행 할 수있는 데이터베이스를 알려줍니다. PDF 파일 테이블의 모든 외래 키는 4 가지의 모든 테이블이 당신을 위해 작동하지 않습니다 기본 키를 가지고 있음을 시행. 그래서 가서 다른 기록을 참조 할 필드를 사용하지만, 간단히 외래 키 제약 조건을 만들 수 없습니다.

  2. ==============================

    2.당신이 만난 문제는 다형성 협회라고

    당신이 만난 문제는 다형성 협회라고

    이 질문을 참조하십시오 : MySQL의 - 조건부 외래 키 제약 조건을

  3. ==============================

    3.그것은 수 있어야한다. 하나의 잠재적 인 문제는 세 개의 외래 키 제약 조건이 동일한 이름을 가지고있다.

    그것은 수 있어야한다. 하나의 잠재적 인 문제는 세 개의 외래 키 제약 조건이 동일한 이름을 가지고있다.

  4. ==============================

    4.아니, 하나 개의 외래 키 필드는 참조 하나의 테이블을 의미한다.

    아니, 하나 개의 외래 키 필드는 참조 하나의 테이블을 의미한다.

    당신은 당신이 설명하는대로 FK 제약 조건을 가지고 있었다 경우 ITEM_ID 필드는 모두 세 개의 테이블에 동일한 기본 키 값을 참조 할 것. 세 가지 다른 테이블에서 원하는 기본 키가 서로 다른 기본 키를했을 가능성이 매우 높다 할 것이다.

    당신이 원하는 것은 테이블 제품, 헤더, 및 서비스의 기준 기록에 하나 개의 레코드 (행)입니다. 그렇게하는 방법은 세 가지 분야, 각 외부 키를 사용하는 것입니다.

    나는 또한 항목 테이블이 필요한 세 개의 외래 키를 가지고 있음을 알 수 있습니다. 당신은 PDF 테이블이 하나 개의 필드 참조 항목 및 항목 참조의 레코드 세 개의 다른 테이블이있을 수 있습니다.

  5. ==============================

    5.나중에 그것의 가능한 외래 키 제약 조건 이름이 같은 다른해야 및 기본 키와 외래 키 테이블 컬럼이 같은 동일한 데이터 유형을 가져야한다 ..

    나중에 그것의 가능한 외래 키 제약 조건 이름이 같은 다른해야 및 기본 키와 외래 키 테이블 컬럼이 같은 동일한 데이터 유형을 가져야한다 ..

    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$$
    
  6. ==============================

    6.이론적으로는 단일 컬럼에 여러 개의 외래 키를 적용 할 수 없습니다. 또는 당신은 당신이 여러 테이블에 존재 입력을 확인하고 필요한 작업을 수행 절차를 사용하여이를 적용 할 수 있습니다. 특정 테이블에 모든 작업이 무결성을 위반 그렇지 않으면 것 리드를 필요한 조건의 유효성을 검사하는 절차에 의해 수행되어야 함을주의하십시오.

    이론적으로는 단일 컬럼에 여러 개의 외래 키를 적용 할 수 없습니다. 또는 당신은 당신이 여러 테이블에 존재 입력을 확인하고 필요한 작업을 수행 절차를 사용하여이를 적용 할 수 있습니다. 특정 테이블에 모든 작업이 무결성을 위반 그렇지 않으면 것 리드를 필요한 조건의 유효성을 검사하는 절차에 의해 수행되어야 함을주의하십시오.

  7. ==============================

    7.네, 가능합니다. 그것은 조금 이상한 것 같다 경우에도 마찬가지입니다.

    네, 가능합니다. 그것은 조금 이상한 것 같다 경우에도 마찬가지입니다.

    먼저 나는 그것이 작동하는지 증언을 내 MySQL의 워크 벤치의 스크린 샷을 보여 드리고자합니다.

    ... 그리고 "어쩌면 당신은 변경 사항을 적용하는 것을 잊었다"말하는 사람들을 위해 ... 여기 스키마 브라우저의 스크린 샷입니다 :

    마지막으로 몇 가지 예를 들어 데이터를 내 보낸 덤프 :

    -- 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 @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8 */;
    /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
    /*!40103 SET TIME_ZONE='+00:00' */;
    /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@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 TIME_ZONE=@OLD_TIME_ZONE */;
    
    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
    
    -- Dump completed on 2018-08-27 10:31:41
    

    당신은 SQL 스크립트 편집기 대신 그것을 테스트하려는 경우 사용 MySQL의 워크 벤치에 '데이터 가져 오기 / 복원'.

    세 가지 모두 동일한 ID를 얻을 것이다 경우는 운이 우연의 일치 일 것입니다 있기 때문에 당신은 pdf_created.item_id 참조하는 제품, 헤더 및 서비스 테이블에 자동 증가를 사용하지 않아야합니다. 당신은 ID (항목의 ID)를 할당해야합니다.

  8. from https://stackoverflow.com/questions/15547276/is-it-possible-to-reference-one-column-as-multiple-foreign-keys by cc-by-sa and MIT license