Programming

Nullable Foreign Key 나쁜 습관?

procodes 2020. 8. 3. 17:57
반응형

Nullable Foreign Key 나쁜 습관?


고객 ID에 대한 외래 키가있는 주문 테이블이 있다고 가정합니다. 자, 고객 ID없이 주문을 추가하고 싶다고 가정 해보십시오. (또 다른 질문인지 여부에 관계없이) 외래 키를 NULL로 만들어야합니다 ... 나쁜 습관입니까? 주문과 고객? 관계는 1 대 n이지만 링크 테이블은 n 대 n을 만듭니다. 반면에, 링크 테이블을 사용하면 더 이상 해당 NULL이 없습니다 ...

외래 키가 NULL 인 레코드는 주문에 대한 고객이 추가 될 때까지 일시적이기 때문에 실제로 데이터베이스에는 많은 NULL이 없습니다.

(제 경우에는 주문과 고객이 아닙니다).

편집 : 할당되지 않은 고객은 어떤 링크를합니까?


링크 테이블을 갖는 것이 더 나은 옵션 일 것입니다 . 최소한 정규화 BCNF (Boyce-Codd normal form)를 위반하지 않습니다 . 그러나 나는 실용적이기를 선호합니다. 이러한 null 값이 거의없고 일시적인 경우에는 구성표에 복잡성을 추가하기 때문에 링크 테이블을 건너 뛰어야한다고 생각합니다.

부수적으로; 링크 테이블을 사용한다고해서 반드시 n에서 n으로 만들 필요는 없습니다. 링크 테이블에서 주문 테이블을 가리키는 외래 키를 해당 링크 테이블의 기본 키로 사용하는 경우 관계는 여전히 1..n입니다. 해당 링크 테이블에는 주문 당 하나의 항목 만있을 수 있습니다.


Nullable FK에는 아무런 문제가 없습니다. 이는 FK가 가리키는 엔터티가 기본 키 참조 테이블과 (0 또는 1) 대 (1 또는 많은) 관계에있을 때 일반적입니다.

예를 들어 테이블에 실제 주소와 우편 주소 속성 (열)이 있고 주소 테이블에 FK가있는 경우를 예로들 수 있습니다. 엔터티에 우체국 상자 (우편 주소) 만있는 경우 실제 주소를 처리 할 수 ​​없도록하고, 우편 주소가 실제 주소와 같은 경우 처리 할 수없는 메일 주소를 만들 수 있습니다.


Nullable 열은 1NF에서 5NF까지 가능하지만 내가 읽은 내용에 따라 6NF에서는 불가능합니다.

Chris Date보다 "첫 번째 일반 형식이 실제로 무엇을 의미하는지"보다 잘 알고있는 경우에만 가능합니다. x와 y가 일부 행의 x 실제로 모두 Null을 허용하고 있습니다와 y가 모두있는 경우 null, 다음 WHERE x=y양보하지 않습니다 true. 이것은 실제 값이 항상 자신과 같기 때문에 null이 값이 아니라는 합리적인 의심의 여지가 없습니다. 그리고 RM은 "테이블의 모든 셀에 값이 있어야한다"고 규정하고 있기 때문에 널을 포함 할 수있는 것은 관계적인 것이 아니므로 1NF의 문제는 발생하지 않습니다.

Nullable 열은 일반적으로 1 차 정규화 수준을 어 기고 있다고 들었습니다.

그 주장의 근본 원인은 위를 참조하십시오.

그러나 실제로는 매우 실용적입니다.

두통의 영향을받지 않는 경우에만 전세계 모든 지역에서 발생합니다. 그러한 두통 중 하나 (그리고 다른 null현상 과 비교할 때 사소한 두통 )는 WHERE x=ySQL에서 실제로 의미 하는 사실 WHERE x is not null and y is not null and x=y이지만 대부분의 프로그래머는 단순히 그 사실을 인식하지 못하고 그냥 읽습니다. 때로는 아무런 해를 끼치 지 않고 다른 때는하지 않습니다.

