powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Числовой нумератор. Но не Sequence
14 сообщений из 14, страница 1 из 1
Числовой нумератор. Но не Sequence
    #34255389
Kruchinin Pahan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужен числовой нумератор такого типа:
1. Должна соблюдаться уникальность в пределах нумератора.
2. Не должно быть пропусков в нумерации. (То есть, после удаления элемента с данным номером, этот номер займет следующий новый элемент).
3. Таблица, где будет использован нумератор может содержать несколько нумераторов (несколько последовательностей номеров).
4. Таблицу, где будет использован нумератор, нельзя лочить на чтение. Потому что выборки по ней ходят постоянно.

Самое сложное требование - отсутствие пропусков в нумерации. Стандартная последовательность этого не реализует. Ко всему прочему, такой подход требует, полного перебора существующих номеров, чтоб дырки заполнить.
Вобщем, может у кого есть идеи по этому поводу, кто-то что-то реализовывал. Откликнитесь.
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34255534
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kruchinin PahanНужен числовой нумератор такого типа:
1. Должна соблюдаться уникальность в пределах нумератора.
2. Не должно быть пропусков в нумерации. (То есть, после удаления элемента с данным номером, этот номер займет следующий новый элемент).
3. Таблица, где будет использован нумератор может содержать несколько нумераторов (несколько последовательностей номеров).
4. Таблицу, где будет использован нумератор, нельзя лочить на чтение. Потому что выборки по ней ходят постоянно.

Самое сложное требование - отсутствие пропусков в нумерации. Стандартная последовательность этого не реализует. Ко всему прочему, такой подход требует, полного перебора существующих номеров, чтоб дырки заполнить.
Вобщем, может у кого есть идеи по этому поводу, кто-то что-то реализовывал. Откликнитесь.
Мы когда-то на фирме долго этот вопрос дискутировали, потом решили что слишком неформализировно с точки зрения многопользовательской работы и было решено "типа реализовать", обработкой на клиенте сообщения что номер уже занят.
Если на фронтенд ничего не завязано - тогда все просто: по полю делаем UNIQUE KEY, и в ХП для вставки лочим таблицу на запись, выбираем максимальное, вставляем, разлочиваем таблицу.
Возхникающие в последствии "дырки" (удаление например) и кучу друго-го гемороя разгребаем как получится.
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34255630
Kruchinin Pahan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey Daeron
Мы когда-то на фирме долго этот вопрос дискутировали, потом решили что слишком неформализировно с точки зрения многопользовательской работы и было решено "типа реализовать", обработкой на клиенте сообщения что номер уже занят.
Если на фронтенд ничего не завязано - тогда все просто: по полю делаем UNIQUE KEY, и в ХП для вставки лочим таблицу на запись, выбираем максимальное, вставляем, разлочиваем таблицу.
Возхникающие в последствии "дырки" (удаление например) и кучу друго-го гемороя разгребаем как получится.
Не совсем оно дружелюбно для пользователя, тем более что выписывается несколько сотен доков от пользователя (любят рабоать авралом и заводят за час все что надо за день). Часто пользователи пересекаются. Можно конечно на фронтэнде обрабатывать исключение и пытаться занять номер в цикле. Ну и последняя фигня - на уровне учетной политики определено журналирование документов без пропусков нумерации. (Кстати, счет-фактура, например требует того же на законодательном уровне).
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34255790
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kruchinin Pahan
Не совсем оно дружелюбно для пользователя, тем более что выписывается несколько сотен доков от пользователя (любят рабоать авралом и заводят за час все что надо за день). Часто пользователи пересекаются. Можно конечно на фронтэнде обрабатывать исключение и пытаться занять номер в цикле. Ну и последняя фигня - на уровне учетной политики определено журналирование документов без пропусков нумерации. (Кстати, счет-фактура, например требует того же на законодательном уровне).
Ну а в "жизни" они как номера раскидывают?
Основные идеи и проблемы:
1. Время заведения номера документа:
а) во время создания
+ сразу юзверю ясен номер
- А если он "обламался" заводить документ? Ну например на резет нажал :)
б) во время сохранения
+ четкая последовательность
- юзер не знает номера документа до момента сохранения
Как компромис - ХП, которая заводит документ и тут же его сохраняет. Зачастую невозможен из-за NOT NULL полей.
2. Последовательность нумерации. Здесь вообще цирк получается при многопользовательской работе. Кто-то добавил документ, кто-то обламался, кто-то понял что накосячил и документ удалил нафик.
Супер-решение - есть ХП которая сохраняет документ, удалять документ нельзя. Для реализации нумератора фполне подойдет обычный сиквенс :)
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34255996
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kruchinin PahanНу и последняя фигня - на уровне учетной политики определено журналирование документов без пропусков нумерации. (Кстати, счет-фактура, например требует того же на законодательном уровне).
гм. тут приятнейший момент - если удалите счет фактуру (номер) а какой-то уже выдан контрагенту - будете перенумеровывать (и перерассылать с изъятием ранее разосланных/выданных)?

