powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Последовательная нумерация в пределах группы записей
14 сообщений из 14, страница 1 из 1
Последовательная нумерация в пределах группы записей
    #39240835
expl0rer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня есть таблица примерно вот такого вида:

Код: plaintext
1.
2.
3.
Организация  Подразделение  Отдел  Группа        Номер          .....
-----------  -------------  -----  ------    -------------     -------
     01            01         01      01     01_01_01_01_1


Поле Номер должно быть уникально и заполняться автоматически (требования бизнеса).

Алгоритм заполнения: Организация + Подразделение + Отдел + Группа + [Очередной порядковый номер в пределах четырех предыдущих полей].

Табличка будет большая - основная таблица в БД, миллионы записей.

Пользователей много, 99% из них работают с этой таблицей. 80% чтений.

Как лучше решить такую задачу?

Делать

Код: plaintext
1.
SELECT MAX(...) FROM TABLE WHERE [Организация] = ... AND [Подразделение] = ... AND [Отдел] = .... AND [Группа] = ....

даже при наличии индексов по этим полям мне кажется не очень удачной идеей.

Autoincremented поля и SEQUENCE здесь не подходят в силу того, что нумерация не сквозная, а рамках группы записей.

Пока думаю над вариантом создания еще одной таблицы, в которой будет храниться следующей номер, который должен быть выделен в пределах выбранной группы полей:

Код: plaintext
1.
2.
3.
Организация  Подразделение  Отдел  Группа   Следующий номер        
-----------  -------------  -----  ------    -------------     
     01            01         01      01           1

Соответвенно при вставке записи в основную таблицу в триггере получать значение [Следующий номер], использовать его в основной таблице, а потом увеличивать значение в вспомогательной таблице.

Может есть решения лучше ?
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240836
expl0rer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, забыл добавить - сгенерированный номер не должен меняться для записи. Это номер, который пойдет в бумажные документы и по нему потом будет искаться запись.
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240854
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
expl0rerМожет есть решения лучше ?Посмотрите Организация пользовательских счетчиков (генераторов) в Microsoft SQL Server , оно уже стало классикой :-)
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240864
expl0rer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, спасибо - похоже то, что нужно. Я правильно понял, что на основную таблицу мне нужно повесить триггер на вставку. В этом триггере я буду проверять если у меня уже в таблице счетчиков счетчик с нужной комбинацией ключевых полей. Если нет - создавать его. А триггер повешенный на таблицу счетчиков будет создавать SEQUENCE и функции для работы с ней?
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240870
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgоно уже стало классикой :-)Классика - когда не нужна транзакционность при генерации.
ТС'у же наоборот, транзакционность генерации нужна.

expl0rer
Код: plaintext
1.
SELECT MAX(...) FROM TABLE WHERE [Организация] = ... AND [Подразделение] = ... AND [Отдел] = .... AND [Группа] = ....
даже при наличии индексов по этим полям мне кажется не очень удачной идеей.Нормальная идея. И индекс нужен один: (Организация, Подразделение, Отдел, Группа, Номер).
Запрос должен выглядеть так:
Код: sql
1.
SELECT @ПоследнийНомер = MAX(...) FROM TABLE with (serializable, updlock) WHERE [Организация] = ... AND [Подразделение] = ... AND [Отдел] = .... AND [Группа] = ....

и быть в одной транзакции со вставкой в таблицу.

Если потребуется одновременная генерации по нескольким сочетаниям (Организация, Подразделение, Отдел, Группа), запрос и индекс придется доработать.
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240874
expl0rer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invmКлассика - когда не нужна транзакционность при генерации.

А в чем именно нарушается транзакционность в предложенном решении? Точнее, какие именно следствия в моему случае вследствие нарушения транзакционности?
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240894
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
expl0rerТочнее, какие именно следствия в моему случае вследствие нарушения транзакционности?К нарушению непрерывности номеров.

Это лечится отключением "автономности" генерации в этом решении. Но даже если так сделать - это не особо поможет.
Вам, по сути, требуется множество генераторов на одну таблицу. А такого там не предусмотрено. Следовательно, придется дорабатывать под свои нужды.

Как по мне, для вашего конкретного случая гораздо проще и эффективнее сделать примерно так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
use tempdb;
go

