문제

곧 개봉될 슈퍼히어로 영화에 대한 내부 정보를 수집하고 있으며 기본 영화 테이블이 다음과 같다고 가정해 보겠습니다.

1 번 테이블

Title              Director   Leading Male      Leading Female    Villain
--------------------------------------------------------------------------
Green Lantern      Kubrick    Robert Redford     Miley Cyrus     Hugh Grant  
The Tick          Mel Gibson  Kevin Sorbo        Linda Hunt    Anthony Hopkins

이는 일반적으로 매우 잘 작동하며 매우 쉬운 쿼리와 행 간의 비교를 허용합니다.

그러나 각 데이터 사실의 출처는 물론 해당 사실을 발견한 언론인의 이름도 추적하고 싶습니다.이것은 일종의 제안인 것 같습니다. EAV 테이블은 다음과 같습니다.

표 2

Movie             Attribute            Value          Source          Journalist
----------------------------------------------------------------------------------
Green Lantern      Director           Kubrick         CHUD              Sarah
Green Lantern    Leading Male      Robert Redford     CHUD              James
Green Lantern   Leading Female      Miley Cyrus    Dark Horizons        James
Green Lantern      Villain           Hugh Grant       CHUD              Sarah
The Tick           Director          Mel Gibson       Yahoo            Cameron
...

이는 우리가 원했던 메타데이터를 쉽게 캡처하지만 쿼리를 더 어렵게 만듭니다.단일 영화의 기본 데이터를 모두 가져오려면 시간이 조금 더 걸립니다.보다 구체적으로 말하면 Green Lantern에 대한 네 가지 중요한 정보를 얻으려면 여기에서 네 개의 행을 처리해야 하지만 표 1에서는 훌륭하게 캡슐화된 단일 행입니다.

그래서 내 질문은 방금 설명한 복잡성과 일반적으로 EAV 테이블을 피해야 한다는 것을 알고 있기 때문에 EAV가 여전히 최선의 솔루션입니까?입니다.이 데이터를 표현하는 유일한 합리적인 방법인 것 같습니다.내가 보는 유일한 다른 대안은 표 1을 다른 표와 함께 사용하는 것입니다. 오직 다음과 같은 메타 데이터를 저장합니다.

표 3

Movie             Attribute            Source          Journalist
----------------------------------------------------------------------------------
Green Lantern      Director             CHUD              Sarah
Green Lantern    Leading Male           CHUD              James
Green Lantern   Leading Female      Dark Horizons         James
Green Lantern      Villain              CHUD              Sarah
The Tick           Director             Yahoo            Cameron
...

그러나 이는 매우 위험합니다. 누군가가 "Villain"에서 "Primary Villain"으로 테이블 1의 열 이름을 변경하면 테이블 3의 행은 여전히 ​​"Villain"으로만 표시되어 불행히도 관련 데이터가 분리되기 때문입니다."속성" 열이 테이블 1 열의 열거 역할을 하는 다른 테이블에 연결되어 있으면 도움이 될 수 있습니다.물론 DBA는 테이블 1의 실제 열과 일치하도록 이 열거 테이블을 유지 관리할 책임이 있습니다.그리고 실제로 열거형 테이블을 직접 만드는 대신 테이블 1의 열 이름이 들어 있는 SQL Server의 시스템 뷰를 사용하면 이를 더욱 향상시킬 수 있습니다.시스템 보기와 관련된 관계를 가질 수 있는지는 확실하지 않습니다.

당신은 무엇을 제안합니까?EAV가 유일한 방법인가요?

그리고 메타데이터 열이 하나만 있는 경우("Journalist" 없이 "Source"만) EAV 경로로 이동해야 합니까?"Director", "Director_Source", "Leading Male", "Leading Male_Source" 등의 열이 있을 수 있지만 이는 매우 빠르게 추악해집니다.내가 생각하지 못하는 더 나은 해결책이 있습니까?

제가 명확하게 설명하지 못한 부분이 있다면 댓글을 남겨주시면 필요에 따라 추가하겠습니다.아, 그리고 제가 사용한 영화 데이터는 조작된 것입니다 :)

편집하다:내 기본 질문을 간결하게 다시 설명하자면, 영화 항목을 실제로 잘 설명하는 표 1의 단순성과 진정한 RDBMS 디자인을 갖고 싶습니다. 동시에 속성에 대한 메타 데이터를 안전하고 접근 가능한 방식으로 저장하고 싶습니다.이것이 가능한가?아니면 EAV가 유일한 방법입니까?

편집 2:좀 더 웹 조사를 한 후에도 열에 메타데이터를 저장하려는 욕구를 중심으로 한 EAV에 대한 토론을 아직 찾지 못했습니다.EAV를 구현하는 주된 이유는 거의 항상 동적이며 예측할 수 없는 열이지만 내 예에서는 그렇지 않습니다.내 예에는 항상 동일한 4개의 열이 있습니다.감독, 남자주인공, 여자주인공, 악역.그러나 각 행의 각 열에 대한 특정 사실(출처 및 기자)을 저장하고 싶습니다.EAV는 이를 용이하게 할 것이지만 나는 그것에 의지하는 것을 피하고 싶습니다.

업데이트

"Movie" 열의 이름을 "Name"으로 바꾸고 전체 테이블 "Movie"를 호출하는 것을 제외하고 표 2 디자인을 사용하여 표 1을 다시 가져오기 위한 SQL Server 2008의 피벗 작업은 다음과 같습니다.

SELECT Name, [Director], [Leading Male], [Leading Female], [Villain]
FROM (Select Name, Attribute, Value FROM Movie) as src
PIVOT
(
Max(Value)
FOR Attribute IN ([Director], [Leading Male], [Leading Female], [Villain])
)  AS PivotTable
도움이 되었습니까?

해결책

디자인에서 사실 가치로 간주하는 것을 변경할 수 있습니다. ...데이터 모델의 사실은 다음 N-튜플로 표현될 수 있는 것 같습니다.

Movie | FactType | FactValue | FactSource | FactJournalist

다음 테이블 구조는 원하는 데이터 모델을 지원해야 하며 비교적 쉽게 인덱싱 및 조인이 가능합니다.다음 관점을 생성할 수 있도록 팩트 값과 팩트 유형만 피벗하는 뷰를 생성할 수도 있습니다.

MovieID | Movie Name | Director | LeadingMale | LeadingFemale | PrimaryVillain | etc

흥미롭게도 이는 EAV 모델을 데이터에 완전히 적용하고 개별 영화(감독, 주연, 악당 등의 직관적인 속성 포함)를 소스에 속성이 집중되는 중심 구조로 분해하는 논리적 확장이라고 생각할 수 있습니다. 대신 정보를 제공합니다.

제안된 데이터 모델의 이점은 다음과 같습니다.

  • 잘 정규화되어 있습니다(완전성을 위해 FactType 필드를 참조 테이블로 정규화해야 하지만).
  • 팩트 유형을 표 형식 구조로 효율적으로 피벗하는 뷰를 생성하는 것이 가능합니다.
  • 상대적으로 확장 가능하며 데이터베이스에서 참조 무결성 및 (원하는 경우) 카디널리티 제약 조건을 적용할 수 있습니다.
  • MovieFact 테이블은 단순한 텍스트 필드뿐만 아니라 다양한 종류의 영화 사실을 지원하도록 서브클래싱될 수 있습니다.
  • 데이터에 대한 간단한 쿼리는 상대적으로 효율적입니다.

데이터 모델의 몇 가지 단점은 다음과 같습니다.

  • 복합 조건부 쿼리는 작성하기가 더 어렵지만 불가능하지는 않습니다(예:감독이 A이고 주연 남자가 B인 영화를 모두 찾아보세요...)
  • 이 모델은 보다 전통적인 접근 방식이나 EAV 구조와 관련된 접근 방식보다 다소 덜 명확합니다.
  • 여러 사실을 업데이트하려면 여러 열이 아닌 여러 행을 업데이트해야 하기 때문에 삽입 및 업데이트가 조금 더 까다롭습니다.

구조를 정규화하기 위해 영화 데이터를 한 수준 위로 올렸고 일관성을 위해 영화 이름을 MovieFact 구조로 푸시할 수 있습니다. (일부 영화의 경우 이름이 소스 정보를 추적하려는 것일 수도 있기 때문입니다.) .

