【发布时间】:2013-08-13 17:43:12
【问题描述】:
在大多数情况下,在开发数据库设计时,我们都会将主键设置为整数类型,用于表中的唯一标识符。为什么不使用字符串或浮点数作为主键?这是否会影响值的可访问性,或者简单地说检索速度?有什么具体原因吗?
【问题讨论】:
标签: sql database-design
在大多数情况下,在开发数据库设计时,我们都会将主键设置为整数类型,用于表中的唯一标识符。为什么不使用字符串或浮点数作为主键?这是否会影响值的可访问性,或者简单地说检索速度?有什么具体原因吗?
【问题讨论】:
标签: sql database-design
整数将比字符串使用更少的磁盘空间,从而为您提供更小的索引文件来搜索。这对于希望在 RAM 中缓存尽可能多的索引的大型表很重要。
此外,它们可以自动递增,因此您无需编写自己的例程来生成密钥。
您通常希望拥有一个技术密钥(也称为代理密钥),该密钥仅用于标识行而不用于其他任何内容。大多数数据迟早会因您无法控制的原因发生变化,并且您不想到处更新。即使是国家分配的个人身份证号码等看似静态的数据也可能会发生变化(如果您获得新身份),或者可能有法律禁止使用它们。但是,您生成的密钥由您自己控制。对于这样的代理键,拥有一个易于生成的小键是很有用的。
至于“浮动为主键”:不要这样做。主键应该唯一标识一行。浮点数没有相等关系,这意味着您不能安全地比较两个浮点值是否相等。这是浮点值的固有缺点。如果您需要小数,请改用定点数类型。
【讨论】:
主键应该是一个索引,它可以提供一种访问表中特定行的唯一方式。主键可以是大多数数据类型(实际应用中,float/double 不会很好用),主键也可以是复合键(由几列组成)
如果您仔细检查表中的数据,您可能会找到一个数据项,该数据项对于表中的每一行都是唯一的,从而消除了像您在一些模式。
如果您在制造环境中,它可能是一个字母数字字段,例如零件编号或装配标识符。零售或仓储应用程序可能具有库存编号或库存编号/装运/制造商的组合。
一般来说,如果您的表中的某些数据应该是唯一标识符,它可能会很好地用作您的表的主键。
使用表中存在的数据已经完全消除了“组成”一个值(例如自增列)并将其用作主键的要求。这节省了空间,因为它在表中少了一列,在表上少了一个索引。
是的,根据我的经验,整数键几乎总是更快,因为数据库引擎比较整数比比较字符串更有效。根据数据的“唯一性”(技术上称为基数http://en.wikipedia.org/wiki/Cardinality_(SQL_statements)),字符键与整数键的效果是名义上的。
字符键可能会降低性能,具体取决于数据库需要比较的字符数以确定键是否相等。在病态的情况下,想象一个只有右侧不同的一百个字符的字段。一行有 100 个 A。我们需要将其与一个有 99 个 A 和一个 B 作为最后一个字符的键进行比较。从概念上讲,数据库从左到右比较字符字段,就像strcmp()(如果您愿意,strncmp())。
祝你好运!
【讨论】:
唯一的原因是性能。
逻辑数据库设计应该指定哪些“真实”列是唯一的,但是当逻辑设计转换为物理设计时,传统上不使用这些“自然”键中的任何一个作为主键;相反,为此添加了一个无意义的整数列 - 称为“代理键”。
通常,设计人员会为逻辑设计中指定的“真实”唯一性业务规则添加更多唯一性约束。
这是因为大多数 DBMS 在更新主键时遇到问题(例如,由于级联更新到子表时的性能问题)。一些 DBMS 可能根本不支持非整数主键。
一些旁注:
没有理论上的原因 主键应该是不可变的。
这与 标准化,这发生在 逻辑模型(不应该 有代理键)。
另外,请注意 “主”键不是关系 概念 - 它只是一种方式 表示“首选”唯一性 约束,也许是关系 完整性 - 但没有任何东西 说你必须使用的 RM 每个子表的键相同。
我已将自然键创建为“主要 以前在 Oracle 数据库中的键”, 尽管很少。我什至有过它们 用于外键约束。 诚然,他们要么 不可变的,或者我手写的 更新级联代码;我有 一个前端的麻烦 PK 包含的应用程序 日期列。
底线:代理键没有理论上的要求,但它们比替代键实用得多。
【讨论】:
我怀疑这是因为我们可以自动增加整数值,因此很容易为每个插入生成一个新的唯一键。
【讨论】:
许多常见的 ORM (Object Relational Mapping) 工具要么强制使用,要么至少推荐使用整数作为主键。
与字符串相比,整数主键还可以节省空间,并且整数主键在某些情况下也更快。至少在您不使用分布式数据库的情况下,序列或自动递增字段可以轻松生成整数主键。
【讨论】:
这些是我认为我们将整数/数字作为主键的一些主要原因。
1.主键应该能够唯一地定义您的行并且应该是不可变的。使用真实属性(名称等)的问题之一是它们可能会随着时间而改变。在这种情况下保持关系完整性将非常困难,因为这种更改需要级联到所有子记录。
2.如果我们使用数字作为选项卡的键,表格的大小和索引会更小。e
3.由于这些是使用序列自动生成的,因此我们可以确保这些值在所有情况下都是唯一的。
检查这个。 http://forums.oracle.com/forums/thread.jspa?messageID=3916511�
【讨论】: