使用CassandraDB/MongoDB等数据库实现ID自增/序列仿真

11

我正在尝试使用非关系型数据库Cassandra构建小型网络系统(URL缩短),但我遇到了自动生成ID的问题。

有人遇到过这个问题吗?

谢谢。

P.S. UUID对我没有用,我确实需要使用从0到Long.MAX_VALUE(Java)的所有数字,因此我需要像SQL序列那样完全可行的解决方案。

更新:

我不喜欢GUID ID的原因在于我的应用程序范围内。

我的应用程序有URL缩短部分,我需要让URL尽可能短。所以我采用以下方法:我从0开始取数字并将其转换为base64字符串。因此,我得到的URL看起来像mysite.com/QA(其中QA是base64字符串)。

在使用SQL数据库时,这很容易实现,我只需取自动递增的ID,将其转换为URL,并100%确定该URL是唯一的。


请更详细地解释为什么不能使用UUID,以及为什么必须使用非SQL数据库。也许我们可以用另一种方式来解决您的问题。 - Espo
3个回答

4
不清楚Cassandra,但是使用MongoDB可以有一个原子序列(它不会扩展,但在分片环境中,如果查询具有分片字段,则会按预期工作)。
可以使用findandmodify命令来完成。
假设我们有一个名为sequences的特殊集合,并且我们想要为帖子编号(名为postid)创建一个序列,您可以使用类似于此代码的代码:
> db.runCommand( { "findandmodify" : "sequences",
                   "query" : { "name" : "postid"},
                   "update" : { $inc : { "id" : 1 }},
                   "new" : true } );
该命令将原子地返回更新后的(new)文档以及状态。如果命令成功完成,则value字段包含返回的文档。

3

自增ID本质上不易扩展,因为需要单一来源来生成数字。这就是为什么像MongoDB这样的可分片/可复制数据库使用更长的类GUID标识符来表示对象。您为什么如此迫切地需要LONG值呢?

您可能能够使用原子递增来完成,保留旧值,但我不确定。这仅适用于单服务器设置。


感谢您对我的问题源代码的充分理解。请查看更新后的问题描述,谢谢。 - Andriy Kopachevskyy
1
CouchDB 确实有唯一约束,至少在 _id 上。是的,最终一致性模型可能会出现问题,因此这仅适用于单个服务器。 在分布式系统中生成自增 ID 的唯一方法是使用专用的 ID 生成服务器(也称为“单点故障”)。 - wump
Cassandra有设置一致性级别的选项,其中最高的是“ALL”,意思是“确保在响应客户端之前将写入所有<ReplicationFactor>个节点。任何无响应的节点都将导致操作失败。”但是对于大型集群来说,这可能不太好,因为会带来性能开销。 - Andriy Kopachevskyy
@wump。生成自增ID是否意味着您有单点故障? Oracle RAC不能生成序列号吗? - TTT
如果ID不需要严格按顺序生成,那么在多个服务器上生成ID就很容易 - 只需按照最大服务器数量递增而不是递增1,因此使用两个服务器时,一个服务器将返回偶数ID,另一个服务器将返回奇数ID。 - Tom Clarkson
显示剩余6条评论

-1

我不确定我理解你的意思。你使用的是什么编程语言?我们在谈论UUID吗?

以下是一些编程语言中生成UUID的方法:

java.util.UUID.randomUUID(); // (Java) variant 2, version 4

import uuid   // (Python)
uuid.uuid1()  //  version 1

UUID对我来说不起作用,我确实需要使用从0到Long.MAX_VALUE(Java)的所有数字,因此我确实需要像SQL序列一样完全起作用的东西。 - Andriy Kopachevskyy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接