Idén
Jag skulle rekommendera dig samma tillvägagångssätt som används av Instagram . Deras krav verkar följa dina.
Genererade ID:n bör kunna sorteras efter tid (så att en lista med foto-ID:n, till exempel, skulle kunna sorteras utan att hämta mer information om fotona) ID:n bör helst vara 64 bitar (för mindre index och bättre lagring i system som Redis) Systemet bör introduceras som få nya "rörliga delar" som möjligt – en stor del av hur vi har kunnat skala Instagram med väldigt få ingenjörer är genom att välja enkla, lättförståeliga lösningar som vi litar på.
De kom fram till ett system som har 41 bitar baserat på tidsstämpeln, 13 o databasens fragment och 10 för en automatisk inkrementdel. Eftersom du inte verkar använda skärvor. Du kan bara ha 41 bitar för en tidsbaserad del och 23 bitar slumpmässigt valda. Det ger en extremt osannolik chans på 1 på 8,3 miljoner att få en konflikt om du sätter in poster samtidigt. Men i praktiken kommer du aldrig att träffa det här. Just så vad sägs om lite kod:
Genererar ID:n
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
Obs, START_TIME
i ovanstående kod finns en godtycklig starttid. Du kan använda time.time()*1000 , hämta värdet och ställa in det som START_TIME
Lägg märke till att reverse_id
metod jag har lagt upp låter dig ta reda på vid vilken tidpunkt posten skapades. Om du behöver hålla reda på den informationen kan du göra det utan att behöva lägga till ytterligare ett fält för det! Så din primära nyckel sparar faktiskt ditt lagringsutrymme snarare än att öka det!
Modellen
Så här skulle din modell se ut.
class MyClass(models.Model):
id = models.BigIntegerField(default = fields.make_id, primary_key=True)
Om du gör ändringar i din databas utanför django måste du skapa motsvarigheten till make_id
som en sql-funktion
Som en fotnot. Det här liknar det tillvägagångssätt som Mongodb använder för att generera dess _ID för varje objekt.