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

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

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

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

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


в остальном - задача вполне решаема - на том же счетчике + триггера на удаление/изменение (с массовым апдейтом вверх по номерам, что немного сложно стыкуется с уникью). Но вот ее физ смысл ограничен тем, что некоторые записи по факту обретения физической реализации (бумаги с номером, отданной клиенту) не могут участвовать в такой перенумерации. А "сплошная нумерация" с нарушением очередности по датам (времени) - не хуже ли?
...
Рейтинг: 0 / 0
15.01.2007, 15:58
    #34256199
Jelis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Числовой нумератор. Но не Sequence
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
15.01.2007, 16:43
    #34256401
Andrey Daeron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Числовой нумератор. Но не Sequence
Jelis
Заводим отдельную табличку (и заполняем ее) с подряд идущими номерами, типа
Код: plaintext
1.
...

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

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

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


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

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

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

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


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