2012-03-10 2 views
1

이것은 프로젝트를위한 것입니다. 나는 사무실을위한 여러 종류의 기록을위한 데이터베이스를 만들고있다. 레코드 테이블의 모든 기본 키를 수집하는 테이블이 있습니다. 따라서 이러한 테이블을 참조하는 외래 키가 필요합니다. 그리고 나는 길을 잃었다. 나는 매우 충직 한 친구 구글에게 물었다. 그러나 나는 이것에 대한 가능한 대답을 이해하지 못했다.SQL - 다른 테이블의 기본 키 (Postgres)를 참조하는 외래 키

다음은 내가 작성한 것입니다 (테이블의 이름은 실제 이름이 아니며 여기서 일반적으로 사용하기를 원합니다).

편집 : 나는 포스트 그레스

을 사용하고

RecordsTable :

recordId -> references record1 id,record2 id,record2 id 
docId -> identifies what kind of record it is 
filingDate 

신기록 :

id 
attribute2 
attribute3 

Record2 :

id 
attribute2 
attribute3 

Record3 :

,451,515,
attribute2 
attribute3 

사실, 신기록, Record2 및 Record3 30 개 이상의 열이 각 (예를 들어, 출생 증명서를 상상)

가 RecordsTable가 사용자에게 표시되는 하나가 될 수 있습니다. 사용자가 무언가를 편집해야하는 경우에만 record1-3이 표시됩니다.

필자는 기록 1-3의 기록 기록을 만들 것이라고 생각했지만 기록 보관소에 처음 입력해야 할 필요가있는 사용자에게는 문제가 될 것입니다. 이는 기록 보관소가 아닌 것입니다. 한 번에 모든 것을 보여주는 것이 좋지 않기 때문에 사무실에 접수 된 모든 기록의 요약을 보여주는 것입니다.

불명확 한 점이 있으면 자세히 설명해주세요. 미리 감사드립니다.

+2

하는가를'RecordsTable' 전혀 존재해야합니다. 개별 레코드 테이블 (및 공통 컬럼) 사이에'UNION ALL '을 수행하는 뷰가 더 나은 목적을 제공하지 않을까요? –

+0

+1 @Damien_The_Unbeliever; 모든 레코드 테이블에서 고유 ID를 사용하면 쿼리가 훨씬 빨라지고 쿼리가 훨씬 간단 해집니다. – Ben

+0

@Ben - 열을 추가한다고 가정합니다. 'TableName'이면'TableName'과'Id'의 조합은 더 이상 노력하지 않고 유일해야합니다. –

답변

0

사용자는 어떤 테이블에 들어가는 지 걱정할 필요가 없습니다. 이는 응용 프로그램의 작업입니다. 당신은 (그리고 그들은 당신이 하나 개의 테이블로 통일 할 수없는 서로 다른 열이) 세 가지 다른 테이블 중 하나를 참조하는 기본 테이블이 필요하면

이 같은 기본 테이블을 설정합니다

RecordsTable: 
Id -> primary key for the table 
docType -> identifies what kind of record it is: 1, 2, or 3 
docID1 -> Foreign key to table1, if docType = 1; NULL otherwise 
docID2 -> Foreign key to table2, if docType = 2; NULL otherwise 
docID3 -> you get the idea 
filingDate 

하지만 내용이 다른 엔티티가 3 종류있는 경우 모두 함께 나열해야합니까? 아마 당신은 정말로 별개의 테이블로 유지할 수 있습니다. 그것들을 모두 함께 나열하는 것이 합리적이라면 개념적으로 3 개의 하위 유형이있는 하나의 엔티티 (그것의 소리에 의해 "문서")가 있습니다. 많은 빈 컬럼을 가진 하나의 테이블에 자신을 쉽게 저장하고 저장할 수 있습니다 (VARCHAR 컬럼은 비어있을 때 공간을 차지하지 않습니다). 조금 낭비이지만 오늘날의 컴퓨터는 공간과 여력을 가지고 있습니다. 시간은 가치가 있습니다. 하지만, 당신은 반대합니다.

단지 모든 것을 한 번에 보여 주면 좋지 않을 것이므로 사무실에 접수 된 모든 기록의 요약을 보여주는 것입니다.

그건 문제가 아닙니다. 요약에 표시 할 열만있는 SELECT 쿼리를 수행하십시오. 사용자가 레코드를 선택하면 SELECT *를 수행하고 전체 결과를 표시합니다.

비표준 필드를 분리하는 문제로 이동하려면 위와 같이하십시오.

기본적으로 약간의 프로그래밍이 필요합니다. 데이터베이스 디자인을 전체 프로그램으로 생각하지 마십시오. 데이터베이스의 작업은 데이터를 저장하는 것이지만 응용 프로그램의 작업은 해당 작업을 수행하는 것입니다.

+1

@ Jinnean 아마도 이것은 효과가 있지만 imho는 매우 섬세한 해결책이 아닙니다. 레코드 테이블을 유지하는 것은 고통입니다. 일부 재 설계로 RecordsTable을 데이터베이스에서 제거 할 수 있습니다. – supertopi

+0

@alexis 예, 나는 그 사용자가 그 것에 대해 걱정하면 안된다는 것을 알고 있습니다. 그래서 나는 그 아이디어를 포기하고 다른 것을 찾고있는 것입니다. 대답은 내가 생각한 답변 중 하나이지만 외래 키는 null이 아니겠습니까? 그게 내가해야 할 일이라면, 그 세 테이블에 합류해야만한다. – Jinnean

+0

@supertopi 나는 또한 레코드를 던지기를 생각하고 모든 ID를 가져 와서 날짜를 기입 한 다음 사용자에게 보여 주도록했다. 하지만 그것은 모든 테이블에 합류해야하고, 날짜별로 정리해야한다는 것을 의미합니다. – Jinnean

1

음, docId 열을 제거합니다. 레코드의 유형을 다른 테이블에있는 레코드의 유형과 함께 알 수 있습니다. It's good practice not to repeat yourself.

id을 3 개의 테이블에서 고유하게 유지하려면 identity 열이 필요합니다. (오라클이나 Postgres를 사용하고 있지 않다면 질문을 편집하십시오.) 그래서 사용자는 세부 정보를 입력하기 전에 레코드 테이블에서 레코드 ID를 얻어야합니다. 아마도이 작업을 수행하는 사용자 인터페이스를 만들 수 있습니다.

RecordsTable: id int identity, filingDate 
Record1: id int foreign key references RecordsTable(id), ... 
Record2: id int foreign key references RecordsTable(id), ... 

당신은 같은 문서 유형 검색 것 :

select case 
     when record1.id is not null then 'Type1' 
     when record2.id is not null then 'Type2' 
     ... 
     else 'Unknown' 
     end 
from RecordsTable rt 
left join 
     Record1 r1 
on  rt.id = r1.id 
left join 
     Record2 r2 
on  rt.id = r2.id 
+0

그래, 포스트그레스를 사용하고 있습니다 – Jinnean

+0

포스트그레스에서는 [시퀀스] (http://www.postgresql.org/docs/8.1/)를 사용할 수 있습니다. static/sql-createsequence.html)을 사용하여 고유 한 ID를 만듭니다. 그래서'RecordTable' 항목을 선택적으로 만들 수 있습니다. – Andomar