Nápad
Doporučil bych vám stejný přístup, jaký používá Instagram . Zdá se, že jejich požadavky těsně následují vaše.
Vygenerovaná ID by měla být řazena podle času (takže například seznam ID fotografií by bylo možné třídit bez načítání dalších informací o fotografiích) ID by měla být ideálně 64bitová (pro menší indexy a lepší úložiště v systémech jako Redis) co nejméně nových „pohyblivých částí“ – velká část toho, jak jsme byli schopni škálovat Instagram s velmi malým počtem inženýrů, je výběr jednoduchých, snadno pochopitelných řešení, kterým věříme.
Přišli se systémem, který má 41 bitů založených na časové značce, 13 bitů databázového fragmentu a 10 pro část s automatickým přírůstkem. Protože se zdá, že nepoužíváte úlomky. Můžete mít pouze 41 bitů pro časovou komponentu a 23 bitů vybraných náhodně. To vytváří extrémně nepravděpodobnou pravděpodobnost 1 ku 8,3 milionu, že dojde ke konfliktu, pokud vložíte záznamy současně. Ale v praxi je pravděpodobné, že tohle nikdy nenarazíte. Správně, co takhle nějaký kód:
Generování ID
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
Poznámka:START_TIME
ve výše uvedeném kódu je nějaký libovolný počáteční čas. Můžete použít time.time()*1000 , získat hodnotu a nastavit ji jako START_TIME
Všimněte si, že reverse_id
metoda, kterou jsem zveřejnil, vám umožňuje zjistit, kdy byl záznam vytvořen. Pokud potřebujete tyto informace sledovat, můžete tak učinit, aniž byste k nim museli přidávat další pole! Váš primární klíč tedy ve skutečnosti šetří vaše úložiště, nikoli jej zvětšuje!
Model
Nyní bude váš model vypadat takto.
class MyClass(models.Model):
id = models.BigIntegerField(default = fields.make_id, primary_key=True)
Pokud provedete změny v databázi mimo django, budete muset vytvořit ekvivalent make_id
jako funkce SQL
Jako poznámka pod čarou. Je to trochu jako přístup používaný Mongodb ke generování jeho _ID pro každý objekt.