您的位置:

Python 3 UUID - 生成全球唯一ID的终极解决方案

一、UUID简介

UUID,全称通用唯一标识符,是一个128位长的数字,用于在计算机系统中的标识符上保证唯一性。

在Python 3中,使用uuid模块就能够轻松生成UUID。

import uuid
print(uuid.uuid1())  # 基于时间戳生成
print(uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org'))  # 基于命名空间和字符串生成
print(uuid.uuid4())  # 随机生成
print(uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org'))  # 基于命名空间和字符串生成

uuid1()函数使用的是计算机本地的时间戳和MAC地址来生成UUID,保证同一个计算机上的UUID唯一,但是在不同计算机上生成的UUID可能会有重复。

uuid3()和uuid5()函数,则是基于命名空间和字符串来计算出UUID,保证同一个命名空间内的UUID是唯一的,但是不同命名空间之间的UUID可能会存在重复。

而uuid4()函数则是随机生成UUID,保证UUID的全球唯一性。

二、uuid1()和uuid4()函数详解

随机性与可预测性成为了UUID最为关注的问题,也是使用UUID的最初动因。uuid1()和uuid4()函数虽然都能够生成随机的UUID,但是它们生成UUID的方式又有所不同。

uuid1()函数生成UUID的过程:

1、使用计算机的当前时间和一个随机数生成128位的序列号。
2、将设备的MAC地址插入该序列号中,通过MD5算法生成新的序列号。
3、设置版本位(version bits)为1。
4、设置变体位(variant bits)为计算机MAC地址加密后的值,确保生成UUID的唯一性并防止冲突。

这种方法生成的UUID不仅能保证生成的UUID全球唯一,而且因为加入了MAC地址,从而也能够保证在同一台计算机上生成的UUID是同一份。

uuid4()函数生成UUID的过程:

1、使用随机数生成128位的序列号。
2、设置版本位(version bits)为4。
3、设置变体位(variant bits)为一个固定值,这里就不多讲了。

这种方法生成的UUID是完全随机的,既能够保证全球唯一,也无法预测或重现。

三、UUID和数据库

在使用关系型数据库的时候,会遇到一个需要全局唯一ID的场景。而UUID就是一个非常好的选择。使用UUID作为主键,既能够确保全局唯一性,也能够在分布式系统中避免冲突。

以下是在Python中使用UUID作为主键的示例代码:

import uuid
import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('''CREATE TABLE users
            (id text PRIMARY KEY, name text, email text)''')
c.execute("INSERT INTO users VALUES (?, ?, ?)",
          (str(uuid.uuid4()), 'Alice', 'alice@example.com'))
conn.commit()
conn.close()

在数据库中,主键为UUID的表和主键为整数ID的表没有区别。使用UUID能够带来良好的可扩展性和可移植性,如果你需要将数据迁移到其他的存储系统,也不需要担心ID的重复问题。

四、UUID和Web应用

在Web应用中,UUID也是一个常用的方式来唯一标识一个用户或者一个资源。在Python中,Flask框架提供的session,就是使用UUID来识别和标识用户的。以下是在Flask中开启session的示例代码:

from flask import Flask, session
import uuid
app = Flask(__name__)
app.secret_key = str(uuid.uuid4())

在这段代码中,我们使用uuid.uuid4()生成一个随机的密钥,使用这个密钥来保护session的数据。

另外,在开发RESTful API时,UUID也是一个很好的资源标识方式。以下是使用Django REST framework中使用UUID作为资源ID的示例代码:

from rest_framework import serializers
import uuid
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    id = serializers.UUIDField(default=uuid.uuid4)
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'description']

在这里,我们将Book的id字段设置为UUIDField,并且将默认值设置为uuid.uuid4(),这样就能够自动生成UUID作为资源的唯一ID。

总结

在Python中,使用uuid模块能够方便地生成UUID,而且可以根据需要自行选择生成UUID的方式。在数据库和Web应用中,使用UUID作为唯一标识符,不仅能够满足全局唯一性的要求,还能够避免ID的重复问题,具有很好的可扩展性和可移植性。