Idéen
Jeg vil anbefale dig den samme tilgang, som bruges af Instagram . Deres krav ser ud til nøje at følge dine.
Genererede id'er bør kunne sorteres efter tid (så en liste over billed-id'er f.eks. kunne sorteres uden at hente mere information om billederne) ID'er bør ideelt set være 64 bit (for mindre indekser og bedre lagring i systemer som Redis) Systemet bør introduceres som få nye 'bevægelige dele' som muligt – en stor del af, hvordan vi har været i stand til at skalere Instagram med meget få ingeniører, er ved at vælge enkle, letforståelige løsninger, som vi stoler på.
De kom op med et system, der har 41 bit baseret på tidsstemplet, 13 o databasen shard og 10 for en automatisk stigningsdel. Da du ikke ser ud til at bruge skår. Du kan bare have 41 bits for en tidsbaseret komponent og 23 bits valgt tilfældigt. Det giver en yderst usandsynlig 1 ud af 8,3 millioner chance for at få en konflikt, hvis du indsætter poster på samme tid. Men i praksis er du aldrig tilbøjelig til at ramme dette. Lige så hvad med noget kode:
Generering af ID'er
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
Bemærk, START_TIME
i ovenstående kode er et vilkårligt starttidspunkt. Du kan bruge time.time()*1000 , få værdien og indstille den som START_TIME
Bemærk, at reverse_id
metode, jeg har postet, giver dig mulighed for at finde ud af, hvornår posten blev oprettet. Hvis du har brug for at holde styr på disse oplysninger, kan du gøre det uden at skulle tilføje et andet felt til det! Så din primære nøgle er faktisk at gemme din lagerplads i stedet for at øge den!
Modellen
Nu er det sådan, din model ville se ud.
class MyClass(models.Model):
id = models.BigIntegerField(default = fields.make_id, primary_key=True)
Hvis du foretager ændringer i din database uden for django, skal du oprette det, der svarer til make_id
som en sql-funktion
Som en fodnote. Dette er lidt ligesom den tilgang, som Mongodb brugte til at generere dets _ID for hvert objekt.