SQL数据库中的重复/不必要的数据

时间:2009-11-25 01:17:12

标签: sql database-design data-modeling

为多个用户设计新的应用程序/数据库时,通常需要有一个用于用户管理的表。

该表通常始终具有用户名和ID ....

只是为了检查我是不是一个白痴(好吧,你可能仍然这么想!)我刚刚下载并查看了MediaWiki和PHPBB的架构,他们也是这样做的。

当我第一次了解关系数据库时,我总是被告知,一个重要的规则是永远不会重复数据或做任何不必要的事情。

那么,为什么我们将ID作为主键而不是用户名?

我理解它不是唯一的原因(例如SO系列网站),但是在这些应用程序中,它是。

我唯一能想到的是,Select * from xxx where ID="454"代替Select * from xxx where name="some_really_long_name"更快,或者因为名字很长会增加数据库的大小。

这些是唯一的原因,还是我错过了什么?

7 个答案:

答案 0 :(得分:9)

使用整数非智能主键代替唯一文本键的原因:

  1. JOIN和其他查询的速度。

  2. 能够更改文本键值并保持数据库的完整性,而无需更新引用该键的每个表。

  3. 当您的应用程序必须在内存中构建键值列表时,提高代码效率并减少内存开销。

  4. 减少引用密钥的表的大小。

答案 1 :(得分:7)

密钥用于两个完全不同的目的,一个是防止插入重复的行....这并不意味着数据值都是相同的,这意味着这两行代表相同的真实世界实体。只有有意义的 自然键 才能实现此目的 第二个目的是充当从属表中外键列的目标 为此,最窄的(最小字节数)密钥将在与密钥一起使用的索引上生成最佳性能,并在执行搜索时使用。

因此,当自然键由多列组成或非常宽时,有时建议创建第二个备用或 代理 键以用作其他表中FK引用的目标。这通常是在数据库中创建的内部创建的值,它不会暴露在应用程序或系统之外,甚至可能不在数据库组件本身之外。

如果那是唯一的密钥,因为它不是一个有意义的或自然的密钥,它完全不足以确保数据一致性,因为两行代表同一个实体,并且所有属性的区别仅在于无意义代理键,仍然可以插入表中 因此,在这种情况下,最好在桌面上使用 两个 键。

除了经常用于提高性能之外,代理键还有额外的优点(因为它们没有意义),不需要更改。提供最好的自然键,准确而独特地识别实体,永远不需要改变,是一种艺术形式,很容易做得很差。 (SSAN是一个规范示例)然后,如果真实世界实体更改了设计不佳的自然键中使用的任何值,并且您将其用作唯一的键,(因此作为其他地方的FK),您将不得不更改数据库中的任何值,包括在您将其用作外键的所有其他表中。

答案 2 :(得分:4)

  

...为什么我们将ID作为主键而不是用户名?

数据建模的第一条规则是公开您的密钥。这是因为:

  1. 您希望隔离系统,使其无法向无法更改的用户群显示信息。
  2. 存在安全问题:假设您没有采取预防措施,现在您的用户可能会被欺骗
  3. 如果您必须迁移到新数据库,同一供应商或其他 - 转换应该是无缝的。您可能需要更新引用,但用户会注意到它们是昨天的1234和今天的100234。人们有足够的麻烦记住创建强密码......
  4. 基于整数的键更快,占用的空间更少。这些被称为人工键。
  5. 允许某人更改用户名是一个很好的功能;当你的系统处理由于结婚(或离婚)而改变的人名时,这是必要的。
  6. 自然与人工钥匙

    自然键只是一个存在的键,原样或通常持有的约定。例如 - 美国州的缩写是理想的关键因素:

    1. 这是独一无二的
    2. 每个了解美国州的人都会知道缩写。
    3. 人工(AKA代理)密钥与数据没有任何关系 - ID#1234可以引用任何内容。

      理论上,尽可能使用人工密钥。因为ID 1234可能意味着什么,当你使用自然键时,不需要加入就知道给定的id值意味着什么。实际上,由于性能和自然键不常见 - 使用人工键。

答案 3 :(得分:3)

  1. 可以轻松更改/重命名用户名。这非常有用。
  2. 它快一点
  3. 总体而言,它节省了空间/内存(真实,微小数量)
  4. PS:不要忘记在unique列上添加username约束。

答案 4 :(得分:2)

这就是所谓的Surrogate Key。它不是重复数据,而是代表数据。它大部分存在只是因为它更容易,特别是当自然键是多个字段时,然后你必须将它用作另一个表中的外键。

它们很常见,但有healthy debate关于它们是否“正确”的问题。就个人而言,我使用它们只是因为它简化了生活。另一个好处是,如果您使用自然键并且有人输入密钥,则最终必须在多个表中进行级联更新(如果它是外键)。由于不可能输入替代密钥(它是系统生成的),因此这绝不是问题。

答案 5 :(得分:1)

至少有一个原因 - 如果用户名不是主键,则可以便宜地更改用户名。

答案 6 :(得分:1)

一个关键优势是拥有一个单独的ID,您可以在不破坏任何外键关系的情况下更改用户名。

此外,使用没有意义的主键是一个很好的RDBMS实践 - 用户名显然有意义