sql >> Databáze >  >> RDS >> Mysql

Jak nahradit primární klíč Django jiným celým číslem, které je pro danou tabulku jedinečné

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.



  1. Jak vypsat aktivní / otevřená připojení v Oracle?

  2. Je čas, abychom IDE Microsoft Access trochu milovali

  3. ALTER &DROP Table DDL s okamžitým spuštěním v databázi Oracle

  4. Jak připojit více databází v PHP, MYSQLi &PDO