т.ч. видимо имеет смысл разбить работу на 2 фазы.
1. создание документа (присваивается некий "предварительный номер")
2. Перевод в актуальное значение - присваивается текущий (в счетчике "актуальных") номер (после чего номер не меняется и удалить документ нельзя - только редактировать - например заменить другим "предварительным").

очевидно, что некоторые "рабочие моменты" (имеющие место быть "по жизни") будут очень сильно связаны таким решением. Хотя можно и их порешить.


в остальном - задача вполне решаема - на том же счетчике + триггера на удаление/изменение (с массовым апдейтом вверх по номерам, что немного сложно стыкуется с уникью). Но вот ее физ смысл ограничен тем, что некоторые записи по факту обретения физической реализации (бумаги с номером, отданной клиенту) не могут участвовать в такой перенумерации. А "сплошная нумерация" с нарушением очередности по датам (времени) - не хуже ли?
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34256199
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kruchinin PahanНужен числовой нумератор такого типа:
1. Должна соблюдаться уникальность в пределах нумератора.
2. Не должно быть пропусков в нумерации. (То есть, после удаления элемента с данным номером, этот номер займет следующий новый элемент).
3. Таблица, где будет использован нумератор может содержать несколько нумераторов (несколько последовательностей номеров).
4. Таблицу, где будет использован нумератор, нельзя лочить на чтение. Потому что выборки по ней ходят постоянно.

Самое сложное требование - отсутствие пропусков в нумерации. Стандартная последовательность этого не реализует. Ко всему прочему, такой подход требует, полного перебора существующих номеров, чтоб дырки заполнить.
Вобщем, может у кого есть идеи по этому поводу, кто-то что-то реализовывал. Откликнитесь.

Заводим отдельную табличку (и заполняем ее) с подряд идущими номерами, типа
Код: plaintext
1.
2.
3.
4.
CREATE TABLE My_Numbers (
number_id    serial primary key,
my_number  integer   -- могут быть и не только целые, но и например "сложные" номера накладных
)

А в основной таблице вставляем id номера, подобным образом
Код: plaintext
1.
2.
3.
4.
5.
6.
INSERT INTO My_Table(my_number_id) 
   SELECT number_id FROM My_Numbers 
                                  WHERE number_id NOT IN 
                                               (SELECT my_number_id FROM My_Table ) 
                                  ORDER BY my_number ASC 
                                  LIMIT  1  ;
Смысл вообщем, что бы взять минимальный элемент, который еще не запользован в основной таблице. Соответственно при удаление ни каких дополнительный телодвижений делать не надо. Основная таблица не лочиться, а производительность при вставке возможно будет "не очень", но это смотря какя нагрузка. Если эти вставки происходят от оператора (создание нового документа) и в основная таблица в пределах нескольких сот тысяч записей, проблемм быть не должно.
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34256401
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jelis
Заводим отдельную табличку (и заполняем ее) с подряд идущими номерами, типа
Код: plaintext
1.
...

А чем это отличается от простого сиквенса? В смысле что может помешать вставится записи при просто использовании сиквенса?
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34256431
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Andrey Daeron Jelis
Заводим отдельную табличку (и заполняем ее) с подряд идущими номерами, типа
Код: plaintext
1.
...

А чем это отличается от простого сиквенса? В смысле что может помешать вставится записи при просто использовании сиквенса?

Тем, что таким образом "нет пропусков в нумерации", как хотел Kruchinin Pahan. Т.е. если мы удалим какуюто запись, то потом этот номер будет опять использован.
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34256456
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jelis
Тем, что таким образом "нет пропусков в нумерации", как хотел Kruchinin Pahan. Т.е. если мы удалим какуюто запись, то потом этот номер будет опять использован.
Точнее будет использован при вставке следующей записи, т.е. непрерывность нумерации не обеспечивается в произвольный момент времени, а только при достижении некоторых условий.
Так что будем ждать от автора определения удовлетворяющей его непрерывности.
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34256905
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Andrey Daeron Jelis
Тем, что таким образом "нет пропусков в нумерации", как хотел Kruchinin Pahan. Т.е. если мы удалим какуюто запись, то потом этот номер будет опять использован.
Точнее будет использован при вставке следующей записи, т.е. непрерывность нумерации не обеспечивается в произвольный момент времени, а только при достижении некоторых условий.
Так что будем ждать от автора определения удовлетворяющей его непрерывности.


