字符串作为SQL数据库中的主键

时间:2009-02-05 19:40:23

标签: sql database database-design string primary-key

我不熟悉数据库及其工作原理。从性能角度(插入/更新/查询)到主键使用字符串比整数更慢吗?

15 个答案:

答案 0 :(得分:163)

技术上是的,但如果一个字符串有意义成为主键,那么你应该使用它。这一切都取决于您所使用的表的大小以及将成为主键的字符串的长度(较长的字符串==难以比较)。对于具有数百万行的表,我不一定会使用字符串,但是通过在较小的表上使用字符串而获得的性能减慢量对于通过使用不具有整数的整数来说可能会有一些麻烦不是指与数据有关的任何事情。

答案 1 :(得分:63)

使用字符串作为主键的另一个问题是,因为索引不断按顺序排列,当创建一个新键时,该键将在顺序的中间,索引必须重新排序...如果你使用自动数字整数,新密钥只是添加到索引的末尾。

答案 2 :(得分:18)

插入具有聚簇索引的表,其中插入发生在序列的中间不会导致索引被重写。它不会导致包含数据的页面被重写。如果页面上有空间,那么它将被放置在该页面中。将重新格式化单个页面,以将行放在页面中的正确位置。当页面已满时,将发生页面拆分,页面上的一半行转到一页,另一半转到另一页。然后将页面重新链接到包含具有聚簇索引的表数据的页面的链接列表中。最多,您最终将编写2页数据库。

答案 3 :(得分:12)

字符串在连接和现实生活中较慢,它们很少真正独特(即使它们应该是这样)。唯一的好处是,如果您只是为了获取名称而加入主表,它们可以减少连接数。但是,字符串也经常发生变化,从而产生了在公司名称发生变化或结婚时必须修复所有相关记录的问题。这可能是一个巨大的性能损失,如果所有应该以某种方式相关的表都不相关(这种情况比您想象的更频繁),那么您可能也会遇到数据不匹配。从数据完整性的角度以及从性能的角度来看,一个永远不会在记录生命周期内改变的整数是一个更安全的选择。自然键通常不太适合维护数据。

我还想指出,两个世界中最好的通常是使用自动增量键(或在某些特殊情况下,GUID)作为PK,然后在自然键上放置一个唯一索引。您获得更快的连接,您不会获得重复的记录,并且您不必更新一百万个子记录,因为公司名称已更改。

答案 4 :(得分:6)

只要它是独一无二的,您使用什么作为主键并不重要。如果您关心速度或良好的数据库设计,请使用int,除非您计划复制数据,然后使用GUID。

如果这是一个访问数据库或一些小应用程序,那么谁真正关心。我认为我们大多数开发人员在前面打击旧的int或guid的原因是因为项目有一种在我们身上发展的方式,你想让自己成长。

答案 5 :(得分:4)

变量太多。它取决于表的大小,索引,字符串键域的性质......

一般,整数会更快。但差异是否足够大以至于关心?很难说。

另外,你选择琴弦的动机是什么?数字自动增量键通常也很容易 。是语义吗?方便?复制/断开关注?您的回答可能会限制您的选择。这也让人想起你忘记的第三个“混合”选项:Guids。

答案 6 :(得分:4)

在您获得与数据描述的主题一致并且与数据的预期用途相符的简单而合理的设计之前,请不要担心性能。然后,如果出现性能问题,您可以通过调整系统来处理它们。

在这种情况下,使用字符串作为自然主键几乎总是更好,让您可以信任它。如果它是一个字符串,请不要担心,只要该字符串相当短,最多约25个字符。你不会在性能方面付出很大的代价。

数据输入人员或自动数据源是否始终为假定的自然键提供值,或者有时会被省略?输入数据偶尔会出错吗?如果是这样,如何检测和纠正错误?

指定查询的程序员和交互式用户是否能够使用自然键来获得他们想要的内容?

如果你不能相信自然键,那就发明一个代理人。如果你发明一个代理,你也可以发明一个整数。然后你必须担心是否要将代理人隐藏在用户社区之外。一些没有隐瞒代理密钥的开发人员后悔了。

