я понимаю, что есть вот такие 2 типа?
1. Следующим ключом делает +1 от максимального ключа
2. Следующим ключом делает +1 от последнего сгенерированного ключа?
То есть во втором случае если последним был 14, а я ручками прописала ключ для след.записи 20, то есть генерация не будет работать, соответственно следующая генерация выдаст 15, 16, 17, 18, 19, потом на 20 выдаст duplicate key value ошибку?
да, поэтому PK делают по сиквенсу, чтобы не возникали такие коллизии
Если PK 2 типа, то как-то его можно поменять на тип 1 при существующей таблице не навредив ничему? Можно ли в целом сделать так, что бы все новые PK были второго типа?
Вы путаете первичный ключ - суть уникальный индекс и sequence - некий нетранзакционный генератор последовательных чисел, который часто используют как генератор уникальных значений для первичного ключа
Первичный ключ не генерирует значения, он только ограничивает содержимое. Вы можете вставлять в колонки ПК любые допустимые значения (не NULL, уникальные). Если что-то “не так” — получите ошибку. SEQUENCE — способ получить автоматическую генерацию целочисленнх ПК.
Нет давно таких типов уже, только последовательность
Нет, никаких "разных типов первичного ключа" в этом смысле несуществует. Первичный ключ -- он всегда просто уникальный ключ на не-null поле, и к генерацыи значений это совершэнно ортогонально.
Это я понимаю. Я про способы генерации этих первичных ключей
да, сделать default value sequence.nextval и навсегда забыть о проблеме генерации новых айдишек (только обязательно не cycle, иначе можно дойти до предела и прыгнуть снова в 1)
Хотя кто-то, безусловно, генерирует новый ключ как +1 от максимального -- это крайне непрофессиональная реализацыя. (А два основных способа генерирования синтэтического первичного ключа -- это последовательность, которая генерирует +1 от последнего сгенерированного, и рандом, последнее чаще всего на uuid чтобы не особо париться с коллизиями).
Генерировать можно миллионом способов, но самые популярные - sequence, uuid и в триггере со своей произвольной логикой (например генерировать номер на основе полей из той же записи)
в ПГ есть спец тип serial - он сразу создает сиквенс и щелкает циферки при вставке
лучше использовать generated by default вместо serial
Не используется первый вариант в современных многопользовательских (many writers) СУБД (по причине отвратительной производительности). А вот в single-writer СУБД, с другой стороны: https://sqlize.online/sql/sqlite3/683fa289ae35b920e5595ede7d3e6da7/
к сожалению до сих пор масса легаси систем юзает метод поиска макс+1
А я бы сказал (про своё абсолютное нежелание спорить по поводу чего-либо из этой ссылки без очень существенных аргументов с другой стороны я тут уже говорил, кажется): https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_serial
Обсуждают сегодня