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


92

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

답변:


108

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"테이블을 단일 테이블로 병합하는 것을 고려해야합니다.


21

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

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


20

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

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

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

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


18

내 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 ...)

13

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

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

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

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


5

자주는 아닙니다.

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

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


5

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

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

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


3

모든 설계 질문과 마찬가지로 대답은 "상황에 따라 다릅니다."

몇 가지 고려 사항이 있습니다.

  • 테이블이 얼마나 커질까요 (필드와 행 모두)? 유지 관리 및 프로그래밍 관점에서 일반적으로 사용되지 않는 다른 데이터와 함께 사용자 이름, 암호를 보관하는 것은 불편할 수 있습니다.

  • 제약 조건이있는 결합 된 테이블의 필드는 시간이 지남에 따라 관리하기가 번거로울 수 있습니다. 예를 들어 트리거가 특정 필드에 대해 실행되어야하는 경우 해당 필드가 영향을 받았는지 여부에 관계없이 테이블에 대한 모든 업데이트에 대해 발생합니다.

  • 관계가 1 : 1이 될 것이라고 얼마나 확신하십니까? 으로 문제는 지적 상황을 신속하게 복잡 할 수 있습니다 얻을.


3

다른 사용 사례는 다음과 같습니다. 일부 소스에서 데이터를 가져 와서 매일 업데이트 할 수 있습니다 (예 : 책에 대한 정보). 그런 다음 일부 책에 대한 데이터를 직접 추가합니다. 그런 다음 가져온 데이터를 자신의 데이터가 아닌 다른 테이블에 넣는 것이 좋습니다.


2

나는 일반적으로 두 가지 일반적인 1 : 1 관계를 실제로 만납니다.

  1. IS-A 관계, 상위 유형 / 하위 유형 관계라고도합니다. 이것은 한 종류의 엔터티가 실제로 다른 엔터티의 한 유형 인 경우입니다 (EntityA는 EntityB입니다). 예 :

    • 동일한 회사 내에서 회계사, 엔지니어, 영업 사원에 대한 별도의 엔티티가있는 개인 엔티티.
    • Widget, RawMaterial, FinishedGood 등에 대한 별도의 엔터티가있는 항목 엔터티
    • 트럭, 세단 등에 대해 별도의 엔티티가있는 자동차 엔티티

    이러한 모든 상황에서 상위 유형 엔티티 (예 : Person, Item 또는 Car)는 모든 하위 유형에 공통된 속성을 가지며 하위 유형 엔티티는 각 하위 유형에 고유 한 속성을 갖습니다. 하위 유형의 기본 키는 수퍼 유형의 기본 키와 동일합니다.

  2. "보스"관계. 사람이 조직 단위 (부서, 회사 등)의 고유 한 상사 또는 관리자 또는 감독자 인 경우입니다. 조직 단위에 허용 된 보스가 한 명 뿐인 경우 보스를 나타내는 개인 엔티티와 조직 단위 엔티티간에 1 : 1 관계가 있습니다.


1
두 번째 예를 좋아합니다. 엔티티 "Department"및 엔티티 "Employee"를 가질 수 있습니다. 한 부서에는 많은 직원이 있으며 직원은 한 부서에서만 일할 수 있습니다. 이것은 1 : n입니다. 직원은 한 부서의 감독자가 될 수 있으며, 부서에는 감독자가 한 명뿐입니다. 따라서 1 : n과 1 : 1의 두 관계로 연결된 두 개의 테이블이 생깁니다.
cezar

2

첫째, 별도의 엔터티를 구성하는 것을 모델링하고 정의하는 문제라고 생각합니다. 당신이 가정 customers오직 하나 하나에 address. 물론 하나의 테이블에 모든 것을 구현할 수 customer있지만, 앞으로 그가 2 개 이상의 주소를 가질 수 있도록 허용한다면이를 리팩토링해야 할 것입니다 (문제는 아니지만 의식적인 결정을 내립니다).

테이블 분할이 유용 할 수있는 다른 답변에서 언급되지 않은 흥미로운 사례를 생각할 수도 있습니다.

다시 말하지만, 각각 customers하나 를 가지고 address있지만 이번에는 주소를 갖는 것이 선택 사항입니다. 물론 NULL.NET과 같은 여러 열로 구현할 수 있습니다 ZIP,state,street. 그러나 주소 있다고 가정 하면 상태는 선택 사항이 아니지만 ZIP은 선택 사항입니다. 단일 테이블에서 모델링하는 방법은 무엇입니까? customer테이블 에 제약 조건을 사용할 수 있지만 다른 테이블에서 나누고 foreign_key를 NULL로 만드는 것이 훨씬 쉽습니다. 그런 식으로 모델은 엔티티 address 가 선택 사항 ZIP이며 해당 엔티티의 선택적 속성 이라는 점에서 훨씬 더 분명 합니다.


0

프로그래밍 시간에 나는 한 가지 상황에서만 이것을 만났습니다. 이는 동일한 두 개체 ( "개체 A"및 "개체 B")간에 일대 다 및 일대일 관계가있는 경우입니다.

"엔티티 A"에 여러 "엔티티 B"가 있고 "엔티티 B"에 "엔티티 A"가 1 개만 있고 "엔티티 A"에는 현재 "엔티티 B"가 1 개만 있고 "엔티티 B"에는 "엔티티 A"가 1 개만있는 경우입니다.

예를 들어, 자동차에는 현재 운전자가 한 명만있을 수 있고 운전자는 한 번에 한 대의 자동차 만 운전할 수 있습니다. 따라서 자동차와 운전자의 개념 간의 관계는 1 : 1이됩니다.-이 예는 @Steve Fenton의 답변에서 빌 렸습니다.

운전자가 동시에 여러 대의 자동차를 운전할 수있는 곳. 따라서 Car 및 Driver 엔티티는 일대 다 또는 다 대다입니다. 그러나 현재 운전자가 누구인지 알아야한다면 일대일 관계도 필요합니다.


0

또 다른 사용 사례는 데이터베이스 테이블의 최대 열 수를 초과하는 경우입니다. 그런 다음 OneToOne을 사용하여 다른 테이블을 조인 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.