sql >> Databasteknik >  >> RDS >> Mysql

Hur man ersätter Djangos primärnyckel med ett annat heltal som är unikt för den tabellen

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.



  1. Salesforce SOQL från Crystal Reports

  2. MySQL:Hur återställer eller ändrar jag MySQL root-lösenordet?

  3. Hur kan jag släppa alla tabeller i en PostgreSQL-databas?

  4. mysql välj dynamiska radvärden som kolumnnamn, en annan kolumn som värde