【发布时间】:2011-10-22 12:25:57
【问题描述】:
这是一个小设计,在自然键上具有常见的 NOT NULL UNIQUE 约束:
CREATE TABLE 'users' {
id int(10) NOT NULL AUTO_INCREMENT,
name NOT NULL UNIQUE,
email NOT NULL UNIQUE,
pass NOT NULL,
PRIMARY KEY ('id')
}
NOT NULL UNIQUE 约束对我来说似乎是 hackish。拥有不相交的候选键对我来说似乎是非规范化的,并且 UNIQUE 约束似乎是一个臃肿的 O(N) 检查功能,所以我倾向于使用与每个自然键都有关系的设计,将自然键映射到代理键在主要关系中。
CREATE TABLE users {
id int(10) NOT NULL AUTO_INCREMENT,
pass NOT NULL,
PRIMARY KEY ('id')
}
CREATE TABLE user_names {
name NOT NULL,
user_id NOT NULL,
PRIMARY KEY ('name')
}
CREATE TABLE user_emails {
email NOT NULL,
user_id NOT NULL,
PRIMARY KEY ('email')
}
这样,我隐含地对用户的电子邮件和用户名强制执行唯一约束,同时提供能够在 O(ln N + ln M) 时间内使用用户的电子邮件或姓名搜索用户信息的奢侈(我非常喜欢欲望)。
我能看到第一个更常见的设计与第二个设计的性能相匹配的唯一方法是,如果 UNIQUE 约束隐式索引表,以便选择自然键并因此检查其唯一性,则可以完成在 O(ln N) 时间内。
我想我的问题是,关于使用自然键的性能插入和选择,处理具有 3 个或更多由代理键索引的自然键的表的最佳方法是什么?
【问题讨论】:
-
在您的第二个模式中,一个用户 (users.id) 可以有多个姓名和电子邮件。在第一个中,只有一个。正如@dportas 所提到的,在第一个模式名称和电子邮件中强制执行 NOT NULL,在第二个中可以为 NULL - 好吧,缺失。不确定比较这两种模式的性能是否有意义。
-
“有不相交的候选键对我来说似乎是非规范化的” 与许多设计元素不同,规范化是基于形式逻辑的,所以这是事实问题,而不是意见问题。在达到 6NF 之前,拥有多个候选键不会违反规范化规则。 (根据我的经验,这是一种罕见的状态。)我建议您研究规范化,直到拥有多个候选键似乎更正常为止。 (咳嗽)
标签: mysql database-design