Регистрация | Войти
Lisp — программируемый язык программирования
RSS
RESTAS+Postmodern нарушение уникальности serial
irmpow - 30.06.2013 21:32, Сообщений - 3
Уважаемые знатоки, с Вами играет Александр, г.Москва.
Столкнулся вот с чем.
Есть таблица со столбцом, тип serial. Добавлял этот столбец уже после внесения строк в таблицу этой командой (через постмодерн, макрос with-connection)

"ALTER TABLE goods ADD COLUMN id serial;"

Соответственно всем строкам дался уникальный id. При добавлении новых строк

"INSERT INTO goods VALUES (~A , '~A' , ~A , '~A' , ~A , ~A , 0)" - где ~A - значения в соответствии с типом столбцов, 0 - количество по умолчанию.

id не передавал и он автоматом давался на 1 больше. Потом уже внесение изменений в строки делал через

"UPDATE goods SET parameter1 = 'value' WHERE id = 'number';"

И все было прекрасно до тех пор, пока не обратил внимания, что иногда исправлялись 2 строки, вместо 1. Проверил id на уникальность:

"SELECT id FROM goods ORDER BY id"
И получил печальную картину:
Нумерация шла так: 1 2 3 4 5 6 7 8 9 10 11 ....  98 99 100 100 101 101 102 102 103 103 .... 133 133 134 134 135 136 137 138 ... 615
Т.е. сначала нормально до 99, потом задвоения, потом нормально.
Решил сделать тест, удалил строки с id 7 8 9 10.
Стало:
1 2 3 4 5 6 11 ....  98 99 100 100 101 101 102 102 103 103 .... 133 133 134 134 135 136 137 138 ... 615
Это как бы тоже нормально. Потом внес еще 4 строки, получилось:
1 2 3 4 5 6 11 ....  98 99 100 100 101 101 102 102 103 103 .... 133 133 134 134 135 135 136 136 137 137 138 138 139 140 141... 615
Т.е. вместо того, чтобы выдавать id начиная с 616 postgres выдавал с последнего задвоенного

все 4 строки добавлялись одной функцией в теле которой:

(progn
  (add-good-to-table parameter1 parameter2...parameter6)
  (add-good-to-table parameter1 parameter2...parameter6)
  (add-good-to-table parameter1 parameter2...parameter6)
  (add-good-to-table parameter1 parameter2...parameter6))

Сначала начал грешить на эту функцию, вдруг она идет не последовательно, а параллельно и id не успевают выдаваться, но это не так. Пересоздал колонку id.

"ALTER TABLE goods DROP COLUMN id;
"ALTER TABLE goods ADD COLUMN id serial;

 И еще раз выполнил функцию с (progn). id выдались последовательно, начиная с последнего. Пересмотрел еще раз код, который с этой таблицей работает. Функции добавления строк id не передают, его высчитывает postgres, функции изменения значений в строках id только запрашивают в качестве фильтра, но его не меняют.

Внимание вопрос, уважаемые знатоки, как такое задвоение получилось и как его можно избежать в будущем.
P.S.:Надеюсь, что разбор этого вопроса убережет новичков от похожих ошибок, гугл не помог...
[#]
Последовательности в PostgreSQL работают вне транзакций. Я бы грешил на свой код. А чтобы проще было найти изменил был добавление на:

ALTER TABLE goods ADD COLUMN id serial UNIQUE;

Тогда добавить неуникальное значение не удастся.

И еще вопрос - а какой первичный ключ в таблице?
amartynov - 01.07.2013 10:52
[#] Ответ на комментарий от amartynov 01.07.2013 10:52
За UNIQUE огромное спасибо.
Если я правильно понял вопрос... Сначала определял все по составному ключу, потом перешел на id.
irmpow - 01.07.2013 23:40
[#] Ответ на комментарий от irmpow 01.07.2013 23:40
Скажем так, ответ про UNIQUE подсказывает мне, что надо дать несколько советов, хоть это тут и будет злостно не по теме(к RESTAS никакого отношения не имеет):
  1. Первичный ключт надо всегда помечать как PRIMARY KEY. Это также хорошая подсказка разработчику, когда он смотрит на таблицу. Одиночное поле можно пометить как есть, составной ключ добавляется как ограничение таблицы.
  2. Все ограничения добавляются в базу как ограничения столбцы или таблицы, включая UNIQUE, CHECK, NOT NULL и т.д.
  3. Ссылки на другие таблицы обязательно участвуют в FOREIGN KEY.

Правила 2 и 3 можно нарушать, но только тогда, когда есть серьезные причины для этого.

Ограничение UNIQUE в PostgreSQL имеет один нюанс - создается уникальный индекс по столбцу, так что поиск становится быстрее, но и обновление медленнее.


При соблюдении всего этого становится гораздо труднее получить нецелостную базу.

amartynov - 02.07.2013 10:16
@2009-2013 lisper.ru