create table dbo.t (id int identity primary key, a int, b int, c int, n int, s varchar(100));
create index IX_t__a__b__c__n on dbo.t (a, b, c, n desc)
go

create trigger dbo.tr_t__iofinsert
on dbo.t
instead of insert
as
begin
 set nocount on;

 declare @g table (a int, b int, c int, base int, primary key (a, b, c));

 with s as
 (
  select top (1) with ties
   t.a, t.b, t.c, t.n
  from
   (select distinct a, b, c from inserted) i join
   dbo.t t with (index = IX_t__a__b__c__n, serializable, updlock) on t.a = i.a and t.b = i.b and t.c = i.c
  order by
   t.n desc
 )
 insert into dbo.t
  (a, b, c, n, s)
  select
   i.a, i.b, i.c, isnull(s.n, 0) + row_number() over (partition by i.a, i.b, i.c order by (select 1)), i.s
  from
   inserted i left join
   s on s.a = i.a and s.b = i.b and s.c = i.c
end;
go

insert into dbo.t
values
 (1, 1, 1, null, 'a'), (1, 1, 1, null, 'b'),
 (1, 1, 2, null, 'c'), (1, 1, 2, null, 'd')

select * from dbo.t order by a, b, c, n;
go

insert into dbo.t
values
 (1, 1, 1, null, 'e'), (1, 1, 1, null, 'f'),
 (1, 1, 2, null, 'g'), (1, 1, 2, null, 'h')

select * from dbo.t order by a, b, c, n;
go

drop table dbo.t;
go

...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240954
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmТС'у же наоборот, транзакционность генерации нужна.Ну, вообще он про это не писал.

Если транзакционность нужна, что можно использовать ту схему, про которую ТС писал, в чём проблема?

expl0rerПока думаю над вариантом создания еще одной таблицы, в которой будет храниться следующей номер, который должен быть выделен в пределах выбранной группы полей:
Впрочем, можно использовать и MAX....

invmВам, по сути, требуется множество генераторов на одну таблицу. А такого там не предусмотрено. Следовательно, придется дорабатывать под свои нужды.Там просто пример реализации автономной транзакции.

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

Дмитрий Костылев в докладах иллюстрировал этот код как раз такими сложными случаями, как у ТС, типа отдельная нумерация для периодов, для подразделений, для "групп по 1000", для клиентов, и прочими причудливыми потребностями бизнес-пользователей.
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240976
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgНу, вообще он про это не писал."Очередной порядковый номер в пределах четырех предыдущих полей" как бы намекает на непрерывность. По крайней мере, я понял именно так.

alexeyvgТам просто пример реализации автономной транзакции.

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

Дмитрий Костылев в докладах иллюстрировал этот код как раз такими сложными случаями, как у ТС, типа отдельная нумерация для периодов, для подразделений, для "групп по 1000", для клиентов, и прочими причудливыми потребностями бизнес-пользователей.Вот именно. Принцип один - либо доп. таблица, либо на основе основной.
А весь огород с CLR необходим если нужны "автономные" транзакции или возможность получать номера функцией.
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240989
expl0rer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения, что сразу не написал. В таком виде транзакционность мне не нужна - пропуски могут быть, главное чтобы их было не очень много. Автоинкрементируемое поле не устраивает клиента своим размером - им нужен короткий 3-4 символьный номер. Если нумеровать в пределах Организация+Подразделение+Отдел+Группа - так и выходит.

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

Варианты вам были предложены. Даже с примером.
Но выбрать вы должны самостоятельно.
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39240993
expl0rer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
да, спасибо
...
Рейтинг: 0 / 0
Последовательная нумерация в пределах группы записей
    #39241201
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
expl0rerВ таком виде транзакционность мне не нужна - пропуски могут быть, главное чтобы их было не очень многоНу, тогда выбор простой - по любому своя таблица (таблицы) с номерами, и дальше либо простые запросы для получения номера, если производительность некритична, либо отдельные транзакции через CLR как в статье выше, если множество конкурентных обращений.

PS ждём реализации в MSSQL нативных автономных транзакций :-)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Последовательная нумерация в пределах группы записей
    #39635411
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.Ничего нового по этой теме не появилось ?
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Последовательная нумерация в пределах группы записей
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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