使用比UUID

时间:2018-04-23 21:06:52

标签: amazon-dynamodb uuid uniqueidentifier hashids

对于支持DyanamoDB的Web应用程序,我需要生成唯一且稳定的URL,以便可靠地引用DynamoDB表中的唯一行。

过去,对于PostgreSQL支持的应用程序,我使用自动递增整数作为主键并使用整数的hashid得到了很好的结果:

In [1]: import hashids

In [2]: hasher = hashids.Hashids(min_length=5, alphabet='abcdefghijklmnopqrstuvwxyz0123456789')

In [3]: hasher.encode(12345)
Out[2]: 'e763y'

然后我会在网址中使用它:

http://example.com/random-mutable-title-e763y/

但是,使用DynamoDB时,没有自动递增的主键和UUIDs are recommended instead

但是,UUID包含128位,并且UUID的哈希值更长:

In [3]: import uuid

In [4]: hasher.encode(uuid.uuid4().int)
Out[4]: '5j257lmv00xwo5pvo132783jv0qkq'

网址过长,或至少是丑陋的:

http://example.com/random-mutable-title-5j257lmv00xwo5pvo132783jv0qkq/

我看到它建议只是mask the UUID

In [5]: hasher.encode((uuid.uuid4().int & (1 << 64) - 1))
Out[5]: 'v0qnq92ml7oj382'

但即使这看起来有点长:

http://example.com/random-mutable-title-v0qnq92ml7oj382/

我可以看到更多的东西:

In [6]: hasher.encode((uuid.uuid4().int & (1 << 32) - 1))
Out[6]: 'lj044pkn'

但这似乎有点危险:

In [7]: len(set(uuid.uuid4().int & (1 << 32) - 1 for _ in range(100000)))
Out[7]: 99999

这里最好/最安全的事情是什么?我预计这个表没有大量的写入负载,所以我是否需要分解并实现带条件写入的自动递增整数方案?

更新

我刚刚意识到如果我右移32位UUID1,它似乎相当独特:

In [8]: len(set(uuid.uuid1().int >> 32 for _ in range(1000000)))
Out[8]: 1000000

但这会回来咬我吗? :d

更新2:

回答评论中的一些问题:

我的申请将是唯一写入此表的人。

该应用程序是用Python编写的。

表的数据模式使用用户标识的散列键和排序键,排序键根据行中存储的内容而变化。假设我正在存储项目中包含的用户记录,用户的项目和文档。我可能最终会有一个全局二级索引来支持基于URL hashid的查询,除非hashid和记录的主键最终是等效的。

该表的常见查询将是:

  1. 用户通过电子邮件(用于登录)由另一个GSI支持
  2. 所有用户(通过哈希键)
  3. 所有用户的项目(使用哈希键和排序键beginswith()
  4. 特定项目(由正在讨论的GSI支持)
  5. 特定项目中的所有文档(哈希键和排序键beginswith()
  6. 个人文件(由正在讨论的GSI支持)

0 个答案:

没有答案