powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Разработка информационных систем [игнор отключен] [закрыт для гостей] / Сквозная нумерация в многопользовательском режиме.
20 сообщений из 45, страница 2 из 2
Сквозная нумерация в многопользовательском режиме.
    #33121852
michael_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzy michael_Ну добъетесь Вы ввода без дырок, а пользователь удалит запись из середины списка и что дальше?
Если речь идет о непрерывных, то номер удаленной записи:
1. попадает в список неиспользуемых номеров и
2. выдается следующей новой записи

Это-то понятно. Только при условии, что следующая запись будет вообще добавлена ;))). А если год уже закрыт, что так и будем с дыркой в старом году сидеть? Ужас!!! :)
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121855
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Роман Дынник
GUID и identity - это не номера, это уникальные PK-ключи и смысла делать для
них нумерацию без дыр никакого нет.
Согласен. Позволю себе только напомнить, что GUID - не уникальный. А повторяющийся с очень малой вероятностью код :)

Роман Дынник
А Номер есть номер, это атрибут документа. Хотите для его создания
используйте стандартные средства, хотите - свои.
Но не надо смешивать номер с PK.
про первичный ключ вы первым начали.
у автора вопроса про ключи ничего не было.
был вопрос вне СУБД. на общую логику.

Роман Дынник
Если продолжить обсуждение на этом поприще то все выльется в тоже
"естественные против искуственных".
Да уж... Не хотелось бы :)
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121866
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
michael_А если год уже закрыт, что так и будем с дыркой в старом году сидеть? Ужас!!! :)
А с какой стати это вы запись удалили, если год закрыт?

Если же удалили как раз до закрытия - так и будем. А что делать? А кому легко?
Но это маловероятная ситуация. Внештатная. И решать ее надо внештатно. ИМХО.
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121874
Сахават Юсифов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос не КАК НАДО, а ГДЕ НАДО?

Например: выделяются интервалы для кодировки изделий, телефонных номеров, IP адресов ...
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121889
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzy
Непрерывная же нумерация потребует хранения неиспользованных номеров. Например, пользователь начал создавать документ, номер сгенерировался. Пользователь передумал, нажал ESC, номер освободился и перешел в таблицу неиспользованных номеров.

Естественно, при создании документа сначала рассматривается таблица неиспользованных номеров. Если там что-нибудь есть - номер берется оттуда.

Можно и не хранить, если позволяют ресурсы сервера и условия задачи. Я однажды так сделал:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
ALTER FUNCTION FindFreeID(in StartID integer,in step integer)
returns integer
begin
  declare @ID integer;
  declare qty integer; -- кол-во в текущем отрезке
  set qty=(select count(*) from some_table where id between StartID and StartID+step- 1 );
  if qty < step then
    if step =  1  then
      set @ID = StartID
    else
      set @ID = FindFreeID(StartId,step/ 2 )
    end if
  else
    set @ID = FindFreeId(StartId+step,step)
  end if;
  return(@ID)
end
Рекурсивный поиск свободных номеров прямо по рабочей таблице методом половинного деления. При наличии индекса по id и правильном подборе шага работает весьма быстро на таблицах с десятками тысяч записей.
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121897
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Александр ГoлдунМожно и не хранить, если позволяют ресурсы сервера и условия задачи. Я однажды так сделал:
Ух, ты!
Забавно. Надо подумать...
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121912
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
  if qty < step then
    if step <=  1  then
...

Чтобы бы предложил улучшить - сделать проверку на "меньше или равно".
Своеобразная защита от дурака и дурацких входящих параметров... 0 например, или отрицательное число...

Но очень забавно...

Но работает только на целых... Строковым номер не может быть... Или может? Надо подумать...
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33121996
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzyЧтобы бы предложил улучшить...
Не, нафиг улучшения.
Алгоритм правильный и в улучшениях не нуждается.

Спасибо, Александр, на редкость красивый алгоритм.
Испытал истинное наслаждение. Спасибо.
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122007
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эх, снова поторопился...
Улучшить таки можно.
Александр, а как вы узнаете значения StartID и step для первого вызова?
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122035
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Э-эх... А похоже алгоритм то совсем неправильный.
Так, например, если в диапазоне 1..100 будет свободен номер 98, то алгоритм его не найдет. Но идея красивая...

Только, после хорошего раздумья... вряд ли стоит так делать.
select count(*) - достаточно тяжелая штука.
даже select count(id) и то не самая легкая операция...

Но огромное спасибо за идею.
Даже в голове не умещалось, что к СУБД можно применять матаппарат.
Эту идею стоит подумать еще.
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122058
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzy пишет:
> Эх, снова поторопился...
> Улучшить таки можно.

Улучшить можно все, что угодно. Ну, может кроме элементарных частиц :)

> Александр, а как вы узнаете значения StartID и step для первого вызова?

Задаются в программе константно. StartID либо 1, либо номер начала
диапазона (например если в репликации удаленные базы имеют разные
диапазоны ID). Step подбирается эмпирическим путем таким образом, чтобы
уменьшить число шагов. Если нет супер больших последовательностей дырок,
то разумно поставить первый шаг равный примерно половине искомого
диапазона. Можно поэкспериментировать.
Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122097
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzy пишет:

> Э-эх... А похоже алгоритм то совсем неправильный.
> Так, например, если в диапазоне 1..100 будет свободен номер 98, то
> алгоритм его не найдет. Но идея красивая...

