Nice programing

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

nicepro 2020. 10. 23. 18:54
반응형

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


그 멍청한 질문에 대해 죄송하지만 데이터베이스의 테이블과 일대일 관계를 사용해야 할 실제 필요가 있습니까? 하나의 테이블 안에 필요한 모든 필드를 구현할 수 있습니다. 데이터가 매우 커지더라도 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


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

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

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

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

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


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


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

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

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

    In all these situations, the supertype entity (e.g. Person, Item or Car) would have the attributes common to all subtypes, and the subtype entities would have attributes unique to each subtype. The primary key of the subtype would be the same as that of the supertype.

  2. "Boss" relationships. This is when a person is the unique boss or manager or supervisor of an organizational unit (department, company, etc.). When there is only one boss allowed for an organizational unit, then there is a 1:1 relationship between the person entity that represents the boss and the organizational unit entity.


First, I think it is a question of modelling and defining what consist a separate entity. Suppose you have customers with one and only one single address. Of course you could implement everything in a single table customer, but if, in the future you allow him to have 2 or more addresses, then you will need to refactor that (not a problem, but take a conscious decision).

I can also think of an interesting case not mentioned in other answers where splitting the table could be useful:

Imagine, again, you have customers with a single address each, but this time it is optional to have an address. Of course you could implement that as a bunch of NULL-able columns such as ZIP,state,street. But suppose that given that you do have an address the state is not optional, but the ZIP is. How to model that in a single table? You could use a constraint on the customer table, but it is much easier to divide in another table and make the foreign_key NULLable. That way your model is much more explicit in saying that the entity address is optional, and that the ZIP is an optional attribute of that entity.


In my time of programming i encountered this only in one situation. Which is when there is a 1-to-many and an 1-to-1 relationship between the same 2 entities ("Entity A" and "Entity B").

When "Entity A" has multiple "Entity B" and "Entity B" has only 1 "Entity A" and "Entity A" has only 1 current "Entity B" and "Entity B" has only 1 "Entity A".

For example, a Car can only have one current Driver, and the Driver can only drive one car at a time - so the relationship between the concepts of Car and Driver would be 1 to 1. - I borrowed this example from @Steve Fenton's answer

Where a Driver can drive multiple Cars, just not at the same time. So the Car and Driver entities are 1-to-many or many-to-many. But if we need to know who the current driver is, then we also need the 1-to-1 relation.


Another use case might be if the maximum number of columns in the database table is exceeded. Then you could join another table using OneToOne

참고URL : https://stackoverflow.com/questions/12318870/when-i-should-use-one-to-one-relationship

반응형