2012-04-03 45 views
1

我有两种用户的数据库。喜欢的东西:数据库:在哪里把外键放在“有”关系?

User: 
    name: String 
    email: String 

PowerUser 
    address: String 
    paypalAcct: String 

,每一个用户是User,但谁签署了延长服务等人也有PowerUser连接到他们的帐户。我想单独将UserPowerUser分开,因为我认为将User表重新用于已成为PowerUser的人员会很好,因为他们应该拥有所有正常的东西User

这是正确的做法,还是应该将User字段添加到PowerUser表中,并且只使用它?

如果是做正确的事,应该User有一个PowerUser一个外键指向,还是应该PowerUser有一个指向User外键?我想这取决于这些东西应该访问的顺序?在这种情况下,我几乎总是从User开始,检查是否有相关的PowerUser,而不是相反。

如果我把User的外键,那么大量的用户将有一个空外键。如果我将外键放在PowerUsers中,那么它们将全部填满,但是从User s到PowerUser s将需要迭代整个PowerUser的表格。哪个更好?

-Haoyi

回答

2

显而易见的答案是将外键添加到从属表。用户不需要需要 PowerUser信息。

如果我把外键放在PowerUsers中,那么它们全部被填满,但是从用户到PowerUsers需要迭代整个PowerUsers表。

您不需要迭代。您可以通过使用left outer join syntax得到与其电源用户信息的所有用户的列表,如果他们有一个:

select 
    a.id, a.email, a.name, a.email, b.address, b.paypalacct 
from 
    users a 
    left outer join powerusers b on a.id = b.id 

如果你只想要得到电力用户的列表,然后使用一个inner join

select 
    a.id, a.email, a.name, a.email, b.address, b.paypalacct 
from 
    users a 
    inner join powerusers b on a.id = b.id 
1

你nearlly回答自己:

如果你使用一个表,你就会有很多空的。空值不好,特别是索引。所以你最好使用单独的表格。

至于他FK,如果您在PowerUser中添加FK,您将有一个非空列,它可以是第二个表中的主键。因此,为用户查找PowerUser条目非常快。

1

一个容易的可转位的代理键是preferrable(因为它通常是与用户帐号数据):

User: 
    id   INTEGER NOT NULL PRIMARY KEY 
    name   VARCHAR 
    email   VARCHAR 

PowerUser: 
    id   INTEGER NOT NULL PRIMARY KEY REFERENCES(User.id) 
    ... 

从技术上讲,你也可以使用的用户名,但改变的时候,这将导致一个重大的麻烦用户名,迟早会出现在几乎每个用户数据库中。 PRIMARY KEY索引使查找速度足够快,因此没有真正的性能损失。