为什么不选择UUID?ULID才是更好的选择!

ulid:universally unique lexicographically sortable identifier(通用唯一词典分类标识符)
uuid:universally unique identifier(通用唯一标识符)
为什么不选择uuid
uuid 目前有 5 个版本:
版本1:在许多环境中是不切实际的,因为它需要访问唯一的,稳定的mac地址,容易被攻击;
版本2:将版本 1 的时间戳前四位换为 posix 的 uid 或 gid,问题同上;
版本3:基于 md5 哈希算法生成,生成随机分布的id需要唯一的种子,这可能导致许多数据结构碎片化;
版本4:基于随机数或伪随机数生成,除了随机性外没有提供其他信息;
版本5:通过 sha-1 哈希算法生成,生成随机分布的id需要唯一的种子,这可能导致许多数据结构碎片化;
这里面常用的就是 uuid4 了,但是,即使是随机的,但是也是存在冲突的风险。
和 uuid 要么基于随机数,要么基于时间戳不同,ulid 是既基于时间戳又基于随机数,时间戳精确到毫秒,毫秒内有1.21e + 24个随机数,不存在冲突的风险,而且转换成字符串比 uuid 更加友好。
ulid特性:
ulid() # 01arz3ndektsv4rrffq69g5fav  
与uuid的128位兼容性
每毫秒1.21e + 24个唯一ulid
按字典顺序(也就是字母顺序)排序!
规范地编码为26个字符串,而不是uuid的36个字符
使用crockford的base32获得更好的效率和可读性(每个字符5位)
不区分大小写
没有特殊字符(url安全)
单调排序顺序(正确检测并处理相同的毫秒)
ulid规范
以下是在python(ulid-py)中实现的ulid的当前规范。二进制格式已实现
01an4z07by      79ka1307sr9x4mv3|----------|    |----------------| timestamp          randomness  10chars            16chars   48bits             80bits  
组成
时间戳
48位整数
unix时间(以毫秒为单位)
直到公元10889年,空间都不会耗尽。
随机性
80位随机数
如果可能的话,采用加密技术保证随机性
排序
最左边的字符必须排在最前面,最右边的字符必须排在最后(词汇顺序)。必须使用默认的ascii字符集。在同一毫秒内,不能保证排序顺序
编码方式
如图所示,使用了crockford的base32。该字母表不包括字母i,l,o和u,以避免混淆和滥用。
0123456789abcdefghjkmnpqrstvwxyz  
二进制布局和字节顺序
组件被编码为16个八位位组。每个组件都以最高有效字节在前(网络字节顺序)进行编码。
0                   1                   2                   3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                      32_bit_uint_time_high                    |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|     16_bit_uint_time_low      |       16_bit_uint_random      |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                       32_bit_uint_random                      |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                       32_bit_uint_random                      |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
应用场景
替换数据库自增id,无需db参与主键生成
分布式环境下,替换uuid,全局唯一且毫秒精度有序
比如要按日期对数据库进行分区分表,可以使用ulid中嵌入的时间戳来选择正确的分区分表
如果毫秒精度是可以接受的(毫秒内无序),可以按照ulid排序,而不是单独的created_at字段
用法(python)
安装
pip install ulid-py  
创建一个全新的ulid。
时间戳记值(48位)来自 time.time(),精度为毫秒。
随机值(80位)来自 os.urandom()。
>>> import ulid>>> ulid.new()  
根据现有的128位值(例如uuid)创建新的ulid 。
支持ulid值类型有 int,bytes,str,和uuid。
>>> import ulid, uuid>>> value = uuid.uuid4()>>> valueuuid('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')>>> ulid.from_uuid(value)  
从现有时间戳值(例如datetime对象)创建新的ulid 。
支持时间戳值类型有int,float,str,bytes,bytearray,memoryview,datetime,timestamp,和ulid
>>> import datetime, ulid>>> ulid.from_timestamp(datetime.datetime(1999, 1, 1))  
根据现有的随机数创建一个新的ulid。
支持随机值类型有int,float,str,bytes,bytearray,memoryview,randomness,和ulid。
>>> import os, ulid>>> randomness = os.urandom(10)>>> ulid.from_randomness(randomness)>>>   
一旦有了ulid对象,就有多种与之交互的方法。
timestamp()方法将为您提供ulid的前48位的时间戳快照,而randomness()方法将为您提供后80位的随机数快照。
>>> import ulid>>> u = ulid.new()>>> u>>> u.timestamp()>>> u.randomness()


预计2013年末4G LTE流量增幅将达207%
英特尔为云和网络客户提供高度定制和可编程的解决方案
iphone15发布会日期定档9月13日,参数提前知晓!
联发科今日发布游戏手机芯片Helio G90 可能是P90的延伸产品
配电箱电流电压温度监测
为什么不选择UUID?ULID才是更好的选择!
你有见到过最美的c语言代码吗?
德国专家批评奥迪:起诉蔚来是无用功,还可能得罪中国市场!
肉类食品药残检测仪的应用及性能
从美国电源工业发展计划看我国电源工业的发展趋势
大数据有哪一些功能模块
邵广禄:要把云服务成为中国电信的主业
以SimpleLink™ Wi-Fi和MSP432 MCU为特色的物联网开发实验室
处理家务活哪个最给力?三款最尖端技术扫地机器人PK对比体验
机器人发展抓住未来10年智能发展的窗口期是关键
柔宇发布首款可折叠柔性屏手机
耐腐蚀高防水才是智能垃圾回收设备选择工业连接的关键
关于无人机的性能分析和应用简介
基于FPGA的实时图像边缘检测系统设计(附代码)
一文详解Linux PCI驱动框架