Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak zastąpić klucz podstawowy Django inną liczbą całkowitą, która jest unikalna dla tej tabeli?

Pomysł

Polecam ci to samo podejście, które jest stosowane przez Instagram . Ich wymagania wydają się ściśle odpowiadać Twoim.

Wygenerowane identyfikatory powinny być możliwe do sortowania według czasu (więc można na przykład posortować listę identyfikatorów zdjęć bez pobierania więcej informacji o zdjęciach) Identyfikatory powinny być najlepiej 64-bitowe (dla mniejszych indeksów i lepszego przechowywania w systemach takich jak Redis) System powinien wprowadzić jako jak najmniej nowych „ruchomych części” — duża część tego, jak udało nam się skalować Instagram przy niewielkiej liczbie inżynierów, to wybór prostych, łatwych do zrozumienia rozwiązań, którym ufamy.

Wymyślili system, który ma 41 bitów w oparciu o znacznik czasu, 13 fragmentów bazy danych i 10 dla części autoinkrementacji. Ponieważ wydaje się, że nie używasz odłamków. Możesz mieć tylko 41 bitów dla składnika opartego na czasie i 23 bity wybrane losowo. Daje to niezwykle mało prawdopodobną szansę 1 na 8,3 miliona wystąpienia konfliktu, jeśli wstawiasz rekordy w tym samym czasie. Ale w praktyce prawdopodobnie nigdy w to nie trafisz. A co z kodem:

Generowanie identyfikatorów

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 

Uwaga, START_TIME w powyższym kodzie jest jakiś arbitralny czas rozpoczęcia. Możesz użyć time.time()*1000 , pobrać wartość i ustawić ją jako START_TIME

Zauważ, że reverse_id Metoda, którą zamieściłem, pozwala dowiedzieć się, w jakim czasie rekord został utworzony. Jeśli chcesz śledzić te informacje, możesz to zrobić bez konieczności dodawania do nich kolejnego pola! Tak więc kluczem podstawowym jest w rzeczywistości oszczędzanie pamięci, a nie jej zwiększanie!

Model

Teraz tak będzie wyglądał Twój model.

class MyClass(models.Model):
   id = models.BigIntegerField(default = fields.make_id, primary_key=True)  

Jeśli dokonasz zmian w swojej bazie danych poza django, będziesz musiał stworzyć odpowiednik make_id jako funkcja sql

Jako notatkę. Jest to trochę podobne do podejścia stosowanego przez Mongodb do generowania jego _ID dla każdego obiektu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak mogę pominąć dane wyjściowe nagłówka kolumny dla pojedynczej instrukcji SQL?

  2. Zgłosić błąd uniemożliwiający aktualizację tabeli w wyzwalaczu MySQL

  3. Jak wyodrębnić n-te słowo i policzyć wystąpienia słów w ciągu MySQL?

  4. Błąd MySQL:specyfikacja klucza bez długości klucza

  5. Pojedyncza tabela MySql, wybierz ostatnie 7 dni i uwzględnij puste wiersze