python uuid1作为时间戳是连续的吗?
Python声明uuid1使用当前时间来形成uuid值。但我找不到确保UUID1是顺序的引用python uuid1作为时间戳是连续的吗?,python,uuid,Python,Uuid,Python声明uuid1使用当前时间来形成uuid值。但我找不到确保UUID1是顺序的引用 >>> import uuid >>> u1 = uuid.uuid1() >>> u2 = uuid.uuid1() >>> u1 < u2 True >>> 导入uuid >>>u1=uuid.uuid1() >>>u2=uuid.uuid1() >>>u1>> 来自: 根据主机ID、序列号和当前时
>>> import uuid
>>> u1 = uuid.uuid1()
>>> u2 = uuid.uuid1()
>>> u1 < u2
True
>>>
导入uuid
>>>u1=uuid.uuid1()
>>>u2=uuid.uuid1()
>>>u1>>> def test(n):
... old = uuid.uuid1()
... print old
... for x in range(n):
... new = uuid.uuid1()
... if old >= new:
... print "OOops"
... break
... old = new
... print new
>>> test(1000000)
fd4ae687-3619-11e1-8801-c82a1450e52f
OOops
00000035-361a-11e1-bc9f-c82a1450e52f
UUID不连续
不,标准UUID并不意味着是顺序的
显然,有人尝试使用guid(微软对uuid的扭曲)使它们按顺序排列,以帮助在某些数据库场景中提高性能。但是,连续性并不是UUID的意图。
MAC是最后一个,不是第一个
不,在标准UUID中,MAC地址不是第一个组件。MAC地址是版本1 UUID中的最后一个组件。
不要假设UUID是哪种类型的
UUID的各种版本旨在相互兼容。因此,期望您始终拥有版本1 UUID可能是不合理的。其他程序员可能会使用其他版本
规范
请阅读UUID规范。只有十几页长 我偶然发现了一个可能的答案,来自 字典时间序 在所有原语类型中,Cassandra支持类型1(基于时间和服务器)和类型4(随机)的UUID值 UUID(唯一通用标识符)的主要用途是在潜在的分布式环境中获得真正唯一的标识符 Cassandra确实支持版本1 UUID。它通过结合计算机的MAC地址和自公历开始以来的100纳秒间隔数,为您提供一个唯一标识符 正如您所见,精度仅为100纳秒,但幸运的是,它与时钟序列混合,增加了随机性。此外,MAC地址还用于计算UUID,因此在一个计算机集群上发生冲突的可能性很小,除非您需要处理大量数据(别忘了,不是每个人都是Twitter或Facebook) UUID(尤其是TimeUUID)最相关的用例之一是将其用作列键。由于Cassandra列键是排序的,因此我们可以利用此功能对列族进行自然排序 Hector客户端提供的默认com.eaio.uuid.uuid的问题是,它不容易使用。作为一个ID,您可能需要将这个值从服务器带到视图层,这就是问题所在 基本上,com.eaio.uuid.uuid重写toString()以提供uuid的字符串表示形式。但是,此字符串格式无法按字典顺序排序 下面是一些连续生成的TimeUUID:
8e4cab00-c481-11e1-983b-20cf309ff6dc在一些t1
2b6e3160-c482-11e1-addf-20cf309ff6dc在t2>t1的一些t2处
“2b6e3160-c482-11e1-addf-20cf309ff6dc”。相比(“8e4cab00-c481-11e1-983b-20cf309ff6dc”)
给出了-6的含义,即“2b6e3160-c482-11e1-addf-20cf309ff6dc”比“8e4cab00-c481-11e1-983b-20cf309ff6dc”少,这是不正确的
TimeUUID的当前文本显示拆分如下:
time\u low–time\u mid–time\u high\u和\u version–variant\u和\u sequence–节点
如果我们从time\u high\u和\u version开始重新排序,那么我们可以按字典顺序对其排序:
time\u high\u和\u version–time\u mid–time\u low–variant\u和\u sequence–节点
实用程序类别如下所示:
public static String reorderTimeUUId(String originalTimeUUID)
{
StringTokenizer tokens = new StringTokenizer(originalTimeUUID, "-");
if (tokens.countTokens() == 5)
{
String time_low = tokens.nextToken();
String time_mid = tokens.nextToken();
String time_high_and_version = tokens.nextToken();
String variant_and_sequence = tokens.nextToken();
String node = tokens.nextToken();
return time_high_and_version + '-' + time_mid + '-' + time_low + '-' + variant_and_sequence + '-' + node;
}
return originalTimeUUID;
}
时间UUID变为:
11e1-c481-8e4cab00-983b-20cf309ff6dc
11e1-c482-2b6e3160-addf-20cf309ff6dc
现在我们得到:
"11e1-c481-8e4cab00-983b-20cf309ff6dc".compareTo("11e1-c482-2b6e3160-addf-20cf309ff6dc") = -1
无参数使用
uuid.uuid1()
会给出非顺序的结果(),但如果设置clock_seq
或node
参数,则可以很容易地将其设置为顺序(因为在这种情况下uuid1
使用python实现,保证在当前进程中有时间戳
部分uuid):
导入时间
从uuid导入uuid1,获取节点
从随机导入getrandbits
_my_clock_seq=getrandbits(14)
_my_node=getnode()
def顺序_uuid(节点=无):
返回uuid1(节点=节点,时钟顺序=\u我的时钟顺序)
def alt_sequential_uuid(时钟顺序=无):
返回uuid1(节点=_我的节点,时钟顺序=时钟顺序)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
从itertools导入计数
old_n=uuid1()#“本机”
old_s=顺序的_uuid()#顺序的
本机冲突索引=无
t_0=时间。时间()
对于计数()中的x:
new_n=uuid1()
new_s=顺序_uuid()
如果旧索引>新索引而非本机冲突索引:
本机冲突索引=x
如果旧的>=新的:
打印(“OOops:'sequential_uuid()`'的非顺序结果”)
打破
如果(x>=10*0x3fff和time.time()-t\u 0>30)或(本机冲突索引和x>2*本机冲突索引):
打印('sequential_uuid()`'没有问题)
打破
旧的=新的
旧的=新的
打印(f'Conflicts for`uuid.uuid1()`:{bool(原生冲突索引)}')
打印(f“尝试:{x}”)
多流程问题
但是如果您在同一台机器上运行一些并行进程,那么:
- 默认为
的uuid.get\u node()
对于所有进程都是相同的李>node
的成功几率很小clock_seq