我需要对我的一些表的主键使用UUID,因为它们需要在多个客户端数据库中是全局唯一的,并且某些数据需要在某个时候重新合并。
使用VARCHAR(36)列和java版本4UUID随机生成器解决了这个问题,但它的问题是UUID不是连续的,因此这将带来索引和插入的另一个问题,特别是在一些大表(1+百万行)上。
我试图通过用当前时间戳替换UUID中的最高有效位(这些位已经代表了时间戳),来生成一个顺序但随机的UUID。我知道网络上有很多解决方案可以做到这一点,也就是COMB UUID,但奇怪的是,我找不到Java实现它。我认为这将是一个常见的问题。
我在C#上找到了一个有趣的实现:http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database
类似的方法可以满足我的需求,但我很难将其转换为Java,所以如果有人能帮助我,我将不胜感激。我认为大多数问题都是关于高字节顺序/低字节顺序的,因为我认为Java将始终使用高字节顺序,而不是原生操作系统中的那个?我真的不知道该怎么处理这个问题。
我的想法基本上是一样的,使用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)编辑:我很感谢到目前为止的答案,但请理解,我的问题是关于在Java上实现上述算法,而不是为此找到另一个替代方案。我知道还有其他几种可能性,其中提到的包括客户端标识符的一种是我过去使用过的,但我不是很喜欢这个解决方案,它不适用于这个项目,主要是因为两件事:-这可能在客户端数量已知的情况下工作得很好,这意味着我需要为每个客户端生成随机id以使其尽可能唯一这将意味着客户端id前缀需要36个字符,而连续部分需要更多字符这意味着50+字符的主键不是一个好主意。-这不会解决我试图解决的问题,即拥有顺序的主键,一旦你开始将来自不同客户端的记录插入到同一个表中,插入就不再是顺序的,并且你的性能将受到影响。
发布于 2016-03-26 21:26:45
你可能想得太多了。
您似乎有两个要求
每个数据库中的IDs.
我建议您为每个数据库分配一个惟一的标识符,然后附加一个顺序生成的值来获取您的标识符。
例如,如果我有两个数据库A和B:
标识符是全局唯一的,并且是连续的。
实际上,我会将此标识符实现为两列,一列用于DB标识符(例如,A或B),另一列用于序列号(存储为整型)。
您甚至可以将DB标识符的创建推迟到实际上必须在两个数据库之间合并行的时候。
发布于 2016-03-26 20:07:45
如果手动操作UUID,不能保证它们是唯一的-很可能,但不能保证。行越多,命中的机会就越大。
更好的设计是拥有一个多部分的主键,其中包含一个客户端代码和一个使用sequencee对象的递增整数。
如果数据库独立运行,并且仅在聚合时需要唯一性,例如在数据仓库中,则只将客户端代码合并到仓库的加载中。
我相信你回来后会说数据设计是不可变的,你必须为PK使用UUID,但如果你不打算让它们自己随机化,那么这就是错误的设计。
https://stackoverflow.com/questions/36235001
复制相似问题