2012-06-15 5 views
2

나는 세 개의 열 표, 있다고 가정 ID (기본 키, 신원), A, 지금 Bnull 값

을, 그들은 일반적인 칼럼 - 아무것도 공유하지 가정, 나는 3 가지 방법이 있다고 가정 현명 :

방법 1 : C, D, E

방법 2 : F, G, H, I가

방법 3 : J

I 한 테이블 할 수 : ID를하는 ,

여기서 M은 메소드 (또는 메소드 ID)의 이름입니다.

그러나 방법 3의 90 %가 사용되면 많은 null 값이 있습니다.
이것이 문제입니까? 그렇다면 이것을 설정하는 더 좋은 방법이 있습니까?

각 메소드를 자체 테이블 엔티티로 만들면 각 ID에 정확히 일치하는 메소드가 하나씩 있는지 확인하려면 어떻게해야합니까?

하나의 테이블로 유지한다면 M이 1이면 C, D, E 만 채워지고 F 쓰루 J는 NULL인지 확인하려면 어떻게해야합니까? OK


, 일부 사람들이하기 어려운 추상적으로 생각했던 것 같다, 그래서 나는 위의 적용 임의의 구체적인 예를 만듭니다 : 운동을 수행하는 사람들의

한다고 가정 내가 가진 기록을.
각 레코드에는 항상 이벤트를 고유하게 식별하는 ID (TIME_STARTED 및 TIME_ENDED)가 있습니다.

그러나 어떤 운동을했는지에 따라 다른 속성이 필요할 수 있습니다.

타원형 : 세 개의 연습이 있었다 가정 INCLINE, LEVEL, SPEED는

철커덕 : User_Weight, 담당자, 지연, Extra_Weight

죽은 리프트 : 각 ID의 경우

을 Weight_Lifted 만이있을 수 있습니다 하나의 "방법". 이것을 적용하면 위의 질문을 참조하십시오.

+3

방법으로 무엇을 의미합니까? 테이블에 ID, A, B 만 있으면 c, d, e, f, g, h, i, j, m은 어디에서 왔습니까? – YavgenyP

+3

여기에 잘못된 질문을하고있을 수 있습니다. "X 데이터를 저장해야합니다. 최적의 스키마는 무엇입니까?" 문맥이 없기 때문에 도움이 되기는 어렵 기 때문에 ABCDEFGHIJM이 무엇인지 전혀 모르겠지만 아주 잘못된 방향으로 가고있는 것처럼 들립니다. –

+0

시운전을 기록하고 ID, A 및 B가 항상 모든 실행의 일부라고 가정합니다. 그러나 실행이 방법 1로 수행 된 경우 C, D 및 E 열에 값을 저장해야합니다. 두 번째 방법이 F, G, H, I 등의 열을 필요로하는 경우와 다른 데이터 유형이 될 수 있습니다. – user17753

답변

3

여기에 supertype/subtype 상황이있는 것 같습니다. 이 경우, Table1에는 상위 유형이 있으며, 각 부속 유형을 보유 할 다른 테이블을 작성하려고합니다. 이 부속 유형 테이블의 PK는 또한 수퍼 유형 테이블에 대한 FK입니다.

Supertype_table 
| ID(PK) | A | B | 

Subtype1_table 
| ID(PK&FK) | C | D | E | 

Subtype2_table 
| ID(PK&FK) | F | G | H | I | 

Subtype3_table 
| ID(PK&FK) | J | 

이 스키마의 요점은 당신이 주로 널되는 행 무리가없는 있는지 확인하는 것입니다 : 그래서 당신이 뭔가를 할 것입니다. 각 방법에 대해 적절한 테이블을 삽입/업데이트하는 별도의 쿼리를 작성해야합니다.

SELECT ID, A, B, J 
FROM MyView 
WHERE J is not null 

편집 : OP의 의견를 들어 당신이 단지 같은 것을 쓸 수 그럼

CREATE VIEW MyView 
SELECT Super.ID, Super.A, Super.B, 
Sub1.C, Sub1.D, Sub1.E, 
Sub2.F, Sub2.G, Sub2.H, Sub2.I, 
Sub3.J 
FROM Supertype_table as Super 
LEFT OUTER JOIN Subtype1_table as Sub1 on Super.ID = Sub1.ID 
LEFT OUTER JOIN Subtype2_table as Sub2 on Super.ID = Sub2.ID 
LEFT OUTER JOIN Subtype3_table as Sub3 on Super.ID = Sub3.ID 