Хм... ну да, точно. Но насколько я понял
Kruchinin Pahan
2. Не должно быть пропусков в нумерации. (То есть, после удаления элемента с данным номером, этот номер займет следующий новый элемент).

Так оно ему и нужно. А если делать что бы нумерация сразу переписывалась.... это тоже не так сложно, но, помоему, еще трудозатратнее. И похорошемму табличку на запись лочить не помешает. Кстати, в моем варианте, тоже не помешает на запись основную таблицу лочить. Ну или проверять на ексепшен.
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34257311
Kruchinin Pahan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey Daeron Jelis
Тем, что таким образом "нет пропусков в нумерации", как хотел Kruchinin Pahan. Т.е. если мы удалим какуюто запись, то потом этот номер будет опять использован.
Точнее будет использован при вставке следующей записи, т.е. непрерывность нумерации не обеспечивается в произвольный момент времени, а только при достижении некоторых условий.
Так что будем ждать от автора определения удовлетворяющей его непрерывности.
Реально, на данный момент происходит приблизительно то же самое, только последовательность не сохранена в табличке, а генерится находу. Таким образом, лочить кроме основной таблички нечего. Возникает вопрос. А сколько генерить номеров. Много номеров, вестимо будет работать медленно. Мало номеров, может не хватить когда-нибудь. Может вьюшку сгенерить? И вьюшку лочить Ж;))
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34257760
Andrey Daeron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kruchinin Pahan
Реально, на данный момент происходит приблизительно то же самое, только последовательность не сохранена в табличке, а генерится находу. Таким образом, лочить кроме основной таблички нечего. Возникает вопрос. А сколько генерить номеров. Много номеров, вестимо будет работать медленно. Мало номеров, может не хватить когда-нибудь. Может вьюшку сгенерить? И вьюшку лочить Ж;))
А может в триггере проверять, и если осталось мало - нагенерить еще пару десятков :)
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34258178
Kruchinin Pahan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey Daeron Kruchinin Pahan
Реально, на данный момент происходит приблизительно то же самое, только последовательность не сохранена в табличке, а генерится находу. Таким образом, лочить кроме основной таблички нечего. Возникает вопрос. А сколько генерить номеров. Много номеров, вестимо будет работать медленно. Мало номеров, может не хватить когда-нибудь. Может вьюшку сгенерить? И вьюшку лочить Ж;))
А может в триггере проверять, и если осталось мало - нагенерить еще пару десятков :)
Забавно, можно попробовать. Хотя, из всего этого я бы вынес одну только идею: блокировать не основную табличку, а какую-нибудь левую. Например, создать табличку счетчиков с уникальным наименованием счетчика.
Как-нить так, например:

SELECT INTO loRow * FROM [Таб_счетчиков] WHERE Name = 'mycounter'::Name FOR UPDATE ;
...
Здесь мы рассчитываем очередное значение счетчика (или ищем дырку).
...
UPDATE [Таб_счетчиков] SET ...
...
Рейтинг: 0 / 0
Числовой нумератор. Но не Sequence
    #34259149
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kruchinin Pahan Andrey Daeron Jelis
Тем, что таким образом "нет пропусков в нумерации", как хотел Kruchinin Pahan. Т.е. если мы удалим какуюто запись, то потом этот номер будет опять использован.
Точнее будет использован при вставке следующей записи, т.е. непрерывность нумерации не обеспечивается в произвольный момент времени, а только при достижении некоторых условий.
Так что будем ждать от автора определения удовлетворяющей его непрерывности.
Реально, на данный момент происходит приблизительно то же самое, только последовательность не сохранена в табличке, а генерится находу. Таким образом, лочить кроме основной таблички нечего. Возникает вопрос. А сколько генерить номеров. Много номеров, вестимо будет работать медленно. Мало номеров, может не хватить когда-нибудь. Может вьюшку сгенерить? И вьюшку лочить Ж;))

ну, это в самом деле не такая уж проблемма :-) Как сказал Andrey Daeron проверяем в триггере, если осталось мало - добавляем. Что такое "мало" и сколько добавлять, решаем исходя из решаемой задачи. Единственное, если каждый раз в триггере делать count(*), то производительноесть упадет :-) Можно, например, просто проверять id выделяемого номера. То есть, если мы за раз добавляем, допустим, 1000 номеров, а сейчас выделяеться номер 950, то пора еще 1000 номеров сгенерить. Правда, с таким подходом, нужно отдельно обыграть случай, когда мы 950 номер выделили один раз, потом его удалили ("вернули в свободные"), а потом еще раз выделили - получиться что добавиться 2000 номеров, вместо 10000.
Либо можно по crontabu проверять раз в сутки сколько осталось, и не нужно ли добавить.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Числовой нумератор. Но не Sequence
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]