2013-03-12 12 views
15

Tworzymy nową aplikację internetową, która będzie mieć wersję aplikacji na iPada/Androida w trybie offline na wielu urządzeniach lokalnych, która będzie obejmować wstawianie nowych danych. W związku z tym wymagamy użycia identyfikatorów UUID, aby umożliwić niezbędną dwukierunkową synchronizację z główną bazą danych. W tym celu będziemy przechowywać klucz UUID jako klucz podstawowy BINARY(16).Czy przy korzystaniu z identyfikatorów UUID należy również używać AUTO_INCREMENT?

Problemem, którego nauczyłem się po badaniu, jest to, że czas potrzebny na niesekwencyjne wstawianie kluczowych kluczy zwiększa się z upływem czasu i że te wstawki będą prowadzić do fragmentacji (jako odpowiedź here). Korzyścią dla AUTO_INCREMENT jest to, że nowe wiersze będą zwykle dodawane do końca tabeli, a zatem nie napotkasz problemów z szybkością w przypadku identyfikatorów UUID.

Moje pytanie brzmi, czy lepiej jest użyć kolumny AUTO_INCREMENT jako klucza podstawowego, a następnie kolumnę UUID jako niezerowy indeks? Prawdopodobnie będzie to miało zalety prędkości wynikające z wkładek sekwencyjnych przy zachowaniu niezbędnych identyfikatorów UUID wymaganych do synchronizacji rozproszonych baz danych.

Jedna kwestia, którą widzę z tym, to że UUID musi być używany jako odniesienie (przy użyciu ograniczeń klucza obcego) do innych tabel (tj. Lista problemów związanych z inspekcją, która z kolei jest dołączona do witryny , z których wszystkie są związane z insertami, a więc wszystkie z nich wymagają UUID). Semantycznie ma sens, aby klucz podstawowy był punktem odniesienia, ale jako jego system rozproszony nie możemy użyć do tego celu AUTO_INCREMENTS. Czy istnieją niedogodności związane z używaniem (nie zerowego) unikalnego indeksu zamiast klucza podstawowego dla tych odniesień (i, oczywiście, JOIN s, które będą z nimi dołączane)?

Warto również zauważyć, że główna (online) baza danych wykorzystuje MySQL (InnoDB), a rozproszone (offline) bazy danych wykorzystują SQLite.

Edit:

Biorąc pod uwagę, że jest to być może lepiej mieć UUID jako klucz podstawowy (jak to jest semantycznie co to jest), chciałbym uzyskać korzyści z kolejnych wkładek jeśli ustawić UUID jako klucz podstawowy i kolumna AUTO_INCREMENT jako niezerowy indeks o wartości zerowej? Czy jest to tylko klucz podstawowy, który ma znaczenie przy ustalaniu, gdzie wstawić nowy wiersz?

Odpowiedz

13

Użycie autoinkrementacji jako podstawowej plus kolumna uuid jest prawidłowym modelem, ale nadal musisz zmagać się z pewnymi problemami, jakie przynosi autoinkrement, wszystko zależy od tego, jak wykonujesz synchronizację.

W każdym razie pracowałem z kluczami uuid jako kluczami podstawowymi (moja obecna baza danych ma pół miliona rekordów) i nadal jest dość szybki, tylko spowalnia nieco wkładki, ale jeśli nie ma bardzo dużych ilości wkładek codziennie nie powinno cię to straszyć.

Jeśli używasz Sql-Server, innym rozwiązaniem, na które możesz rzucić okiem, są sekwencyjne UUID, które mają nieco większe szanse kolizji niż zwykłe UUID, ale absolutna szansa kolizji jest wciąż dość niska, a ponieważ są one częściowo sekwencyjne która obejmuje problemy z fragmentacją.

0

Można użyć złożonego klucza podstawowego, składającego się z automatycznie zwiększanej wartości identyfikatora bigint, przypisanej przez klienta trybu offline oraz identyfikatora bigintuta przypisanego do klienta. W związku z tym użytkownik powinien mieć wpis 15 dokonany na kliencie 1235.

Klient powinien najpierw zażądać swojego identyfikatora z serwera przed pierwszymi modyfikacjami, na przykład po pierwszym pobraniu danych podstawowych serwera.

4

Gdy masz dużą rozproszoną hurtownię danych, jeśli użyjesz identyfikatora UUID lub GUID jako klucza unikalnego i użyjesz go później, nie jest to dobre.

Zamiast używać UUID lub GUID, należy utworzyć sekwencyjny klucz zastępczy w głównej bazie danych lub w potoku danych.

Podziel się doświadczeniem naszego projektu jako odniesieniem. Mamy 300 miliardów rekordów zapisanych w równoległej hurtowni danych, w naszym systemie klucz automatyczny nie jest nawet obsługiwany. Używamy 8 bajtów bigint jako klucz podstawowy (tak naprawdę unikalny klucz w naszym systemie nie jest obsługiwany, ale nie ma to wpływu na unikalność logiczną), kiedy przetwarzamy plik i ładujemy plik, używamy 3 bajtów do wygenerowania ID pliku, który jest 2^24 pliki, mamy około 2000 plików do załadowania dziennie, więc 2^24 może obsługiwać około 25 lat, jeśli nie jest źle.
Używamy pozostałych 4 bajtów jako identyfikatora wiersza, który ma 4 miliardy wierszy, nie mamy 4 miliardów wierszy w żadnym pliku. Zarezerwowaliśmy 1 bajt. Podczas przetwarzania ETL musimy tylko śledzić identyfikator pliku w głównej bazie danych, która obsługuje automatyczny identyfikator przyrostowy, kiedy potrzebujemy wygenerować identyfikator rekordu podczas przetwarzania pliku, łączymy FileID + 1 bajt rezerwy + 4 bajty rowID.

Powiązane problemy