我有一个包含两种用户的数据库。类似的东西:
User:
name: String
email: String
PowerUser
address: String
paypalAcct: String
每个用户都是User
,但注册了扩展服务等的用户也会在其帐户中附加PowerUser
。我想将User
和PowerUser
分开,因为我认为对已经成为User
的人重复使用PowerUser
表会很好,因为他们应该有所有正常的东西User
都有。
这是正确的做法,还是应该将User
字段添加到PowerUser
表中并使用它?
如果这是正确的做法,User
应该有一个指向PowerUser
的外键,或者PowerUser
是否有一个指向{{1}的外键}?我猜这取决于这些东西应该访问的顺序?在这种情况下,我几乎总是从User
开始检查是否存在相关的User
,而不是反过来。
如果我将外键放在PowerUser
中,那么大量用户将拥有一个空外键。如果我将外键放在User
中,那么它们都将被填充,但从PowerUsers
到User
s将需要遍历整个PowerUser
表。哪个更好?
答案 0 :(得分: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 :(得分:1)
你快要回答自己了:
如果使用单个表,则会有很多空值。空值不好,特别是用于索引。所以你最好使用一个单独的表。
至于FK,如果你在PowerUser中添加FK,你将拥有一个非空列,它可以是第二个表中的主键。因此,为用户查找PowerUser条目非常快。
答案 2 :(得分:1)
易于索引的代理键是可取的(通常与用户帐户数据一样):
User:
id INTEGER NOT NULL PRIMARY KEY
name VARCHAR
email VARCHAR
PowerUser:
id INTEGER NOT NULL PRIMARY KEY REFERENCES(User.id)
...
从技术上讲,您也可以使用用户名,但这会在更改用户名时引起重大麻烦,并且迟早会出现在几乎所有用户数据库中。 PRIMARY KEY
索引使查找速度足够快,因此没有真正的性能损失。