: SQL 서버로, 당신은 모든 테이블을 결합 떨어진 조인을 추상화보기를 할 수 있습니다

각 ID가 하나의 테이블에 있는지 확인하려면 상위 유형 테이블에 일종의 식별자가 필요합니다. 당신이 유형 ID라는 열을했다 그렇다면, 당신은 함수를 만들 것입니다 : 그 사용, 그리고

CREATE FUNCTION [dbo].[SubtypeofSuperID](@ID int) 
RETURNS int 
AS 
BEGIN 
    DECLARE @TypeID int; 

    SELECT @TypeID = TypeID 
    FROM Supertype_table 
    WHERE ID = @ID 

    RETURN @TypeID 
END 

을, 당신은 하위 테이블의 각에 수표를 만들 수 있습니다

ALTER TABLE Subtype1_table CONSTRAINT [CK_CorrectSubtype1] 
CHECK ([dbo].[SubtypeofSuperID]([ID]) = 1) 
ALTER TABLE Subtype2_table CONSTRAINT [CK_CorrectSubtype2] 
CHECK ([dbo].[SubtypeofSuperID]([ID]) = 2) 
ALTER TABLE Subtype3_table CONSTRAINT [CK_CorrectSubtype3] 
CHECK ([dbo].[SubtypeofSuperID]([ID]) = 3) 
+0

처음에는 이런 생각을하고 있었지만, 내가 가지고 있었던 문제가 하나 있습니다. 여러 개의 부속 유형 테이블이 모두 동일한 수퍼 유형 행을 가리킬 수있었습니다. 정확히 하나의 Supertype 행이 하나의 부속 유형 테이블 (및 해당 테이블 내의 행)에만 적용되는지 확인하십시오. 예 : – user17753

+0

연결이 끊어진 서브 타입이 필요하다면, 서브 타입 식별자로 작동하기 위해 Supertype의 컬럼을 사용하고 싶습니다. 내 마지막에 논리 검사를 기반으로 삽입을 시행합니까? 또는 DB가 이러한 삽입을 자동으로 허용하지 않도록 설정할 수 있습니까? – user17753

+1

명시 적으로 확인해야합니다. 함수 + check 메소드를 사용하면 저에게 적합합니다. 또한 클라이언트 코드에서 확인 작업을 수행하여 사용자가 예상하지 못한 작업을 시도 할 때 오류 메시지가 표시되도록해야합니다. 나에게있어 DB 수표는 마지막 방어선이다. – Jason

1

몇 가지 방법을 ...

우선 제이슨의 대답은 여러 가지 테이블로 디자인을 깨뜨리는 것 중 하나입니다. 이는 대부분의 작업에있어 매우 좋은 접근 방법입니다. 당신은 마지막 필드에 이름 - 값 쌍의 문자열을 가질 수

1)

대안 (더 '정상화'접근 일명). 예 :

ID Method DateTimeStart DateTimeEnd ValueString 
1 1  2012-01-01... 2012-01-01... C:value,D:value,E:value 
2 2  2012-01-01... 2012-01-01... F:value,G:value,H:value,I:value 

이렇게하면 값 유형을 미리 계획 할 수없는 경우에 편리 할 수 ​​있습니다. 예를 들어, 방법 1에 'W'값을 기록하기 위해 비행을 결정할 수 있어야하고, 정규화 된 설계에서해야하는 것처럼 구조적 수정을 수행하는 것은 불가능합니다.

이것은 전자 서명 양식 개발자가 사용하는 일반적인 방법입니다. 누군가가 기입하고 승인을 위해 전자적으로 라우트하는 "부서 휴가 요청"과 같은 웹 양식을 상상할 수 있습니다. 그 다음에 고객이 "주문서"웹 양식을 작성하기를 원합니다.이 양식에는 기록해야 할 값이 다른 필드 &이 있습니다. 여기에 새로운 테이블을 만들거나 기존 테이블에 열을 추가하는 대신 이름 - 값 쌍 모델을 사용하여 모든 테이블 데이터를 같은 테이블에 저장합니다.

2) 단일 큰 테이블에서 인서트를 실행중인 사람/프로세스를 신뢰하지 않으면 테이블 트리거를 사용하여 무결성을 적용 할 수 있습니다. 예를 들어, 업데이트 전 트리거가 메소드 번호를 확인한 다음 부적절한 데이터 값을 무효화하여 개인 또는 프로세스가 삽입하려고 시도한 데이터를 수정할 수 있습니다.

FWIW