电子邮件地址是唯一键还是主键?


11

我是数据库的新手。我四处阅读,发现使用电子邮件地址作为主键可能不是一个好主意,因为字符串比较慢,这会影响复杂连接中的性能;如果电子邮件发生更改,我必须更改所有外键,这需要很多工作努力。

但是,如果我的用户表要求每个用户都有一个电子邮件地址,并且每个电子邮件地址都应该是唯一的,那么在电子邮件列上添加唯一索引就足够了吗?因为afaik唯一字段允许空值,而我要求每个用户都有一个电子邮件地址,但不允许空值。我在这里想念什么吗?或者我想使电子邮件列唯一,并确保在服务器上的数据验证期间用户确实输入了电子邮件地址,以便每个用户都有一个电子邮件地址?


3
用户更改其电子邮件地址时会发生什么-因为他们将例如更改工作
user151019 2014年

1
字符串比较不仅较慢,而且字符串也往往比整数大,因此您可以在内存中的页面上容纳更少的内容,从而增加了查询的逻辑读取量。
匿名2014年

Answers:


7

首先让我们区分键和索引,键是逻辑模型的一部分,通常使用唯一索引来实现。但是,您可以创建唯一索引而不创建键,但是不能由外键引用。

候选键可以唯一地标识表中的行,在SQL中,候选键中的一个通常用作主键(我从不真正理解为什么ck中的一个被认为比其他人“更好”,但是那是另一个故事),剩下的ck成为唯一约束。

可以使用与主键相同的方式来使用唯一约束。考虑:

create table A ( x ... not null
               , y ... not null
               , z ... not null
               ,     unique (x)
               ,     primary key (y,z) );

create table B ( x ...
               ,   ...
               ,     foreign key (x) references A (x) );

create table C ( y ...
               , z ...
               ,   ...
               ,     foreign key (y, z) references A (y, z) );  

B引用唯一约束,C引用主键约束。

NOT NULL是另一种约束。根据您的情况,您可以对电子邮件强制执行此操作,而无需声明其唯一性。

帖子的下一个方面涉及密钥的稳定性,密钥应该是稳定的(但这并不意味着它永远不能更改,它不必是不变的)。一些DBMS实现了ON UPDATE CASCADE,它可以为此类操作提供帮助,但是即使密钥在您的模型中分布,更新它也会很麻烦。

在您的情况下,我可能会选择另一个候选键作为主键,并声明email为NOT NULL和UNIQUE。


1
在SQL Server中,您可以将唯一索引引用为FK。
马丁·史密斯

1
我无权访问sql,所以无法自行检查,在创建唯一索引时是否隐式创建了唯一约束?
Lennart 2014年

1
不能。唯一约束的处理略有不同,与唯一索引相比,它具有一些其他元数据和其他限制,但是SQL Server允许在FK中使用其中一种。
马丁·史密斯

1
那时有点奇怪,在sql标准中甚至都没有提到索引,而键是它的核心部分。无论如何,感谢您提供的信息。
Lennart 2014年

值得注意的是,如果有很多外键键入到您的电子邮件中的记录,则在更新级联时,更新所有这些记录可能会花费相当多的时间。
cimmanon 2014年

6

是的,在EmailAddress列上具有唯一索引应该可以。唯一的问题是,如果有人在注册您的服务后放弃了该电子邮件地址,但没有告诉您,则该电子邮件地址的所有者将尝试注册。但这是一个非常罕见的边缘情况。

关于唯一索引是否允许空值,这将取决于您的数据库平台。Oracle确实如此,SQL Server允许单个NULL值。您可以通过使列不允许使用NULL值,然后在其上构建唯一索引来解决此问题。


1
关于SQL Server并非如此。您可以创建带有where子句的索引,例如,这些子句允许您NULL从索引中排除值。
Kirk Woll 2014年

1
该说法SQL Server allows a single NULL value仍然正确。它没有说没有办法获取多个NULL值。我认为答案是试图使答案保持简单,而不是解释额外的细节(如过滤索引)。
布兰登2014年

1
是的,我本来可以过滤掉整个过滤索引的兔子,但是一个简单的问题通常需要一个简单的答案。如果没有数据库平台和版本,我的回答将保持通用。
mrdenny

2

在EmailAddress上具有唯一索引很好。

正如您已经说过的那样,您的应用程序中存在将“电子邮件地址”作为必填字段的验证,我想说,由于另一个验证来自数据库,因此不接受没有电子邮件地址的用户,并且也防止重复输入,并且这些验证将与此唯一索引一起强加。

如针对SQL Server的其他答案所述,您需要在建立唯一索引之前使一列不允许空值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.