Pull to refresh

Comments 14

Еще вариант — использовать тип uuid вместо serial, тогда никаких последовательностей не нужно.
В случае, когда используемый ORM это позволяет — тоже можно. Но тогда обычно про serial и не вспоминают.

UUID надо генерировать при создании сущности в памяти, а не при вставке в базу. Тогда от ORM ничего особенного и не требуется (да, в случае с mysql-ем там свои нюансы, но мы же про постгрес).

Я про то, что если ORM позволяет связывать сущности в памяти по UUID (а не просто генерировать как одно из полей), тогда в базе serial обычно не встречается вовсе.
просто
Сконвертировать поле и вместо smallserial использовать serial или bigserial — это позволит продлить агонию приложения на месяцы или даже годы.

Серьёзно? У вас были случаи исчерпания диапазона bigserial?

Для serial — были.
И это очень легко, если приложение делает, например, 1K/sec таких операций: 2^31 / 1000 ops / 86400 sec ~= 25 дней.
bigserial вряд ли удастся застать на своем веку. :)
Ну так, для serial у многих были. А bigserial для того и нужен, чтобы не париться. При закладываемом жизненном цикле приложения в 10 лет надо
(2^63)/(365*10*86400)~3e10 операций в секунду делать. Слоник так быстро не бегает…
Kilor, что мешает использовать NOT EXISTS при наличии уникального ключа (ключ стостоит из одного, двух полей) вместо ON CONFLICT?
NOT EXISTS во вложенном запросе не гарантирует атомарность операции и может приводить к ошибкам конкурентного доступа:
SELECT -- 0 rows
    SELECT -- 0 rows
INSERT
    INSERT -- fail

ON CONFLICT — гарантирует, поскольку сначала захватывает блокировку на уникальном ключе:
LOCK(uniqueVal)
    LOCK(uniqueVal) -- wait
INSERT
    ON CONFLICT

Кстати, Кирилл, можете добавить в вашу статью ещё один способ накрутки счётчика транзакций, о котором мало кто из разработчиков знает.


В PL/pgSQL обработка исключений реализуется при помощи SAVEPOINT. Если в хранимой процедуре/функции имеется блок "EXCEPTION", то при каждом выполнении этого кода будет создаваться SAVEPOINT, и соответственно, будет увеличиваться счётчик транзакций. Если такая функция применяется к возвращаемым строкам запроса, то это может приводить к аварийной остановке кластера, я читал про такие кейсы.


Об этом не сказано в документации, но есть подробный комментарий в исходном коде.


Отсюда вытекает рекомендация. Не используйте обработчики исключений внутри функций, которые вы собираетесь применять к строкам, возвращаемых запросами. Этот механизм предназначен для процедур, реализующих бизнес логику на стороне СУБД,

Может, запилите полноценную статью с примерами?

На самом деле я сморозил глупость. В селектах построчно счётчик так просто не наматывается. Всё немного сложнее, он наматывается внутри хранимых процедур.


Так что теперь точно придётся написать статью с примерами и переводом комментов в коде, чтоб загладить вину :-)

Sign up to leave a comment.