[database] 일대일 관계를 언제 사용해야합니까?

그 멍청한 질문에 대해 죄송하지만 데이터베이스의 테이블과 일대일 관계를 사용해야 할 실제 필요가 있습니까? 하나의 테이블 안에 필요한 모든 필드를 구현할 수 있습니다. 데이터가 매우 커지더라도 SELECT를 사용하는 대신 문 에서 필요한 열 이름을 열거 할 수 있습니다 SELECT *. 이 분리가 정말로 필요한 때는 언제입니까?



답변

1에서 0..1

  • 수퍼 클래스와 하위 클래스 사이의 “1에서 0..1″은 상속구현 하기위한 “개별 테이블의 모든 클래스”전략의 일부로 사용됩니다 .

  • “1에서 0..1″은 “0..1”부분이 NULL 가능 필드로 덮여있는 단일 테이블로 표시 될 수 있습니다. 그러나 관계가 대부분 “1 대 1″행만있는 “1 대 0″인 경우 “0..1”부분을 별도의 테이블로 분할하면 일부 저장소 (및 캐시 성능) 이점을 줄일 수 있습니다. 일부 데이터베이스는 다른 데이터베이스보다 NULL을 저장하는 데 더 저렴하므로이 전략이 실행 가능한 “컷오프 지점”은 상당히 다를 수 있습니다.

1 대 1

  • 실제 “1 대 1″은 데이터를 수직으로 분할하므로 캐싱에 영향을 미칠 수 있습니다. 데이터베이스는 일반적으로 개별 필드 수준이 아닌 페이지 수준에서 캐시를 구현하므로 행에서 몇 개의 필드 만 선택하더라도 일반적으로 행이 속한 전체 페이지가 캐시됩니다. 행이 매우 넓고 선택한 필드가 상대적으로 좁 으면 실제로 필요하지 않은 많은 정보를 캐싱하게됩니다. 그런 상황에서 그렇게 수직으로 데이터를 분할하는 것이 유용 할 수 있습니다 캐시 효과적으로 “큰”를 만들기 때문에, 좁은, 더 자주 사용되는 일부 또는 행이 캐시됩니다 더 그들 중 캐시에 맞게 할 수 있습니다.

  • 수직 분할의 또 다른 용도는 잠금 동작을 변경하는 것입니다. 데이터베이스는 일반적으로 개별 필드 수준에서 잠글 수없고 전체 행만 잠글 수 있습니다. 행을 분할하면 절반 중 하나에서만 잠금이 발생하도록 허용합니다.

  • 트리거는 일반적으로 테이블에 따라 다릅니다. 이론적으로는 테이블이 하나만 있고 트리거가 행의 “잘못된 절반”을 무시하도록 할 수 있지만 일부 데이터베이스는 트리거가 수행 할 수있는 작업과 불가능한 작업을 추가로 제한하여이를 비현실적으로 만들 수 있습니다. 예를 들어, Oracle은 변경 테이블을 수정할 수 없습니다. 별도의 테이블을 사용하면 그중 하나만 변경 될 수 있으므로 트리거에서 다른 테이블을 수정할 수 있습니다.

  • 별도의 테이블은 더 세분화 된 보안을 허용 할 수 있습니다.

이러한 고려 사항은 대부분의 경우 관련이 없으므로 대부분의 경우 “1 대 1″테이블을 단일 테이블로 병합하는 것을 고려해야합니다.


답변

한 테이블의 데이터가 관련되어 있지만 다른 테이블에서 설명하는 엔터티에 ‘속하지 않는’경우 해당 데이터를 별도로 유지할 후보입니다.

이는 별도의 데이터가 다른 엔티티와 관련되어야하는 경우 향후 이점을 제공 할 수 있습니다.


답변

두 개의 일대일 테이블을 하나에 배치하면 의미론 문제가 발생할 가능성이 있습니다. 예를 들어, 모든 장치에 하나의 조종기가있는 경우 장치와 조종기를 하나의 테이블에 배치하는 것은 좋지 않습니다. 특정 속성이 장치 또는 원격 컨트롤러에 속하는지 알아내는 데 시간을 소비해야 할 수도 있습니다.

