SQL - 引用不同表的主键的外键(Postgres)

时间:2012-03-10 17:50:23

标签: sql postgresql foreign-keys multiple-tables

这是一个项目。我正在为办公室编制不同类型记录的数据库。有一个表收集这些记录表的所有主键。所以,我需要有一个引用这些表的外键。而我迷失了。我问了我非常忠诚的朋友谷歌,但我不明白这方面的一些可能的答案。

这就是我的结果(表格的名称不是它们的真实姓名,只是希望它在这里是通用的。)

编辑:我正在使用Postgres

RecordsTable:

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

记录1:

id
attribute2
attribute3

RECORD2:

id
attribute2
attribute3

RECORD3:

attribute2
attribute3

实际上,Record1,Record2和Record3各有30多列(想象出生证明,例如)。

RecordsTable将显示给用户。只有在用户需要编辑内容时才会显示record1-3。

我想,我会记录1-3参考记录稳定,但这对用户来说会很麻烦,因为他/她需要先在recordstable中输入,而这不是记录稳定的。它只是显示在办公室提交的所有记录的摘要,因为同时显示所有这些记录是不好的。

如果有什么不清楚的地方,请告诉我,以便我可以解释一下。 提前致谢

2 个答案:

答案 0 :(得分:1)

好吧,我会删除docId列。您可以根据其在其他表中的存在来判断记录的类型。 It's good practice not to repeat yourself.

要在这三个表中保持id唯一,您需要一个identity列。 (除非您使用的是Oracle或Postgres,否则请编辑您的问题。)因此,用户必须先从Records表中获取记录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

答案 1 :(得分: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

但是如果你有三种内容非常不同的实体,你真的需要一起列出它们吗?也许你不是真的,在这种情况下你可以将它们作为单独的表维护。如果将它们全部列在一起是有意义的,那么概念上就是一个实体(“文档”,通过它的声音)具有三个子类型。让自己变得容易并将它们存储在一个表中,有很多空列(VARCHAR列在空时不占用空间)可能是有意义的。这有点浪费,但今天的计算机有足够的空间和电力,你的时间很宝贵。但是,你反对,

  

只是为了显示在办公室提交的所有记录的摘要,因为同时显示所有这些记录并不好。

这不是问题!仅使用要为摘要显示的列执行SELECT查询。如果用户选择记录,则执行SELECT *并显示完整结果。

如果您确实想要拆分非公共字段,请按上述步骤操作。

基本上,你需要做一些编程。不要将您的数据库设计视为整个程序:数据库的工作是存储数据,应用程序的工作是与它们一起工作。