Może CURRENT_TIMESTAMP
być używany jako PRIMARY KEY
?
Czy istnieje możliwość, że dwa lub więcej różnych WSTAWEK dostanie to samo CURRENT_TIMESTAMP
?
postgresql
database-design
primary-key
timestamp
John Puskin
źródło
źródło
Odpowiedzi:
Zgodnie z dokumentacją dokładność
CURRENT_TIMESTAMP
wynosi mikrosekund. Zatem prawdopodobieństwo kolizji jest niskie, ale możliwe.Teraz wyobraź sobie błąd, który zdarza się bardzo rzadko i powoduje błędy bazy danych. Jak trudno jest to debugować? Jest to znacznie gorszy błąd niż ten, który jest co najmniej deterministyczny.
Szerszy kontekst: prawdopodobnie chcesz uniknąć tych małych niuansów w sekwencjach, co jest szczególnie denerwujące, jeśli jesteś przyzwyczajony do MySQL.
Ponadto, jeśli używasz transakcji (większość frameworków internetowych, szczególnie Java, zrób!), Znaczniki czasu będą takie same w transakcji! Demonstracja:
Do zobaczenia? Dwa selekcje, dokładnie taki sam wynik. Nie piszę tak szybko. ;-)
-
Jeśli chcesz łatwo identyfikować, unikając użycia sekwencji, wygeneruj pewną wartość skrótu na podstawie rzeczywistych identyfikatorów rekordów. Na przykład, jeśli w Twojej bazie danych znajdują się ludzie i wiesz, że ich data urodzenia, nazwisko panieńskie matki i prawdziwe nazwisko jednoznacznie ich identyfikują, użyj
jako identyfikator Poza tym możesz użyć
CreationDate
kolumny po tym, co indeksujesz tabelę, ale nie jest to klucz (który jest id).Ps Ogólnie rzecz biorąc, bardzo dobrą praktyką jest, aby twoja DB była tak deterministyczna, jak to możliwe. To znaczy ta sama operacja powinna stworzyć dokładnie taką samą zmianę w DB . Identyfikator oparty na znacznikach czasu nie spełnia tej ważnej funkcji. Co jeśli chcesz coś debugować lub symulować? Ponownie odtworzysz operację, a ten sam obiekt zostanie utworzony z innym identyfikatorem ... naprawdę nie jest trudny do naśladowania i oszczędza wiele godzin pracy.
Ps2 Każdy, kto sprawdzi kod w przyszłości, nie będzie miał najlepszej opinii na podstawie identyfikatorów wygenerowanych znacznikami czasu z powyższych powodów.
źródło
INSERT
wiele wierszy, wszystkie otrzymają to samocurrent_timestamp
. A potem masz wyzwalacze ...Nie do końca, ponieważ CURRENT_TIMESTAMP może podać dwie identyczne wartości dla dwóch kolejnych WSTAWEK (lub jednego WSTAWU z wieloma wierszami).
Zamiast tego użyj UUID opartego na czasie: uuid_generate_v1mc () .
źródło
Ściśle mówiąc: Nie. Ponieważ
CURRENT_TIMESTAMP
jest funkcją i tylko jedna lub więcej kolumn tabeli może tworzyćPRIMARY KEY
ograniczenie.Jeśli masz na myśli, aby stworzyć
PRIMARY KEY
presję na kolumnie z wartości domyślnejCURRENT_TIMESTAMP
, to odpowiedź brzmi: Tak, to możliwe . Nic nie powstrzymuje cię przed zrobieniem tego, tak jak nic nie powstrzymuje cię przed wystrzeleniem jabłek z głowy syna. Pytanie wciąż nie miałoby sensu, dopóki nie zdefiniujesz jego celu. Jakie dane mają przechowywać kolumna i tabela? Jakie zasady próbujesz wdrożyć?Zazwyczaj pomysł jest związany napotkasz duplikatów kluczowych błędów, ponieważ
CURRENT_TIMESTAMP
jest toSTABLE
funkcja powrocie taką samą wartość dla tej samej transakcji (czas rozpoczęcia transakcji). Wiele WSTAWEK w tej samej transakcji musi się zderzyć - podobnie jak inne zilustrowane już odpowiedzi. Instrukcja:Znaczniki czasu Postgres są implementowane jako 8-bajtowe liczby całkowite reprezentujące do 6 cyfr ułamkowych (rozdzielczość mikrosekundowa).
Jeśli budujesz tabelę, która ma pomieścić nie więcej niż jeden wiersz na mikrosekundy, a warunek ten nie ulegnie zmianie (coś o nazwie
sensor_reading_per_microsecond
), wówczas może to mieć sens. Zduplikowane wiersze powinny wywoływać błąd naruszenia klucza duplikatu. To jednak egzotyczny wyjątek. I typ danychtimestamptz
(nietimestamp
) byłby prawdopodobnie preferowany. Widzieć:Wolałbym zamiast tego użyć zastępczego klucza podstawowego szeregowego. I dodaj
UNIQUE
ograniczenie do kolumny znacznika czasu. Mniej możliwych komplikacji, nie polegających na szczegółach implementacji RDBMS.źródło
sensor_reading_per_microsecond
Może nawet kolidować, jeśli nie można absolutnie zagwarantować, że czas każdego odczytu jest idealnie zsynchronizowany w stosunku do poprzedniego; odchylenie poniżej mikrosekundy (co często nie jest niemożliwe) psuje schemat. Generalnie nadal całkowicie tego unikam. (Pamiętaj, jak wskazałeś w takim przypadku, pożądana kolizja może być pożądana!)