答案 7 :(得分:2)

指数意味着很多比较。

通常,字符串比整数长,并且可以应用校对规则进行比较,因此比较字符串通常比计算比较整数更加计算密集。

但是,有时候,使用字符串作为主键比使用string to numerical id表进行额外连接更快。

答案 8 :(得分:2)

是的,但除非你希望有数百万行,否则不使用基于字符串的密钥,因为它较慢通常是“过早优化”。毕竟,字符串存储为大数字,而数字键通常存储为较小的数字。

但要注意的一件事是,如果在任何键上都有聚簇索引,并且在索引中执行大量非顺序插入操作。写入的每一行都会导致索引重写。如果你正在进行批量插入,这确实可以减慢进程。

答案 9 :(得分:2)

为PK列使用整数的两个原因:

  1. 我们可以为整数字段设置自动增加的标识。

  2. 当我们创建PK时,db会创建一个索引(Cluster或Non Cluster),在将数据存储到表中之前对其进行排序。通过在PK上使用标识,优化程序无需在保存记录之前检查排序顺序。这可以提高大表的性能。

答案 10 :(得分:1)

将字符串作为主键的原因是什么?

我只是将主键设置为自动递增整数字段,并在字符串字段上放置一个索引。

这样,如果您在桌面上进行搜索,它们应该相对较快,并且所有联接和正常查找都不会受到影响。

您还可以控制索引的字符串字段的数量。换句话说,如果您认为这样就足够了,您可以说“仅索引前5个字符”。或者,如果您的数据可能相对相似,则可以索引整个字段。

答案 11 :(得分:1)

从性能角度来看 - 与使用整数(PK)获得的性能相比,是字符串(PK)会降低性能,其中PK --->主键。

从要求的角度来看 - 虽然这不是你问题的一部分,但我还想提一下。当我们在不同的表中处理大量数据时,我们通常会查找可以为特定表设置的可能密钥集。这主要是因为有很多表,并且大多数表或某些表通过某种关系(外键的概念)与另一个表相关。因此,我们实际上不能总是选择一个整数作为主键,而是将3个,4个或5个属性组合作为该表的主键。当我们将记录与其他表相关联时,这些键可以用作外键。这样可以在需要时将记录关联到不同的表中。

因此,对于最佳使用 - 我们总是将1或2个整数与1或2个字符串属性组合在一起,但仅在需要时再次组合。

答案 12 :(得分:0)

数据库中的字符串可能存在很大的误解。几乎每个人都认为数字的数据表表示比字符串更紧凑。他们认为db-s中的数字表示为内存。但事实并非如此。在大多数情况下,数字表示更接近A字符串,如表示其他字符串。

使用数字或字符串的速度更依赖于索引,然后是类型本身。

答案 13 :(得分:0)

默认情况下,ASPNetUserIds是128个字符串,性能很好。

如果密钥 HAS 在表中是唯一的,则它应该是密钥。这就是原因;

主要字符串键=正确的数据库关系,1个字符串键(主要)和1个字符串索引(主要)。

另一个选项是一个典型的int Key,但如果字符串 HAS 是唯一的,你仍然可能需要添加一个索引,因为不停的查询要验证或检查它的唯一性

因此使用 int identity key =不正确的DB关系,1 int key(主要),1 int index(主要),可能是唯一的字符串Index,并且手动必须验证相同的字符串不存在(类似于sql检查的东西也许)。

为了在主键的字符串上使用int获得更好的性能,当字符串 HAS 是唯一的时,它必须是一个非常奇怪的情况。我总是喜欢使用字符串键。并且作为一个好的经验法则,在 NEED 之前不要对数据库进行非规范化。

答案 14 :(得分:0)

我可能会使用整数作为您的主键,然后将您的字符串(我假设它是某种ID)作为单独的列。

create table sample (
  sample_pk             INT NOT NULL AUTO_INCREMENT,
  sample_id             VARCHAR(100) NOT NULL,
  ...
  PRIMARY KEY(sample_pk)
);

您始终可以在字符串(ID)列(其中sample_id = ...)上进行查询并有条件地进行连接。