Table Movie
========================
MovieID   NUMBER, PrimaryKey
MovieName VARCHAR

Table MovieFact
========================
MovieID          NUMBER,  PrimaryKeyCol1
FactType         VARCHAR, PrimaryKeyCol2
FactValue        VARCHAR
FactSource       VARCHAR
FactJournalist   VARCHAR

그러면 가상 영화 데이터는 다음과 같습니다.

Movie Table
====================================================================================
MovieID  MovieName
====================================================================================
1        Green Lantern
2        The Tick

MovieFact Table
====================================================================================
MovieID  FactType       FactValue         FactSource       FactJournalist
====================================================================================
1        Director       Kubrick           CHUD             Sarah
1        Leading Male   Robert Redford    CHUD             James
1        Leading Female Miley Cyrus       Dark Horizons    James
1        Villain        Hugh Grant        CHUD             Sarah
2        Director       Mel Gibson        Yahoo            Cameron
2        Leading Male   John Lambert      Yahoo            Erica
...

다른 팁

흥미로운 시나리오.엔터티를 일류 개체로 생각하면 EAV 빈민가를 피할 수 있습니다.그것을 사실이라고 부르자.그리고 이 경우 모든 영화가 정확히 동일한 네 가지 사실을 가지고 있다는 점에서 직교하는 것이 도움이 됩니다.EAV 테이블은 원래의/올바른 테이블이 될 수 있으며, 그런 다음 해당 테이블을 마이닝하고 데이터를 적절하게 정규화된 형식으로 복제하는 외부 프로세스를 가질 수 있습니다(예:첫 번째 테이블).이렇게 하면 메타 데이터와 함께 원하는 데이터를 얻을 수 있으며, 마이닝 프로세스가 실행되는 빈도에 따라 정확한 영화 정보를 쉽게 쿼리할 수 있습니다.

일반 테이블과 EAV 테이블에서 무결성을 유지하는 데이터베이스 내 방법이 없는 것 같기 때문에 데이터가 유효한지 확인하려면 "데이터베이스 외부" 기능이 확실히 필요하다고 생각합니다.복잡한 일련의 트리거를 사용하면 거의 모든 작업을 수행할 수 있지만 문제를 "이해하는" 한 명의 인간 관리자가 처리하기가 훨씬 쉬울 것입니다.

여기에 또 다른 아이디어가 있습니다. 자유롭게 구멍을 뚫어보세요 :)

Table: Movie
Columns: MovieId|Movie|Director|LeadMale|LeadFemale|Villain

Table: MovieSource
Columns: MovieSourceId|MovieId|MovieRoleId|Source|Journalist

Table: MovieRole
Columns: MovieRoleId|MovieRole
Values: 1|Director, 2|LeadMale, 3|LeadFemale, 4|Villain

내가 생각하는 것은 영화 테이블의 열이 ~할 수 있었다 유형이 달라야 합니다(귀하의 예에서는 모두 문자열/varchar이지만 소스가 있는 숫자 또는 날짜 정보일 수도 있습니다).

그러나 소스 데이터의 열 유형은 영화 데이터의 열 유형에 따라 달라지지 않으므로 데이터 무결성을 잃지 않고 소스에 대해 더 많은 EAV 시스템을 사용할 수 있습니다.

MovieRole 테이블을 사용하면 역할을 명시적으로 열거할 수 있으므로 소스와 영화 테이블의 특정 셀 사이에 확실한 연결을 생성할 수 있습니다.

-단

소스 데이터에 대해 두 개의 필드(Source 및 Journalist)만 있으므로 다음과 같은 메타데이터 테이블을 권장합니다.

Movie    DirectorSource  DirectorJournalist  LeadingMaleSource  LeadingMaleJournalist ...
---------------------------------------------------------------------------------------
The Tick   Yahoo           Cameron           ...                ...

이렇게 하면 덜 중요한 소스 데이터가 기본 테이블에서 제외되지만 쿼리가 복잡해지지 않고 코드를 더 쉽게 읽을 수 있습니다.

나는 단지 조언할 것이다 EAV 만약에 ...

  • 소스 메타데이터 필드가 3개를 초과합니다.
  • 필요 영화 필드를 쉽게 추가하거나 변경할 수 있습니다.('악당'에서 '주악당'으로의 변경 등이 하루에 여러 번씩 이루어지고 있습니다)

