2016-12-08 1 views
0

현재 일부 속성이 있거나 없을 수있는 동적 데이터 개체를 모델링하려고합니다 (속성 이름은 현재 요구 사항에 대해 알려져 있음). 나중에 새 속성을 추가할지 여부는 알 수 없습니다 (그러나 거의 확실합니다). 모델링 된 객체는이 라인을 따라 뭔가 :많은 NULL이있는 데이터에 대한 테이블 구조

int id PRIMARY KEY NOT NULL; 
int owner FOREIGN KEY NOT NULL; 
Date date NOT NULL; 
Time time NOT NULL; 
Map<String,String> properties; 

속성은 모든 유형 (INT, 부울, 문자열, ...)

나는이 모델링하는 방법을 잘 모르겠어요이 될 수 있습니다 SQL 데이터베이스의 개체. 이 작업을 수행 할 수있는 두 가지 방법이 있으며 개발자 "작업"(유지 관리), 메모리 소비 및 성능면에서 더 나은 선택이 될 수있는 몇 가지 정보를 원합니다. 부울 정보 : 속성은 거의 항상 NULL (존재하지 않음)입니다.

(1) ID, 소유자, 날짜, 시간 및 모든 속성이있는 열이없는 큰 테이블은 열 속성이없는 반면 NULL로. 예 :

TABLE_X 
id|owner|date|time|prop_1|prop_2|prop_3|... 

이 테이블에는 많은 NULL 값이 있습니다.

새로운 속성을 첨가해야 내가 ALTER 표를하고 여기에

내가이 "보통"을 할 것마다 새 속성에 대한 새 열을 삽입 할 경우

SELECT * FROM TABLE_X ... 

(2) 내가 것

TABLE_X 
id|owner|date|time 

을 그리고 다음과 같이 모든 속성에 대해 별도의 테이블이 있습니다 : 모든 NOT NULL 데이터를 메인 테이블이

TABLE_X_PROP_N 
foreign_key(TABLE_X(id))|value 

여기에는 전혀 NULL 값이 없습니다. 속성이 값을 갖고 해당 테이블에 있거나 값이 NULL이고 해당 테이블에 나타나지 않습니다.

새 속성을 추가하려면 다른 테이블을 추가하면됩니다. 여기

질문 (그래서 당신은 스크롤 할 필요가 없습니다) 반복하려면

SELECT * FROM TABLE_X LEFT JOIN TABLE_X_PROP_1 ON ... LEFT JOIN TABLE_X_PROP_2 ON ... 

할 것입니다 : 유지 보수 측면에서 더 나은 문제를 다루는 boths 방법 (개발자 용), 메모리 소비 (디스크) 및 성능 (초당 쿼리 수)? 어쩌면 당신도이 문제를 어떻게 처리 할 수 ​​있을지 더 잘 알고있을 것입니다. 미리 감사드립니다.

답변

1

, 내가 생각 : : 그냥 하나 개의 테이블에 모든 것을 넣어 | 소유자 | 날짜 |

TABLE_HEADER
ID를 시간

TABLE_PROPERTY
id | name

TABLE_PROPERTYVALUE
id | headerID (FK) | propertyID (FK) | 값

새 속성을 쉽게 추가 할 수 있으므로 유연성이 향상되고 훨씬 빠르게 반복 할 수 있습니다. 등록 정보의 수는 영향을 미칩니다 (예를 들어 500 개의 등록 정보가있는 경우 500 개의 열이있는 테이블을 원하지 않을 수도 있음). 주된 단점은 복잡한 비즈니스 로직을 속성을 사용하여 복잡한 네비게이션 구조로 연결할 필요가 있고 특정 필드에 대해 null이 아닌 것처럼 데이터 무결성을 적용 할 수없는 경우 추악해진다는 것입니다. 당신이 정말로 당신의 객체 구조에서 모델링 한 것과 같은 속성 가방을 원한다면 쉽게 매핑됩니다. 모든 것과 마찬가지로 가장 적합한 것에 대한 상황에 따라 다릅니다.

+0