Это почему еще? Только что проверил - прекрасно находит при любых
параметрах 1<=StartID<=98 и Step>0

> Только, после хорошего раздумья... вряд ли стоит так делать.
> select count(*) - достаточно тяжелая штука.
> даже select count(id) и то не самая легкая операция...

А чем отличается select count(*) от select count(id), если id NOT NULL?
По логике, да и по сути это одно и то же. По крайней мере в Sybase ASA
время выполнения не отличается. А на таблице с 70 тысячами записей
выполняется за доли секунды при параметрах (1,100000). По моему более
чем приемлемая скорость, особенно для такой вещи, как генерация ID для
создаваемой человеком записи.
Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122132
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Александр Гoлдун
Это почему еще? Только что проверил - прекрасно находит при любых
параметрах 1<StartID<=98 и Step>0
Подумаю еще.
Но смущает то, что алгоритм ищет только в первой половине FindFreeID(StartId,step/2)
А на вторую половину вызова нет FindFreeID(StartId + step/2, step/2)

Но я еще подумаю. Хорошо бы, если бы я ошибался.

Александр Гoлдун
> Только, после хорошего раздумья... вряд ли стоит так делать.
> select count(*) - достаточно тяжелая штука.
> даже select count(id) и то не самая легкая операция...

А чем отличается select count(*) от select count(id), если id NOT NULL?
А об этом было сказано? :)

Александр Гoлдун
По логике, да и по сути это одно и то же. По крайней мере в Sybase ASA
время выполнения не отличается. А на таблице с 70 тысячами записей
выполняется за доли секунды при параметрах (1,100000). По моему более
чем приемлемая скорость, особенно для такой вещи, как генерация ID для
создаваемой человеком записи.
Дело скорее не в скорости, а в объеме прочитанных данных.
count должен прочитать все страницы таблицы.
Либо держать таблицу в кэше, чтобы работать быстро.
Что в общем то совершенно некузяво для общего случая.
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122137
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Александр, а как вы узнаете значения StartID и step для первого вызова?
>
> Задаются в программе константно. StartID либо 1, либо номер начала
> диапазона (например если в репликации удаленные базы имеют разные
> диапазоны ID). Step подбирается эмпирическим путем таким образом, чтобы
> уменьшить число шагов. Если нет супер больших последовательностей дырок,
> то разумно поставить первый шаг равный примерно половине искомого
> диапазона. Можно поэкспериментировать.

А если точнее, то взять максимально возможный, при котором оптимизатор
все еще сочтет выгодным использовать индекс вместо сканирования. Т.е.
селективность при первом вызове должна быть в районе 20% (зависит от
сервера и еще некоторых условий)
Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122138
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Неправильно. Страницы индекса, конечно...
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122146
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzyА на вторую половину вызова нет FindFreeID(StartId + step/2, step/2)
И снова я неправ.
Что такое FindFreeProdId?
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122171
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzy пишет:

> А на вторую половину вызова нет FindFreeID(StartId + step/2, step/2)
>
>
> И снова я неправ.
> Что такое FindFreeProdId?

Забыл переименовать. FindFreeId, естественно.
А на вторую половину для вызова НЕЛЬЗЯ уполовинивать диапазон, иначе оно
может не доползти до дырки, если ее не нашлось в первой половине.
Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122181
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Александр Гoлдун
mazzy пишет:

> А на вторую половину вызова нет FindFreeID(StartId + step/2, step/2)
>
>
> И снова я неправ.
> Что такое FindFreeProdId?

Забыл переименовать. FindFreeId, естественно.
А на вторую половину для вызова НЕЛЬЗЯ уполовинивать диапазон, иначе оно
может не доползти до дырки, если ее не нашлось в первой половине.
Posted via ActualForum NNTP Server 1.2
а... тогда это не деление пополам :)
т.е. step не должен в первый раз гарантировано покрывать весь диапазон?

так например, для диапазона 1..100 с дыркой в 98
в первый раз надо вызывать, например, так FindFreeId(1,10)?
угу... чтобы был выбран индекс, а не сканирование...
угу... надо подумать...
но count - почему-то по-прежнему не нравится...
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122695
Фотография Александр Гoлдун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mazzy
а... тогда это не деление пополам :)
т.е. step не должен в первый раз гарантировано покрывать весь диапазон?

Если в диапазоне есть дырки, то ищутся именно делением пополам. Если нет - то берется следующий диапазон. Соответственно step не обязан все покрывать.
mazzy

так например, для диапазона 1..100 с дыркой в 98
в первый раз надо вызывать, например, так FindFreeId(1,10)?
угу... чтобы был выбран индекс, а не сканирование...

Можно и так, но именно при таких количествах индекс не актуален и нормальный оптимизатор может вполне отвергнуть его в пользу скана. Тогда выгоднее взять шаг побольше - будет меньше глубина рекурсии.
...
Рейтинг: 0 / 0
Сквозная нумерация в многопользовательском режиме.
    #33122811
mazzy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Александр ГoлдунМожно и так, но именно при таких количествах индекс не актуален и нормальный оптимизатор может вполне отвергнуть его в пользу скана. Тогда выгоднее взять шаг побольше - будет меньше глубина рекурсии.
Да, понял.
Диапазон выбран сугубо для примера, чтобы цифирек много не писать :)
...
Рейтинг: 0 / 0
20 сообщений из 45, страница 2 из 2
Форумы / Разработка информационных систем [игнор отключен] [закрыт для гостей] / Сквозная нумерация в многопользовательском режиме.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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