如何使用Python为Mongo创建全球唯一的GUID/UUID系统?

10
在Mongo文档中,它声明如下:
_id字段可以是任何类型; 然而,它必须是唯一的。因此,您可以在_id字段中使用UUID而不是BSON ObjectIds(BSON ObjectIds稍微更小;它们不需要全球唯一,只需对于单个 db 集群保持唯一)。当使用UUID时,您的应用程序必须自己生成UUID。理想情况下,UUID然后以[BSON]类型存储以提高效率-但是如果您知道空间和速度不是使用情况的问题,您也可以将其作为十六进制字符串插入。
那么,在这种情况下,是否有人能够为我演示如何创建一个在所有Mongo文档中以[DOCS:BSON]格式呈现的防护性、全球唯一的GUID?我想确保在任何时候都不会出现重复的GUID,即使跨集群。有没有人在处理Mongo和GUIDs时有经验或最佳实践的想法?在插入并生成新的ObjectID之前,使用Mongo的本地ID系统并检查重复是否更容易?

1
想要了解有关GUIDs / UUIDs的更多背景信息,请查看Eric Lippert的一系列博客文章:part 1part 2part 3 - Daniel Pryden
2个回答

8
如果您需要一个唯一的 ID,而不想使用 ObjectId,那么您可能想使用 uuid4:
>>> import pymongo
>>> import uuid
>>> c = pymongo.Connection()
>>> uu = uuid.uuid4()
>>> uu
UUID('14a2aad7-fa01-40a4-8a80-04242b946ee4')
>>> c.test.uuidtest.insert({'_id': uu})
UUID('14a2aad7-fa01-40a4-8a80-04242b946ee4')
>>> c.test.uuidtest.find_one()
{u'_id': UUID('14a2aad7-fa01-40a4-8a80-04242b946ee4')}

这真的很酷,但这样做不会只是用字符串(UUID)替换ObjectID吗? pymongo如何知道UUID是UUID而不是普通字符串? 是否有一种方法可以保留特定于ObjectID的其他属性,例如generation_time? - zakdances
在这种情况下,uuid1不是比uuid4更可取吗? - zakdances
PyMongo将UUID作为BSON二进制存储,具有特定的子类型(3或4,请参阅bson.binary中的文档以获取详细信息)。 MongoDB知道如何处理针对这些子类型(以及更多一些)的查询。当PyMongo解码文档时,它会看到此二进制块的子类型为3或4,并创建一个UUID实例。 - Bernie Hackett
我不确定uuid1是否更为理想。我知道uuid1使用机器的网络地址,这可能会涉及到一些人的隐私问题。 - Bernie Hackett

5

2
PyMongo会自动为您序列化UUID,您无需对其进行任何特殊处理。 - Bernie Hackett
PyMongo 如何知道这是 UUID 而不仅仅是普通字符串? - zakdances
1
因为你将一个 UUID 实例作为输入。 - Mischa Arefiev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接