arturros에 대한 내 코멘트와 비슷한 답변 내가 TABLE_HEADER에 ID에 대한 여러 속성을 가지고 특정 속성 값을 검색하는 방법을 모르겠습니다. 시각적으로 * I * LEFT JOIN 일 때 시각적으로 서로 옆에 있지만 DB 엔진이이를 수행 할 때도 마찬가지입니까? 열이 무작위 순서가 될 수 없습니까? 예 : id1 | owner1 | date1 | id1propValue1 | id_propName1 | id1 | value1 | id_propName2 | name2 | id_propValue2 | id_propName2 | id1 | value2 ->이 결과에서 prop_2의 값을 얻는 방법 ? – Nogiax

+0

@Nogiax - 개체 구조 (Map properties;)는 속성 봉, 즉 행에 속성을 보유하려는 것을 나타냅니다. 이 옵션은 옵션 2에 적합합니다. 여기서는 조인을 수행하지 않고 대신 머리글과 속성에 대해 2 개의 작은 쿼리를 수행한다고 가정합니다. 논리는 모두 데이터베이스가 아닌 코드에 있습니다. 속성을 조인하여 단일 행 즉 속성을 열로 사용하려는 경우 옵션 1을 사용하면 훨씬 쉽게 쿼리 할 수 ​​있으므로 옵션 1을 사용할 수도 있습니다. – Daniel

+0

설명해 주셔서 감사합니다. 귀하의 접근 방식은 합리적인 것으로 들립니다. 내가 후속 질문 : 만약 내가 TABLE_HEADER에서 모든 행을 선택하고 검색된 행의 수는 X 될 것입니다. 그럼 모든 행에 대한 속성을 얻고 싶습니다.Wouln'td는 모든 객체에 대한 모든 속성을 가져 오기 위해 X 요청을 추가로 수행합니다 (모든 데이터에 대해 1 + X 쿼리를 수행합니다). – Nogiax

1

해결 방법 2. 모든 속성에 대해 별도의 표가없는 이유는 무엇입니까?당신이 3 개 테이블이 필요하면 옵션 2로 가면

properties(
foreign_key(TABLE_X(id)) 
property_name, 
value); 
+0

이것은 생각 일 수 있지만 prop_1 값과 prop_2 값을 구별하는 방법을 잘 모르겠습니다. 내 두 번째 솔루션에서 나는 속성의 이름과 같은 속성의 "값"열의 이름을 지정할 수 있으므로 테이블을 조인 할 때 값은 열 이름과 연결됩니다. 그러나 이것이 당신의 솔루션과 어떻게 작동할까요? 편집 : 나는 이것에 정말로 새로운 것이다. 미안 해요 만약 당신의 솔루션과 함께이 작품을 "명백한" – Nogiax

1

여기 엔 Entity-Attribute-Value (종종 anti-as-an-anti-pattern) 패턴을 구현하려는 것 같습니다. 당신은 그들과 친하십니까? 여기 몇 가지 참조 :

https://softwareengineering.stackexchange.com/questions/93124/eav-is-it-really-bad-in-all-scenarios

http://www.dbforums.com/showthread.php?1619660-OTLT-EAV-design-why-do-people-hate-it

https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model

개인적으로 나는 RDBMS의 설정이 유형의 매우 조심 해요. 나는 NoSQL 문서 스타일 데이터베이스가 이러한 유형의 동적 구조에 더 적합하다고 생각하는 경향이 있지만 실제로 NoSQL에 대한 실제 경험은 비교적 적습니다.

+0

첫 번째 링크에 대한 대답은 반 패턴에 대해서는 아무 것도 말하지 않습니다. 그것은 당연히 (IMO) 개발자가 자신의 고유 한 상황에 대해 판단 할 필요가있는 트레이드 오프뿐 아니라 이익도 있다고 말합니다. 유사하게 세 번째 기사는 그것을 안티 패턴으로 간주하지 않습니다. – Daniel

+0

@ 대니얼 - 나는 동의하지 않습니다 ... (안티)를 사용한 것은 반 패턴으로 간주되는 경우가 더 많다는 것을 더 많이 지적했습니다. 또한 반 패턴으로 간주되기 때문에 상당한 상반 관계가 있다는 사실에 대해 인식을 높이는 것이 더 중요했습니다. 그것을 하나의 자신으로 표시하는 것보다 인식하고 있습니다. – jleach

+0

@ jdl134679 - 감사합니다. 참고 자료를 살펴 보겠습니다. – Nogiax

관련 문제