2011-01-27 69 views
5

我有一个用户表useridusername,并且都是唯一的。 在useridusername之间,这会更好地用作外键,为什么? 我的老板想用字符串?这可以吗?外键是字符串还是int首选?

+0

我可以问你为什么在表中有两个独特的列? – 2011-01-27 14:16:45

+2

为什么他不能有两个独特的列。就像有一个ID,电子邮件和用户名。他们可以是独一无二的,不是吗? – 2011-01-27 14:16:45

+0

我承认。愚蠢的问题。只是想知道这两列是否真的描述了同样的事情。 nonnb很好地回答了这个问题。 – 2011-01-27 14:16:45

回答

13

它看起来就像你有两个代理键(int userId)和自然键(charvarchar username怎么说)。任何一列都可以用作表的主键,无论哪种方式,您仍然可以执行其他键的唯一性。

关于Natural和Surrogate Keys之间的权衡问题,有许多现有的讨论 - 您需要决定什么对您有用,以及您的组织内的“标准”是什么。

这里的一些考虑选择一个或其他方式时:

。如果你使用一个用户ID(如AUTO_INCREMENT INT)作为主用代理键(如用户ID INT AUTO_INCREMENT)

的情况下,键,那么引用表MyUsers的所有表将使用UserId作为外键。

可以仍然通过但是使用的附加unique index执行varchar username列的唯一性,例如:

CREATE TABLE `MyUsers` (
    `userId` int NOT NULL AUTO_INCREMENT, 
    `username` varchar(100) NOT NULL, 
    ... other columns 
    PRIMARY KEY(`userId`), 
    UNIQUE KEY UQ_UserName (`username`) 

作为每@Dagon,使用窄的主键(如一个int)具有的性能和存储的好处通过使用更宽的(和可变长度)值,如varchar。这个好处也会影响更多的表格,这些表格参考MyUsers,因为userid的外键会变窄。

此外,如果所有表都通过username耦合到MyUsers,则更改用户名会更不方便(因为否则将违反外键关系)。如果在使用username作为外键的表上需要更新用户名,则需要采用像ON UPDATE CASCADE这样的技术来保持数据完整性。

但是,使用代理整数键,可以更改用户名,而不会影响引用MyUsers(但该更改仍可追踪)的表。

使用自然键(即用户名)

不利的一面是使用代理键,表并通过代理键引用MyUsers总是需要一个连接回到谈判桌,以获得用户名的情况。 Natural key的一个潜在好处是,如果查询只需要引用MyUsers的表中的Username列,那么它不需要回到MyUsers来检索用户名。从某种意义上说,自然键在关键列上提供了一种温和的缓存形式。

更多参考herehere

1

INT意愿指数更快,可能会或可能不会是一个问题,很难根据您所提供

1

一个int为4个字节,一个字符串可以尽可能多的字节,只要你喜欢。因此,int将始终表现更好。除非ofcourse如果你坚持与少于4个字符长:)

除了用户名,你不应该使用的列作为PK/FK如果列中的数据本身可以改变。用户倾向于更改他们的用户名,即使该应用现在不存在该功能,maby也会在几年内完成。当那一天到来时,你可能会有1000个引用该用户表的表,然后你将不得不更新一个事务中的所有1000个表,这很糟糕。

相关问题