내 답변은 SO에 비해 너무 철학적으로 보일 수 있습니다.참아주세요.

"소스" 열은 주제 데이터가 아니라 메타데이터인 것 같습니다.이는 실제로 우리가 다른 데이터를 어떻게 알게 되었는지에 대한 데이터입니다.그것이 데이터에 관한 데이터가 되고, 그것이 바로 메타데이터입니다.

EAV가 문제를 일으키는 이유 중 하나는 데이터와 메타데이터를 단일 행에 혼합한다는 사실입니다.내가 달성하고 싶은 결과를 향한 중간 단계로서 의도적으로 스스로 그렇게 한 경우가 있습니다.하지만 저는 결과물에 데이터와 메타데이터를 절대로 섞지 않으려고 노력했습니다.

내가 왜 그렇게 하지 않았는지 알지만, 그것을 간결하게 설명할 수는 없습니다.

실제로 아무도 그것에 대해 균열을 일으키고 있지 않기 때문에 나는 내 질문에 답할 것입니다.나는 EAV와 같은 테이블이 실제로 갈 수 있는 유일한 방법이라고 확신합니다.각 열(이 경우 소스 및 기자 관련)에 메타데이터를 저장하려면 실제로 각 열을 그 자체로 엔터티로 처리해야 하며, 이는 EAV가 허용하는 것입니다.

~할 수 있었다 데이터를 저장하기 위해 각 원본 열에 두 번째 및 세 번째 열을 추가하는 것과 같은 다른 경로로 가십시오. 그러나 이는 확실히 몇 가지 기본적인 정규화 규칙을 위반하는 것이며 아마도 나중에 고통을 초래할 것입니다.

흠....저는 이것을 사용해 본 적이 없으므로 경험을 바탕으로 말하는 것이 아닙니다(예:작동하지 않더라도 나를 비난하지 마십시오.) 그러나 표면적으로는 일반 테이블에 있는 것처럼 항상 존재하는 "공통" 데이터와 다음과 같이 변경될 수 있는 "메타데이터"를 저장할 수 있는 것처럼 보입니다. XML.그러면 문제는 어떻게 쿼리를 잘 할 것인가인데, 설명된 대로 그렇게 할 수 있을 것 같습니다. 여기.

고려해야 할 또 다른 접근 방식은 클래스 테이블 상속입니다.Bill Karwin은 EAV 옵션에 대해 훌륭하게 검토했습니다. 이 SO 답변, 그리고 좋은 맥락이 많이 있습니다.

나는 코딩해야 할 내용에 따라 결정을 내릴 것입니다.

src/journo가 단순히 추가 정보라면 추가 열로 이동하겠습니다.그러나 복잡한 src/journo 쿼리를 작성하게 될 것이라는 것을 안다면 EAV로 갈 것입니다. 주요여성기자 그리고 악당저널리스트 등.

개인적으로 저는 src/journo 메타데이터를 EAV 스타일의 다른 테이블에 덤프하고 싶지만 FK를 사용하여 속성 정의 테이블을 정의합니다.자유형 속성 텍스트 필드를 갖는 것은 재난의 비법입니다. 항상 제약 조건을 통해 속성을 제어하십시오.필요한 경우 참조 무결성을 향상시키기 위해 트리거를 구현할 수 있습니다.

나에게 그것은 관점으로 귀결됩니다.출처와 언론인이 그 자체로 관계에 관심이 있다고 보시나요? 아니면 단지 정보를 보완하기 위한 추가 데이터일 뿐인가요? 영화?다음 단계의 개선은 다음에 대한 다른 테이블을 만드는 것입니다. MovieData소스 그리고 영화데이터저널리스트 이를 통해 FK를 유효한 정의 테이블에 매핑할 수 있습니다. 출처 그리고 언론인 (그러면 해당 출처/저널리스트에 대한 추가 정보가 구체화될 수 있습니다).여기서 수행할 작업은 다음과 같은 다대다 관계를 설정하는 것입니다. 영화 실체와 원천 (그리고 또한 기자) 엔터티.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top