Можна CURRENT_TIMESTAMP
використовувати як PRIMARY KEY
?
Чи існує можливість двох або більше різних ВСТУП отримати однакові CURRENT_TIMESTAMP
?
Можна CURRENT_TIMESTAMP
використовувати як PRIMARY KEY
?
Чи існує можливість двох або більше різних ВСТУП отримати однакові CURRENT_TIMESTAMP
?
Відповіді:
Відповідно до документації , точність значення CURRENT_TIMESTAMP
мікросекунд. Таким чином, ймовірність зіткнення низька, але можлива.
Тепер уявіть помилку, яка трапляється дуже рідко, і викликає помилки в базі даних. Наскільки важко це налагодити? Це набагато гірша помилка, ніж принаймні детермінована.
Більш широкий контекст: напевно, ви хочете уникнути цих маленьких нюансів із послідовностями, що особливо дратує, якщо ви звикли до MySQL.
Крім того, якщо ви використовуєте транзакції (це робиться більшість веб-фреймів, особливо Java), то часові позначки будуть однакові всередині транзакції! Демонстрація:
postgres=# begin;
BEGIN
postgres=# select current_timestamp;
current_timestamp
-------------------------------
2018-08-06 02:41:42.472163+02
(1 Zeile)
postgres=# select current_timestamp;
current_timestamp
-------------------------------
2018-08-06 02:41:42.472163+02
(1 Zeile)
Побачимось? Два вибір, точно однаковий результат. Я не набираю так швидко. ;-)
-
Якщо ви хочете легко ідентифікувати, уникаючи використання послідовностей, то генеруйте деяке хеш-значення з реальних ідентифікаторів записів. Наприклад, якщо у вашій базі даних є люди, і ви знаєте, що їх дата народження, дівоче прізвище матері та справжнє ім'я однозначно їх ідентифікують, то використовуйте
md5(mother_name || '-' || given_name || '-' birthday);
як ід. Крім цього, ви можете використовувати CreationDate
стовпчик, після чого індексуєте таблицю, але це не ключ (який є ідентифікатором).
Ps Загалом, дуже хороша практика зробити ваш БД настільки детермінованим, наскільки це можливо. Тобто одна і та ж операція повинна створювати абсолютно однакові зміни в БД . Будь-яка ідентифікатор, що базується на часових позначках, не відповідає цій важливій функції. Що робити, якщо ви хочете щось налагодити чи імітувати? Ви відтворюєте операцію, і той самий об’єкт буде створений з іншим ідентифікатором ... насправді це не важко дотримуватися, і це витрачає багато робочих годин.
Ps2 Кожен, хто перевіряє ваш код у майбутньому, не матиме найкращої думки щодо ідентифікаторів, що генеруються часовими позначками, із зазначених вище причин.
INSERT
кілька рядків, всі вони виходять однаковими current_timestamp
. І тоді у вас є тригери ...
Не зовсім тому, що для CURRENT_TIMESTAMP можна надати два однакових значення для двох наступних INSERT (або одного INSERT з декількома рядками).
Замість цього використовуйте UUID на основі часу: uuid_generate_v1mc () .
Строго кажучи: Ні. Тому що CURRENT_TIMESTAMP
це функція, і лише одна або кілька стовпців таблиці можуть утворювати PRIMARY KEY
обмеження.
Якщо ви маєте на увазі створити PRIMARY KEY
обмеження на стовпчик зі значенням за замовчуванням CURRENT_TIMESTAMP
, то відповідь така: Так, ви можете . Ніщо не заважає тобі це робити, як ніщо не заважає тобі відстрілювати яблука з голови сина. Питання все одно не має сенсу, поки ви не визначите мету. Які дані мають містити стовпці та таблиці? Які правила ви намагаєтесь виконати?
Зазвичай ідея обов'язково стикається з повторюваними помилками ключа, оскільки CURRENT_TIMESTAMP
це STABLE
функція, що повертає однакове значення для тієї самої транзакції (час початку транзакції). Кілька INSERT в одній транзакції повинні зіткнутися, як і інші відповіді, які вже проілюстровані. Посібник:
Оскільки ці функції повертають час початку поточної транзакції, їх значення не змінюються під час транзакції. Це вважається особливістю: ціль полягає в тому, щоб дозволити одній транзакції мати послідовне уявлення про "поточний" час, так що кілька модифікацій в межах однієї транзакції мають однакову позначку часу.
Послідові часові позначки реалізуються у вигляді 8-байтних цілих чисел, що представляють до 6 дробових цифр (роздільна здатність мікросекунди).
Якщо ви будуєте таблицю, яка повинна займати не більше одного рядка за мікросекунди і ця умова не зміниться (що - то з ім'ям sensor_reading_per_microsecond
), то це може мати сенс. Повторювані рядки повинні викликати помилку порушення дублюючого ключа. Але це екзотичний виняток. І тип даних timestamptz
(не timestamp
), ймовірно, буде кращим. Подивитися:
Я б все-таки скоріше скористався сурогатним серійним первинним ключем. І додайте UNIQUE
обмеження у стовпчик часової позначки. Менше можливих ускладнень, не покладаючись на деталі впровадження RDBMS.
sensor_reading_per_microsecond
може зіткнутися, якщо ви не можете абсолютно гарантувати, що час кожного читання ідеально синхронізований щодо попереднього; субмікросекундне відхилення (що часто неможливо) порушує схему. Взагалі я все-таки повністю цього уникаю. (Зверніть увагу, як ви вказали, в такому випадку зіткнення в результаті може бути бажаним!)