我应该将AUTO_INCREMENT id列初始化为2 ^ 32 + 1而不是0吗?

时间:2009-06-12 22:33:59

标签: sql twitter 64-bit primary-key

我正在设计一个新系统来存储短信息[原文如此]。

我将通过数据库中的唯一标识符识别每条消息,并使用AUTO_INCREMENT列生成这些标识符。

传统观点认为从0开始并从那里开始编号我的信息是可以的,但我担心我服务的寿命。如果我创建一个外部API,并将其发送到2 ^ 31条消息,那么使用该API的某些人可能会将我的标识符错误地存储在带符号的32位整数中。在这一点上,他们会溢出或崩溃或发生可怕的事情。如果可能的话,我想避免这种foo-pocalypse。

我应该“更新消息SET id = 2 ^ 32 + 1;”在我启动服务之前,强制每个人从头开始将我的标识符存储为带符号的64位数字?

7 个答案:

答案 0 :(得分:5)

如果您想实现目标并避免克莱图斯提到的问题,解决方案是将您的起始值设置为2 ^ 32 + 1。还有很多ID可用,它不适合32位值,签名或其他。

当然,记录价值范围并为您的API或数据客户提供指导是唯一正确的解决方案。有人会一直试着坚持一个很长的时间,并且想知道为什么它不起作用(总是)

答案 1 :(得分:3)

实际上0对于许多持久性库来说可能会有问题。那是因为他们将它用作某种哨兵值(替代NULL)。无论是对还是错,我都会避免使用0作为主键值。公约将从1开始并上升。对于负数,你可能只是为了让人们感到困惑。

答案 2 :(得分:3)

如果您提供了一组测试套件或测试服务使用“高但仍然有效”范围内的消息并说服您的服务用户使用它来验证其代码是正确的,该怎么办?出于防御原因从任意值开始对我来说有点奇怪;提供健全测试让我感到非常正确。

答案 3 :(得分:1)

如果地球上每个人都活着,每秒钟不停地发送一条消息,那么你的计数器在使用64位整数的年份 2050 之前不会回滚。

可能从1开始就足够了。

(但如果你确实从下限开始,它将延伸到2092年的开始。)

答案 4 :(得分:1)

为什么要使用递增ID?这些都需要锁定,并且会杀死任何通过多台计算机分发服务的计划。我会使用UUID。 API用户可能会将它们存储为不透明的字符串,这意味着如果您愿意,可以稍后更改方案。

如果您想确保消息有订单,请按照链接列表实施排序:

---
id: 61746144-3A3A-5555-4944-3D5343414C41
msg: "Hello, world"
next: 006F6F66-0000-0000-655F-444E53000000
prev: null
posted_by: jrockway
---
id: 006F6F66-0000-0000-655F-444E5300000
msg: "This is my second message EVER!"
next: 00726162-0000-0000-655F-444E53000000
prev: 61746144-3A3A-5555-4944-3D5343414C41
posted_by: jrockway
---
id: 00726162-0000-0000-655F-444E53000000
msg: "OH HAI"
next: null
prev: 006F6F66-0000-0000-655F-444E5300000
posted_by: jrockway

(顺便说一句,如果您实际上将结果作为YAML返回,则可以使用&和*引用而不是仅使用ID作为数据。然后客户端将“免费”获取链接列表结构。 )

答案 5 :(得分:1)

我不明白的一件事是为什么开发人员不会意识到他们不需要公开他们的AUTO_INCREMENT字段。例如,richardtallent提到使用Guids作为主键。我说做得更好。对您的表ID /主键使用64位Int,但也使用GUID或类似的东西作为公开的ID。

示例Message表:

Name           | Data Type
-------------------------------------
Id             | BigInt - Primary Key
Code           | Guid
Message        | Text
DateCreated    | DateTime

然后您的数据如下:

Id | Code                                   Message   DateCreated
-------------------------------------------------------------------------------
1  | 81e3ab7e-dde8-4c43-b9eb-4915966cf2c4 | ....... | 2008-09-25T19:07:32-07:00
2  | c69a5ca7-f984-43dd-8884-c24c7e01720d | ....... | 2007-07-22T18:00:02-07:00
3  | dc17db92-a62a-4571-b5bf-d1619210245a | ....... | 2001-01-09T06:04:22-08:00
4  | 700910f9-a191-4f63-9e80-bdc691b0c67f | ....... | 2004-08-06T15:44:04-07:00
5  | 3b094cf9-f6ab-458e-965d-8bda6afeb54d | ....... | 2005-07-16T18:10:51-07:00

Code是您向公众公开的内容,无论是URL,服务,CSV,Xml等。

答案 6 :(得分:0)

不想成为下一个Twitter,嗯?洛尔

如果您担心可扩展性,请考虑使用GUID(uniqueidentifier)。

它们只有16个字节(bigint的两倍),但它们可以在多个数据库或BL服务器上独立分配,而不必担心冲突。

由于它们是随机的,因此使用NEWSEQUENTIALID()(在SQL Server中)或COMB技术(在您的业务逻辑或MSSQL 2005之前的数据库中)来确保每个GUID都比最后一个“更高”(速度插入到你的桌子)。

如果你从一个高的数字开始,一些“天才”程序员将减去2 ^ 32以将其压缩成int,或者只是忽略第一个数字(“总是相同的”直到你通过第一个数字十亿左右的消息)。