z

自增唯一id(autoincrementing unique identifier)

应用

自增唯一id最常见的应用就是作为关系型数据库的主键,因为主键必须确保每个数据项都有唯一id。

它也可以在不支持自增唯一id的数据库中(比如MongoDB)用来替代唯一id(uniqueidentifier,通常是一个哈希值),为用户提供更好的URL:比如将/topic/4e491e229f328b0cd900010d修改为/topic/10086

定义

一个自增唯一id对象最重要的是保证值的唯一性,要做到这一点,自增id的自增incr操作必须是一个原子操作,它应该能在一个原子时间内完成以下两件事:

  1. 增加id值
  2. 返回当前id值

并且它也没有减法decr和清零reset等操作,因为这些操作破坏了唯一性。

get操作一般只用于内部检查,比如观察值是否溢出,但在一般情况下,自增唯一id对象应该只有一个incr操作。

See also

如果你需要一个非唯一的,带incrresetdecr等操作的计数对象,请参考计数器(counter)

实现

自增唯一id可以用以下两种方式实现:

  1. String类函数: INCRGET
  2. Hash类函数:HINCRBYHGET

String实现

# file: ./z/auid/string_implement.py

from redis import Redis

INITIAL_VALUE = 0

class Auid:
    
    def __init__(self, name, client=Redis()):
        self.name = name
        self.client = client

    def incr(self):
        value = self.client.incr(self.name)
        return int(value)

    def get(self):
        value = self.client.get(self.name)
        return INITIAL_VALUE if value is None else int(value)

Hash实现

# file: ./z/auid/hash_implement.py

from redis import Redis

INITIA_VALUE = 0
INCREMENT = 1
KEY = 'auid'

class Auid:

    def __init__(self, name, client=Redis(), key=KEY):
        self.key = key
        self.name = name
        self.client = client

    def incr(self):
        value = self.client.hincrby(self.key, self.name, INCREMENT)
        return int(value)

    def get(self):
        value = self.client.hget(self.key, self.name)
        return INITIA_VALUE if value is None else int(value)