这是一个小设计,在自然键上有常见的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约束对我来说似乎很苛刻。具有不相交的候选键似乎对我进行了非规范化,并且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约束隐式索引表,以便选择with,并因此检查自然键的唯一性,可以完成在O(恩N)时间。
我想我的问题是,关于性能插入和使用自然键的选择,处理具有3个或更多自然键的表的最佳方法是什么,该自然键由代理键索引?
答案 0 :(得分:1)
您所描述的似乎是6th Normal Form。假设您的原始表是5NF,那么由3个表组成的新模式在6NF中。拥有三个候选密钥并不违反5NF,但会违反6NF。
从数据完整性的角度来看,6NF具有明显的缺点。通常情况下会丢失某些依赖项。例如,您的原始表强制执行每个用户都有名称和密码的约束。你的6NF版本不能这样做 - 如果你想允许插入所有表,至少不能在SQL中。 6NF对某些特定情况(时间数据)很有用,但从数据完整性的角度来看,5NF通常更有用和可取。
这不能回答你的表现问题,但我认为值得指出。
答案 1 :(得分:0)
我认为你正常化太多了。您不仅会因插入/更新而影响性能,因为您现在正在连接3个表而不是在一个表中执行直接插入/选择/更新/删除。
我不同意NOT NULL UNIQUE是hackish但是我觉得奇怪的是名字列上存在这样的约束。