Django UUIDField 如何在 Postgresql 中生成 UUID?

How does a Django UUIDField generate a UUID in Postgresql?

阅读此博客后posthttps://blog.starkandwayne.com/2015/05/23/uuid-primary-keys-in-postgresql/

我想更多地了解 Django 如何生成 uuid,因为我将它们用作我的 pk。好吧,根据文档,https://docs.djangoproject.com/es/1.9/ref/models/fields/#uuidfield, Django is relying on the Python UUID module https://docs.python.org/3/library/uuid.html#uuid.UUID。但是UUID有很多种,我完全不清楚Django中生成的是哪一种,或者如何选择,假设有一个选择。

最后,考虑到博客 post 中指出的碎片问题,并假设 uuid_generate_v1mc 在 Python 或 Django 中不能直接使用,有没有办法强制他们用它?

  • How does Django and or Python generate a UUID in Postgresql?

  • But there are many kinds of UUID, and it is not at all clear to me which one is being generated in Django

当你在Django中使用UUIDField作为主键时,它不会为你生成一个UUID,你在保存对象之前自己生成它

我不知道事情是否发生了变化,但上次我使用了 UUIDField,你必须自己指定 UUID 值(例如,当你创建对象时,Django 不会让您保存一个具有空白 UUID 的对象并让数据库生成一个)。查看 Django 文档示例强化了我的想法,因为它们提供了 default=uuid.uuid4() 例如在主键中。

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
                                                    ^
                                                    |__ calls uuid.uuid4() 

选择哪个UUID版本

要比较不同 UUID 版本的属性,请参阅以下问题:使用哪个 UUID 版本?

对于很多应用来说,UUID4就可以了

如果您只想生成一个 UUID 并继续您的生活,uuid.uuid4() 就像上面的代码片段一样就可以了。 UUID4 是一个随机的 UUID,发生碰撞的可能性很小,所以您真的不需要担心,尤其是如果您没有每秒生成大量碰撞时。

Finally, given the fragmentation issue pointed out in the blog post, and assuming uuid_generate_v1mc is not available directly in Python or Django, is there a way to force them to use it?

A Python UUID1 具有随机 MAC 地址,如 uuid-osspuuid_generate_v1mc

您链接的博客提到了 UUID1 的使用。 Python 的 uuid.uuid1() 采用一个参数来代替默认的真实硬件 MAC 地址(48 位)。因为这些随机位是UUID1的末尾,所以UUID1的第一位可以sequential/timestamp-based来限制索引碎片

所以

uuid.uuid1(random_48_bits)

应该会得到与 uuid_generate_v1mc 类似的结果,后者是具有随机 MAC 地址的 UUID1。

要生成随机的 48 位,作为一个虚拟示例,我们可以使用:

import random
random_48_bits = random.randint(0, 2**48 - 1)

试一试:

>>> import uuid
>>> import random
>>> 2 ** 48 - 1
281474976710655
>>> uuid.uuid1(random.randint(0, 281474976710655))
UUID('c5ecbde1-cbf4-11e5-a759-6096cb89d9a5')

现在用它创建一个函数,并将其用作 Django 的 default UUIDField

自定义 UUID,以及来自 Instagram 的示例

请注意,提出您的自定义 UUID 方案并使用可用位来编码对您的应用程序有用的信息是完全可以的。

例如您可以使用一些位来编码给定用户的国家/地区,一些带有时间戳的位,一些用于随机性等。

您可能想阅读如何 Instagram (built on Django and PostgreSQL) cooked up their own UUID scheme to help with sharding