[sql] 외래 키가있는 테이블 열이 NULL 일 수 있습니까?

다른 테이블에 여러 ID 열이있는 테이블이 있습니다.

거기에 데이터를 넣을 때만 외래 키가 무결성을 유지하기를 원합니다 . 나중에 해당 열을 채우려면 업데이트를 수행하면 제약 조건도 확인해야합니다.

(이것은 데이터베이스 서버에 따라 다를 수 있습니다 .MySQL & InnoDB 테이블 유형을 사용하고 있습니다)

나는 이것이 합리적인 기대라고 생각하지만 내가 틀렸다면 나를 바로 잡으십시오.



답변

예, 값이 NULL이 아닌 경우에만 제한 조건을 적용 할 수 있습니다. 다음 예제를 통해 쉽게 테스트 할 수 있습니다.

CREATE DATABASE t;
USE t;

CREATE TABLE parent (id INT NOT NULL,
                     PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (id INT NULL,
                    parent_id INT NULL,
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=INNODB;


INSERT INTO child (id, parent_id) VALUES (1, NULL);
-- Query OK, 1 row affected (0.01 sec)


INSERT INTO child (id, parent_id) VALUES (2, 1);

-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key 
-- constraint fails (`t/child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY
-- (`parent_id`) REFERENCES `parent` (`id`))

첫 번째 삽입은에 NULL을 삽입하기 때문에 전달됩니다 parent_id. parent테이블에 존재하지 않는 값을 삽입하려고했기 때문에 외래 키 제약 조건으로 인해 두 번째 삽입이 실패 합니다.


답변

삽입 할 때 null 열 값을 구체적으로 NULL로 선언해야한다는 것을 알았습니다. 그렇지 않으면 빈 문자열이 아닌 제약 조건 위반 오류가 발생합니다.


답변

예, 예상대로 작동합니다. 불행히도, MySQL 매뉴얼 에서 이것에 대한 명시 적 진술을 찾는 데 어려움을 겪고있는 것 같습니다 .

외래 키는 다른 테이블에 값이 있어야 함을 의미합니다. NULL 은 값이 없음을 나타내므로 열을 NULL로 설정하면 제약 조건을 적용하려고 시도하는 것이 적합하지 않습니다.


답변

위의 작동하지만 작동하지 않습니다. ON DELETE CASCADE 참고

CREATE DATABASE t;
USE t;

CREATE TABLE parent (id INT NOT NULL,
                 PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (id INT NULL,
                parent_id INT NULL,
                FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE

) ENGINE=INNODB;


INSERT INTO child (id, parent_id) VALUES (1, NULL);
-- Query OK, 1 row affected (0.01 sec)


답변

예, 값은 NULL 일 수 있지만 명시 적이어야합니다. 나는 이전에도 이와 같은 상황을 경험했으며, 왜 이런 일이 발생했는지 잊어 버리기 쉬우므로 수행해야 할 일을 기억하는 데 약간의 시간이 걸립니다.

제출 된 데이터가 빈 문자열로 캐스트되거나 해석되면 실패합니다. 그러나 INSERTING 또는 UPDATING 일 때 명시 적으로 값을 NULL로 설정하면 좋습니다.

그러나 이것은 프로그래밍의 재미입니다. 우리 자신의 문제를 만들고 고친다! 건배!


답변

이 문제를 해결하는 또 다른 방법은 다른 테이블에 DEFAULT 요소를 삽입하는 것입니다. 예를 들어, 다른 테이블에서 uuid = 00000000-0000-0000-0000-000000000000에 대한 참조는 조치가 없음을 나타냅니다. 또한 코드 로직에 영향을주지 않으려면 해당 id의 모든 값을 “중립”으로 설정해야합니다 (예 : 0, 빈 문자열, null).


답변

나는 또한이 문제를 고수했다. 그러나 외래 키를로 정의하여 간단히 해결했습니다 unsigned integer. 아래 예제를 찾으십시오.

CREATE TABLE parent (
   id int(10) UNSIGNED NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (
    id int(10) UNSIGNED NOT NULL,
    parent_id int(10) UNSIGNED DEFAULT NULL,
    FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
) ENGINE=INNODB;