열의 절반이 오랫동안 비어 있거나 채워지지 않는 경우가있을 수 있습니다. 예를 들어, 자동차에는 여러 특성이있는 트레일러가 하나 있거나없는 경우가 있습니다. 따라서 사용하지 않는 속성이 많이 있습니다.

테이블에 20 개의 속성이 있고 그중 4 개만 가끔 사용되는 경우 성능 문제를 위해 테이블을 2 개의 테이블로 나누는 것이 좋습니다.

그러한 경우 모든 것을 하나의 테이블에 담는 것은 좋지 않습니다. 게다가 45 열이있는 테이블을 다루는 것은 쉽지 않습니다!


답변

내 2 센트.

저는 우리 모두가 대규모 애플리케이션에서 개발하고 모든 것이 모듈 인 곳에서 일합니다. 예를 들어, users테이블이 있고 사용자에 대한 페이스 북 세부 정보를 추가하는 모듈과 사용자에게 트위터 세부 정보를 추가하는 또 다른 모듈이 있습니다. 이러한 모듈 중 하나를 분리하고 응용 프로그램에서 모든 기능을 제거 할 수 있습니다. 이 경우 모든 모듈은 다음과 같이 1 : 1 관계가있는 자체 테이블을 전역 users테이블에 추가합니다.

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)


답변

이것을 사용하는 가장 현명한 시간은 이러한 방식으로 만 관련되는 두 개의 개별 개념이있는 경우입니다. 예를 들어, 자동차는 현재 운전자를 한 명만 가질 수 있고 운전자는 한 번에 한 대의 자동차 만 운전할 수 있습니다. 따라서 자동차와 운전자의 개념 간의 관계는 1 대 1이 될 것입니다. 포인트.

또 다른 이유는 개념을 다른 방식으로 전문화하고 싶기 때문입니다. Person 테이블이 있고 Employee, Customer, Shareholder와 같은 다양한 유형의 Person 개념을 추가하려는 경우 각각 다른 데이터 세트가 필요합니다. 이들간에 유사한 데이터는 Person 테이블에 있고 전문가 정보는 Customer, Shareholder, Employee에 대한 특정 테이블에 있습니다.

일부 데이터베이스 엔진은 매우 큰 테이블 (많은 행)에 새 열을 효율적으로 추가하는 데 어려움을 겪고 있으며 새 열이 원래 테이블에 추가되는 대신 새 열을 포함하는 데 사용되는 확장 테이블을 보았습니다. 이것은 추가 테이블의 더 의심스러운 사용 중 하나입니다.

성능 또는 가독성 문제를 위해 단일 개념에 대한 데이터를 두 개의 서로 다른 테이블로 나누기로 결정할 수도 있지만 처음부터 시작하는 경우 상당히 특별한 경우입니다. 이러한 문제는 나중에 표시됩니다.


답변

자주는 아닙니다.

보안을 구현해야하는 경우 일부 이점을 찾을 수 있습니다. 따라서 일부 사용자는 일부 열 (table1)을 볼 수 있지만 다른 열 (table2)은 볼 수 없습니다.

물론 일부 데이터베이스 (Oracle)에서는 동일한 테이블에서 이러한 종류의 보안을 수행 할 수 있지만 일부 데이터베이스는 그렇지 않을 수 있습니다.


답변

데이터베이스 정규화를 참조하고 있습니다. 내가 관리하는 애플리케이션에서 생각할 수있는 한 가지 예는 Items입니다. 이 애플리케이션을 통해 사용자는 다양한 유형의 항목 (예 : InventoryItems, NonInventoryItems, ServiceItems 등)을 판매 할 수 있습니다. 모든 항목에 필요한 모든 필드를 하나의 Items 테이블에 저장할 수 있지만 모든 항목에 공통된 필드가 포함 된 기본 항목 테이블을 보유한 다음 각 항목 유형 (예 : Inventory, NonInventory, 등)에는 해당 항목 유형에만 해당하는 필드가 포함됩니다. 그러면 항목 테이블이 나타내는 특정 항목 유형에 대한 외래 키를 갖게됩니다. 특정 항목 테이블과 기본 항목 테이블 간의 관계는 일대일입니다.

아래는 정규화에 대한 기사입니다.

http://support.microsoft.com/kb/283878