在SQL数据库中复制/不必要的数据
当为多个用户设计新的应用程序/数据库时,通常需要有一个用于用户管理的表 该表通常总是有用户名和ID 为了确认我不是一个白痴(好吧,你可能仍然这么认为!),我刚刚下载并查看了MediaWiki和PHPBB的模式,他们也做了同样的事情 当我第一次了解关系数据库时,我总是被告知一条重要规则是永远不要复制数据或做任何不必要的事情 那么,为什么我们把ID作为主键而不是用户名呢 我理解其原因,如果它不是唯一的(如SO系列网站),但是在这些应用程序中,它是唯一的 我能想到的唯一一件事是,执行在SQL数据库中复制/不必要的数据,sql,database-design,data-modeling,Sql,Database Design,Data Modeling,当为多个用户设计新的应用程序/数据库时,通常需要有一个用于用户管理的表 该表通常总是有用户名和ID 为了确认我不是一个白痴(好吧,你可能仍然这么认为!),我刚刚下载并查看了MediaWiki和PHPBB的模式,他们也做了同样的事情 当我第一次了解关系数据库时,我总是被告知一条重要规则是永远不要复制数据或做任何不必要的事情 那么,为什么我们把ID作为主键而不是用户名呢 我理解其原因,如果它不是唯一的(如SO系列网站),但是在这些应用程序中,它是唯一的 我能想到的唯一一件事是,执行Select*fr
Select*from xxx where ID=“454”
比Select*from xxx where name=“some\u really\u long\u name”
更快,或者因为名称过长会大大增加数据库大小
这些是唯一的原因吗,还是我遗漏了什么?至少有一个原因-如果用户名不是主键,您可以便宜地更改用户名。这就是所谓的密码。它不是在复制数据,而是在替代数据。它的存在主要是因为它更简单,特别是当自然键是多个字段时,然后您必须在另一个表中将其用作外键
它们是常见的,但它们是否“正确”还有待观察。就我个人而言,我使用它们只是因为它简化了生活。另一个好处是,如果您使用一个自然键,而有人键入了该键,那么如果它是外键,您最终必须跨多个表进行级联更新。因为不可能键入代理密钥(由系统生成),所以这从来都不是问题。一个密钥优势是,通过使用单独的ID,您可以更改用户名,而不会破坏任何外键关系
此外,良好的RDBMS实践是使用没有意义的主键-用户名显然有意义使用整数非智能主键代替唯一文本键的原因:
注意:不要忘记在
用户名
列上添加一个唯一的
约束。键有两个不同的用途,一个是防止插入重复的行。。。。这并不意味着数据值都是相同的,而是意味着这两行代表相同的真实实体。只有有意义的自然键才能做到这一点。第二个目的是充当依赖表中外键列的目标。
为此,最窄的(最小字节数)键将在与该键一起的索引上生成最佳性能,并在执行搜索时使用该索引 因此,当自然键由多列组成,或非常宽时,有时建议创建第二个备用键,或代理键,用作其他表中FK引用的目标。这通常是一个内部创建的值,在数据库中创建,不会暴露在应用程序或系统之外,甚至可能不会暴露在数据库组件本身之外 如果这是唯一的键,因为它不是有意义的键或自然键,那么它完全不足以确保数据的一致性,因为两行表示相同的实体,并且仅通过无意义的代理键在所有属性上有所不同,仍然可以插入表中。
因此,在这种情况下,最好将两个键都放在表上 除了经常用于提高性能外,代理键还有一个额外的优点(因为它们没有意义),即永远不必更改。提出尽可能最好的自然钥匙,准确、唯一地识别实体,并且永远不需要更改,这是一种艺术形式,很容易做得不好。(SSAN是一个典型的例子)然后,如果真实世界的实体更改了设计糟糕的自然键中使用的任何值,并且您将其用作唯一的键(因此在其他地方使用FKs),则必须更改数据库中的所有位置的值,包括将其用作外键的所有其他表中的值 …为什么我们将ID作为主键而不是用户名 数据建模的第一条规则是不公开密钥。这是因为: