Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java顺序UUID_Java_Sql_Uuid - Fatal编程技术网

Java顺序UUID

Java顺序UUID,java,sql,uuid,Java,Sql,Uuid,我需要对我的一些表的主键使用UUID,因为它们需要在多个客户机数据库中全局唯一,并且一些数据需要在某个时候合并回来 使用VARCHAR(36)列和java的V4 UUID随机生成器解决了这个问题,但问题是UUID不是顺序的,因此这将带来索引和插入的另一个问题,特别是在一些大型表(100多万行)上 我试图通过用当前时间戳替换UUID中最重要的位(这些位已经代表了时间戳)来生成一个顺序但随机的UUID。我知道web上有很多解决方案可以做到这一点,即COMB UUID,但奇怪的是,我找不到它的Java

我需要对我的一些表的主键使用UUID,因为它们需要在多个客户机数据库中全局唯一,并且一些数据需要在某个时候合并回来

使用VARCHAR(36)列和java的V4 UUID随机生成器解决了这个问题,但问题是UUID不是顺序的,因此这将带来索引和插入的另一个问题,特别是在一些大型表(100多万行)上

我试图通过用当前时间戳替换UUID中最重要的位(这些位已经代表了时间戳)来生成一个顺序但随机的UUID。我知道web上有很多解决方案可以做到这一点,即COMB UUID,但奇怪的是,我找不到它的Java实现。我认为这是一个常见的问题

我在C#上发现了一个有趣的实现:

类似的方法可以满足我的需要,但我很难将其转换为Java,所以如果有人能帮助我,我将不胜感激。我认为大多数问题都是关于big-endian/little-endian的,因为我认为Java将始终使用big-endian,而不是来自本机操作系统的big-endian?我真的不知道该怎么处理

我的想法基本相同,使用UUID.randomUUID()生成一个UUID,然后用System.currentTimeMillis()替换结果id中的MSB。有一件事我不确定,那就是我需要多少字节,因为我认为我们可以用6个字节表示当前的时间戳,而UUID的时间戳部分使用7.5个字节:

time_low               = 4*<hexOctet>
time_mid               = 2*<hexOctet>
time_high_and_version  = 2*<hexOctet> (1 byte for UUI algorithm version)
time\u low=4*
时间=2*
时间\u高\u和\u版本=2*(UUI算法版本为1字节)
编辑:我很感激到目前为止的答案,但请理解,我的问题是关于在Java上实现上述算法,而不是寻找其他替代方法。我知道还有其他几种可能性,其中提到的包含客户标识符的可能性是我过去使用过的,但我不太喜欢这种解决方案,它不适用于本项目,因为主要有两种情况: -当客户机的数量已知时,这可能会很好地工作,但情况并非如此。这意味着我需要为每个客户机生成随机id,使其尽可能唯一。这意味着客户机id前缀为36个字符,顺序部分为更多字符。这意味着50+个字符的主键不是一个好主意。
-这并不能解决我试图解决的问题,即使用顺序主键,一旦开始将来自不同客户端的记录插入到同一个表中,插入将不再是顺序的,并且会影响性能。

如果手动操作UUID,则不能保证它们是唯一的-很可能,但不能保证。行数越多,命中率越高

更好的设计是使用一个多部分主键,它包含一个客户端代码和一个使用sequencee对象的递增整数

如果数据库独立运行,并且在聚合时只需要唯一性,例如在数据仓库中,则只将客户机代码合并到仓库的加载中


我相信你会回来说数据设计是不可变的,你必须使用UUID进行PK,但是如果你不让它们自己随机化,那就是错误的设计。

你可能想得太多了

你似乎有两个要求

  • 全局唯一(在数据库中)ID
  • 在每个数据库中按顺序生成ID
  • 我建议您为每个数据库分配一个唯一的标识符,然后附加一个顺序生成的值以获得标识符

    例如,如果我有两个数据库A和B:

    • A按以下顺序生成标识符:A-1、A-2、A-3等
    • B按以下顺序生成标识符:B-1、B-2、B-3等
    标识符是全局唯一且连续的

    实际上,我将把这个标识符实现为两列,一列用于DB标识符(例如A或B),第二列用于序列号(存储为整数类型)


    您甚至可以延迟DB标识符的创建,直到您实际上必须在两个数据库之间合并行为止。

    您的应用程序服务器是单个进程还是分布式的?如果您使用索引组织的表(即它有聚集索引),UUID只会出现“问题”。如果想避免这种情况,可以使用堆组织的表,它是分布式的。我对数据库模型没有控制权,主键索引是集群的。我不确定这个问题的重点是什么,为了在大型表中获得性能(至少对于btree索引),您必须具有顺序UUID。我想唯一让我困惑的是多个客户端之间的顺序,这实际上可能很难,除非你在数据库中这样做。这里仍然有一个被删除的答案,我希望看到用UUID重新包装和修改。不能保证它们是唯一的,这是一个错误的问题。真的,总是有机会生成重复的。随机化仍然存在,这次我将用另一个仅连续的部分替换基于时间戳生成的部分。确实,冲突的概率可能会增加,但发生这种情况的可能性仍然很小,而且对于这种完全可以接受的应用程序使用,我连续中两次彩票的可能性要比生成重复id的可能性更大。这样看来,您的数据库设计从一开始就受到了影响,去一个基于站点和顺序的两部分PK,并保证唯一性,但不能保证所有插入都是顺序的,这是我的主要问题。