Python生成唯一ID几种方式
我们在实际编程过程中会经常遇到需要用生成唯一ID的场合
例如用户ID,订单编号,发货单号,OSS文件重命名等等...
今天总结一下我目前见过的几种生成id的方式.
1.UUID
最常见的就是UUID.全称叫通用唯一识别码
(英文:Universally Unique Identifier,缩写:UUID)
- `UUID1:保证全球范围内的唯一性
- UUID2:算法与uuid1相同,不同的是把时间戳的前4位置换为POSIX的UID(Python不支持)
- UUID3:通过计算名字和命名空间的MD5散列值得到,保证同一命名空间中不同名字的唯一性,和不同命名空间的唯一性,同一命名空间的同一名字会生成相同的uuid
- UUID4:由伪随机数得到,有一定的重复概率,该概率可以计算出来
- uuid.uuid5:算法与uuid3相同,不同的是使用 Secure Hash Algorithm 1 算法
小结:在大型系统里,UUID其实不太适合作为主要数据的唯一ID,特别是用户ID,订单ID等等。
因为在我们在数据库里通常会对这些数据字段做了索引以便于系统进行频繁的查询,而在很大的数据体量里,一串32位长度的随机字符串作为索引就是一个灾难,我们一般不建议在非线性数据的字段上做索引,这样效率会非常低。
2.根据当前时间生成id
适用于对于业务场景id唯一性要求不高的,比如文件重命名等等
# 1.使用time,hashlib
import time, hashlib
def create_id():
m = hashlib.md5(str(time.perf_counter()).encode("utf-8"))
return m.hexdigest()
print(type(create_id()))
print(create_id())
# 2.使用time生成时间戳
time_stamp = int(time.time())
print(time_stamp)
print(type(time_stamp))
3.数据库主键自增ID
在数据库每一个表里都有一个名为id的字段,它也被称之为主键ID,它的特点是从1开始,当每新增一条数据,id里的值就会自动加1,因为它的内容是int类型的且数据具有连续性,适合用来作为索引
但是如果数据库数据量过大,分表存储的问题,在多张表的情况下,如何划分自增ID是一个很麻烦的问题
安全性问题:客户端可以根据自增ID很轻易猜出我们的业务数据,按照顺序遍历就是了。
4.mongodb的ObjectId
mongodb
的ObjectId
和uuid
一样,还是存在相同的问题
import bson
create_id = bson.ObjectId()
print(create_id)
5.雪花算法
twitter(推特)前些年把自己的唯一ID生成算法开源了,也叫做雪花算法,取自(世界上没有一片相同的雪花)。
1.原理
Snowflake是Twitter提出的一个算法,其目的是生成一个64位的整数;
0b11111110101111100001010000100000000100010000000010000000000001
1位:一般是符号位,不做处理
41位:用来记录时间戳(可以记录69年)
10位:前五位(机房编号/数据中心)后五位(机器编号)
12位:循环位(随机数),对于同一毫秒产生的不同id,12位最高可以记录4095个,也就是最多记录4095个,超过的需要的下一毫秒
2.基本使用
下载库
pip install pysnowflake
启动服务
启动pysnowflake —pysnowflake基于Tornado开发,启动时相当于一个服务
#安装完成后,就可以在本地命令行启动snowflake服务
# win
snowflake_start_server --worker=1
nohup snowflake_start_server --address=127.0.0.1 --port=8910 --dc=1 --worker=1 --log_file_prefix=/tmp/pysnowflask.log>/dev/null &
参数:
snowflake_start_server \
--address=0.0.0.0 \
--port=8910 \
--dc=1 \
--worker=1 \
--log_file_prefix=/tmp/pysnowflask.log
参数说明:可以通过–help查看
—address:本机的IP地址默认localhost
—dc:数据中心唯一标识符默认为0
—worker:工作者唯一标识符默认为0
—log_file_prefix:日志文件所在位置
生成唯一id:
# 生成唯一id
import snowflake.client
def get_snowflake_uuid():
guid = snowflake.client.get_guid()
return guid
print(get_snowflake_uuid()) # 4650391352096329729
# 解析成二进制
print(bin(4589032814791368705))
# 0b11111110101111100001010000100000000100010000000010000000000001
# 可以看到上文所述的第一位是标识符,此后是41位的时间戳,紧接着10位的节点标识码,最后12位的递增序列,从后面数12位是:000000000001,再数5位是:00010 这5位就是某个节点的存储标识,但是它目前是二进制,我们再将它转换为十进制
print(int('00010', 2))
其他可以提供的参考:
版权声明:
作者:淘小欣
链接:https://blog.taoxiaoxin.club/138.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。

共有 0 条评论