A ideia
Eu recomendaria a você a mesma abordagem usada pelo Instagram . Suas exigências parecem seguir de perto as suas.
IDs gerados devem ser classificáveis por tempo (para que uma lista de IDs de fotos, por exemplo, possa ser classificada sem buscar mais informações sobre as fotos) IDs devem ser idealmente de 64 bits (para índices menores e melhor armazenamento em sistemas como Redis) O sistema deve apresentar como poucas 'peças móveis' possíveis - grande parte de como conseguimos dimensionar o Instagram com pouquíssimos engenheiros é escolhendo soluções simples e fáceis de entender nas quais confiamos.
Eles criaram um sistema que tem 41 bits com base no timestamp, 13 no fragmento do banco de dados e 10 para uma porção de incremento automático. Desde que você não parece estar usando shards. Você pode ter apenas 41 bits para um copmonent baseado em tempo e 23 bits escolhidos aleatoriamente. Isso produz uma chance extremamente improvável de 1 em 8,3 milhões de obter um conflito se você inserir registros ao mesmo tempo. Mas, na prática, você nunca vai acertar isso. Certo, então que tal algum código:
Gerando IDs
START_TIME = a constant that represents a unix timestamp
def make_id():
'''
inspired by http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
'''
t = int(time.time()*1000) - START_TIME
u = random.SystemRandom().getrandbits(23)
id = (t << 23 ) | u
return id
def reverse_id(id):
t = id >> 23
return t + START_TIME
Observe,
START_TIME
no código acima é algum tempo de início arbitrário. Você pode usar time.time()*1000 , obter o valor e defini-lo como START_TIME
Observe que o
reverse_id
O método que postei permite que você descubra em que momento o registro foi criado. Se você precisar acompanhar essas informações, poderá fazê-lo sem precisar adicionar outro campo para isso! Portanto, sua chave primária está realmente salvando seu armazenamento em vez de aumentá-lo! O modelo
Agora é assim que seu modelo ficaria.
class MyClass(models.Model):
id = models.BigIntegerField(default = fields.make_id, primary_key=True)
Se você fizer alterações em seu banco de dados fora do django, você precisará criar o equivalente a
make_id
como uma função sql Como nota de rodapé. Isso é um pouco parecido com a abordagem usada pelo Mongodb para gerar seu _ID para cada objeto.