您对使用 UUID 作为数据库行标识符有什么看法,尤其是在 Web 应用程序中?

为了简单和(假设的)速度,我一直更喜欢使用长整数作为数据库中的主键。但是当对对象实例使用 REST 或类似 Rails 的 URL 方案时,我最终会使用如下网址:

http://example.com/user/783

然后假设还存在 ID 为 782、781、...、2 和 1 的用户。假设有问题的 Web 应用程序足够安全,可以防止人们输入其他号码查看其他用户,而无需授权,一个简单的顺序分配的代理键也会“泄漏”实例总数(比这个更旧),在这种情况下是用户,这可能是特权信息。 (例如,我是用户

请先 登录 后评论

9 个回答

Bryan Roth

我认为在您的情况下使用 GUID 是更好的选择。它占用更多空间,但更安全。

请先 登录 后评论
Dan

我认为这是引起准宗教辩论的问题之一,谈论它几乎是徒劳的。我只想说使用你喜欢的。在 99% 的系统中,无论您使用哪种类型的密钥,都不会出现问题,因此使用一种密钥的好处(在其他帖子中说明)永远不会成为问题。

请先 登录 后评论
SQLMenace

我可以回答您,在 SQL Server 中,如果您使用唯一标识符 (GUID) 数据类型并使用 NEWID() 函数创建值,您将由于页面拆分而获得可怕的碎片。原因是使用 NEWID() 时生成的值不是顺序的。 SQL 2005 添加了 NEWSEQUANTIAL() 函数来解决这个问题

仍然使用 GUID 和 int 的一种方法是在表中有一个 guid 和一个 int,以便 guid 映射到 int。 guid 在外部使用,但在 DB 内部使用 int

例如

457180FB-C2EA-48DF-8BEF-458573DA1C10    1
9A70FF3C-B7DA-4593-93AE-4A8945943C8A    2

1 和 2 将用于连接和 Web 应用程序中的 guid。这个表会很窄,查询起来应该很快

请先 登录 后评论
Andrea Bertani

您可以使用与行号相关但不连续的整数。例如,您可以采用顺序 ID 的 32 位并使用固定方案重新排列它们(例如,位 1 变为位 6,位 2 变为位 15,等等)。
这将是一种双向加密,您将确保两个不同的 ID 将始终具有不同的加密。
如果您花时间生成足够的 ID 并获取架构,显然很容易解码,但是,如果我正确理解您的问题,您只是不想太容易泄露信息。

请先 登录 后评论
Josh

而不是像这样的网址:

http://example.com/user/783

为什么没有:

http://example.com/user/yukondude

哪个对人类更友好并且不会泄露那一点点信息?

请先 登录 后评论
Adam Tuttle

就其价值而言,我已经看到一个长时间运行的存储过程(9 秒)只需从 GUID 主键切换到整数,运行时间就会减少到几百毫秒。这并不是说显示一个 GUID 是一个坏主意,但正如其他人指出的那样,根据定义,加入它们并为它们编制索引不会像使用整数那样快。

请先 登录 后评论
Douglas Tosi

我不能说你问题的网络方面。但是 uuid 非常适合 n 层应用程序。 PK 生成可以是分散的:每个客户端生成自己的 pk,没有冲突的风险。 且速度差异一般较小。

确保您的数据库支持高效的存储数据类型(16 字节、128 位)。 至少你可以用 base64 编码 uuid 字符串并使用 char(22)。

我已经将它们广泛用于 Firebird 并且推荐。

请先 登录 后评论
Marius

我们使用 GUID 作为所有表的主键,因为它兼作 MS SQL Server 复制的 RowGUID。当客户突然在世界的另一个地方开设办事处时,这很容易...

请先 登录 后评论
GateKiller

我使用一个使用整数形式的 UUID 的学生管理系统。他们有一个表,用于保存下一个唯一 ID。

虽然从架构的角度来看这可能是一个好主意,但它使日常工作变得困难。有时需要进行批量插入,而拥有 UUID 会使这变得非常困难,通常需要编写游标而不是简单的 SELECT INTO 语句。

请先 登录 后评论