실제로 널 입력 가능 컬럼은 가장 기본적인 데이터베이스 설계 규칙 중 하나를 위반합니다. 하나의 컬럼에 고유 한 정보 요소를 결합하지 마십시오. 널 (null)은 부울 값 "이 필드는 실제로 존재하지 않습니다"를 실제 값과 결합하기 때문에 정확하게 수행합니다.


외래 키에서 null로 표시되는 선택적 n-1 관계라는 잘못된 점은 없습니다. 그렇지 않으면 링크 테이블을 넣으면 nn 관계가되지 않도록 관리해야하므로 더 많은 문제가 발생합니다.


관계형 모델에서는 선택적 관계가 가능합니다.

널을 사용하여 관계가 없음을 나타낼 수 있습니다. 그것들은 편리하지만 널이 다른 곳에서 당신을 일으키는 것과 같은 두통을 유발할 것입니다. 그들이 문제를 일으키지 않는 한 곳은 조인입니다. 외래 키에 null이있는 행은 참조 된 테이블의 행과 일치하지 않습니다. 그래서 그들은 내부 조인에서 빠져 나옵니다. 외부 조인을 수행하면 어쨌든 null을 처리하게됩니다.

실제로 null을 피하려면 (6 번째 정규 형식) 테이블을 분해 할 수 있습니다. 분해 된 두 테이블 중 하나에 두 개의 외래 키 열이 있습니다. 하나는 선택 사항 인 외래 키이고 다른 하나는 원래 테이블의 기본 키를 참조하는 외래 키입니다. 이제 구속 조건을 사용하여 관계가 다대 다가되지 않도록해야합니다.이를 방지하려고합니다.


NULL을 사용하면 불완전한 주문을 정리할 수 있습니다.

SELECT * FROM `orders`
WHERE `started_time` < (UNIX_TIMESTAMP() + 900) AND `customer_id` IS NULL

위는 관련 고객 ID가없는 15 분보다 오래된 주문을 보여줍니다.


선택적 다 대일 관계에 대한 Nullable FK는 완전히 괜찮습니다.


고객이 정의 될 때까지 고객 ID없이 일시적으로 주문을 추가하는 경우 단일 트랜잭션에서 고객과 주문을 추가하는 것이 더 간단하지 않으므로 NULL 외래 키 입력의 필요성을 제거하고 제한 조건 또는 트리거를 피할 수 있습니다 위반을 설정 했습니까?

일반적으로이 상황은 고객이 누구인지 정의하기 전에 주문이 자세히 설명 된 웹 앱에서 발생합니다. 이러한 상황에서는 주문이 데이터베이스에 유지되는 시점에서 전체 주문에 필요한 모든 상태가 제공 될 때까지 주문이 서버 상태 또는 쿠키로 유지됩니다.

위에서 언급했듯이 주소와 같은 경우 NULL 외래 키는 괜찮습니다. 그러나 NULL 고객 필드는 주문에 적합하지 않으므로 제한되어야합니다.


Id = -1 및 CustomerName = 'Unknown'과 같은 Customer 테이블에 항상 인공 행을 추가 한 다음 일반적으로 CustomerId를 Order NULL로 설정 한 경우 -1로 설정합니다.

따라서 널 입력 가능 FK는 없지만 여전히 데이터 부족을 적절하게 나타낼 수 있습니다 (다운 스트림 사용자가 널 처리 방법을 모르는 경우).


Nullable 열은 일반적으로 1 차 정규화 수준을 위반한다고 주장하는 것을 들었습니다. 그러나 실제로는 매우 실용적입니다.


네, 뭔가 잘못되었습니다. 널 입력 가능하면 외래 키가 아닙니다. 코드 별 데이터베이스 디자인. 어쩌면 할당되지 않은 링크를 만들지 않을 수도 있습니다. 또는 문자 열을 사용하는 경우 "할당되지 않음". 데이터의 무결성을 100 % 유지하십시오.

참고 URL : https://stackoverflow.com/questions/1723808/nullable-foreign-key-bad-practice

반응형