RDBM和SQL数据库中有关主键,自动递增和UUID的最佳做法

时间:2018-09-19 21:26:34

标签: sql database-design uuid rdbms

我们正在为用户实体设计一个表。唯一不平凡的要求是应该有一个指向用户实体的永久URL(例如,他们的个人资料)。网络上有很多关于int / long vs UUID的信息。但是我仍然不清楚。

  1. 考虑到配置文件包含私人信息这一事实,在URL中嵌入可预测的ID并不是一个好主意。我说的对吗?
  2. 要满足第一个要求,我可以将主键作为UUID并将其嵌入URL中。但是有两个问题。无论如何,我是否应该担心以UUID作为主键会降低性能?索引,插入,选择,加入?

话虽如此,以下哪一项更好(相对于上述情况)?

CREATE TABLE users(
  pk UUID NOT NULL,
  .....
  PRIMARY KEY(pk)
);

CREATE TABLE users(
  pk INT NOT NULL AUTO_INCREMENT,
  id UUID NOT NULL,
  .....
  PRIMARY KEY(pk),
  UNIQUE(id)
);

4 个答案:

答案 0 :(得分:4)

这实际上是一个选择问题,从我的角度来看,这个问题可以提出基于观点的答案。我经常做的事,即使有多余的工作,我也会在自动增量列上创建主键(我称之为技术键),以使其在数据库中保持一致,并允许“主键”发生更改,以防在设计阶段出现问题,并且还可以减少在其他任何表中外键约束指向键的情况下占用的空间,并且使候选键唯一且不为null。

技术键通常不会显示给最终用户,除非您决定这样做。对于出于某些目的(例如修改日期,创建日期,版本,更改记录的用户等)而仅出于数据库目的保留的其他技术专栏,这可能是相同的。

在这种情况下,我会选择您的第二个选择,但稍作修改:

CREATE TABLE users(
  pk INT NOT NULL AUTO_INCREMENT,
  id UUID NOT NULL,
  .....
  PRIMARY KEY(pk),
  UNIQUE(id)
);

答案 1 :(得分:1)

这个问题是基于观点的,所以这是我的。

我的想法是使用第二个,即与PK分开的UUID。事情是:

  • PK是唯一的,不会向公众公开。
  • UUID是唯一的,并且可能会向公众公开。

如果由于某种原因UUID受到威胁,则需要对其进行更改。更改PK可能很昂贵,并且有很多副作用。如果将UUID与PK分开,则其更改(尽管不容易)的后果要小得多。

答案 2 :(得分:0)

请勿将其设为数据库的主键:这将在将来您要更改数据库技术时引起问题。而且,如果您将其数量增加,您的竞争对手将知道您拥有多少用户,以及您添加新用户的速度如何。

答案 3 :(得分:0)

我看到了一篇很好的文章,它解释了使用 UUID 作为主键的利弊。最后,它建议对外部世界使用 PK 和 UUID 的增量整数。永远不要把你的 PK 暴露在外面。

<块引用>

在几种不同的上下文中使用的一种解决方案对我有用 简而言之,就是同时使用两者。 (请注意:不是一个好的解决方案 - 请参阅 请注意对下面原始帖子的回复)。在内部,让 数据库以小型、高效、数字化的方式管理数据关系 顺序键,无论是 int 还是 bigint。然后添加一列填充 带有 UUID(可能作为插入时的触发器)。范围内 数据库本身,关系可以使用通常的 PK 和 FK。

但是当对数据的引用需要暴露给 外部世界,即使“外部”意味着另一个内部系统,他们 必须仅依赖于 UUID。这样,如果你不得不改变 您的内部主键,您可以确定它的范围仅限于一个 数据库。 (注意:正如 Chris 所观察到的,这完全是错误的)

我们在另一家公司对客户数据使用了这种策略,只是为了避免 “可猜测”的问题。 (注意:避免与阻止不同,请参阅 下面)。

在另一种情况下,我们会生成文本的“slug”(例如在 像这样的博客文章)会使 URL 更人性化一点 友好的。如果我们有重复,我们只会附加一个散列值。

即使作为“辅助主键”,在 字符串形式错误:使用内置数据库机制作为值 存储为 8 字节整数,我希望。

使用整数是因为它们很有效。使用数据库 除了对任何外部引用之外,还实现了 UUID 混淆。

https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439