Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 08:18
Оценка:
SQL2005, нужно на базе реализовать простой счётчик, который при обращении каждый раз возвращает увеличенное значение.
Требования:
1. Генерируемые значения должны быть уникальны
2. После генерации нового значение желательно что бы никаких блокировок на базе не оставалось

Сейчас это реализованно давольно тупо, одна таблица с одной колонкой и одним рядом в котором лежит значение текущее и хранимка которая его увеличивает, проблема в том, что после UPDATE-а этого значение ессно остаются висеть блокировки. Вот от них и надо как то избавиться. Думаем что возможно написать CLR стору, которая будет создавать новую конекцию и генерировать новое значение в ней а потом возвращать назад. Так как это будет новая конекция/транзакция локи будут сразу сняты после её окончания. Вот думаю:

1. Как лучше бы всё это реализовать
2. То что я придумал возможно?
3. То что я придумал извращение?

Ы?
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re: Счётчик на базе
От: ksg71 Германия  
Дата: 24.10.06 08:31
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>2. То что я придумал возможно?

Tom>3. То что я придумал извращение?

Tom>Ы?



— возможно
— не извращение (на 2000 писались Ext. SP для "автономных" транзакций)
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re: Счётчик на базе
От: Softwarer http://softwarer.ru
Дата: 24.10.06 08:53
Оценка:
Здравствуйте, Tom, Вы писали:

Единственно, я бы посмотрел, не нагрузит ли базу создание новых соединений по каждому чиху. Возможно, будет лучше повесить рядом с базой небольшой сервис секвенсоров, удерживающий соединение, а из хранимки обращаться к этому сервису.
Re[2]: Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 09:03
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, Tom, Вы писали:


S>Единственно, я бы посмотрел, не нагрузит ли базу создание новых соединений по каждому чиху. Возможно, будет лучше повесить рядом с базой небольшой сервис секвенсоров, удерживающий соединение, а из хранимки обращаться к этому сервису.


У нас не так часто это надо, вопрос скорее в том, ка кбы без геморно и быстрее это реализовать, сейчас есть счётчик, но он "не автономен"... Сервис — это слишком
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re: Счётчик на базе
От: IB Австрия http://rsdn.ru
Дата: 24.10.06 09:03
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>SQL2005, нужно на базе реализовать простой счётчик, который при обращении каждый раз возвращает увеличенное значение.

Tom>Требования:
Tom>1. Генерируемые значения должны быть уникальны
Tom>2. После генерации нового значение желательно что бы никаких блокировок на базе не оставалось
см. функцию NEWSEQUENTIALID() — это уникальный GUID, такой же как от NewID(), но каждое следующее значение этой функции гарантировано больше предыдущего. Единственное ограничение просто так его вызвать нельзя он обязательно должен быть дефолтным констрейнтом в таблице. Получать вставленное значение можно через INSERT ... OUTPUT ... INTO.

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

А таблица с identity не катит, обязательно надо апдейтить?

Tom>2. То что я придумал возможно?

Да.

Tom>3. То что я придумал извращение?

Да.
Мы уже победили, просто это еще не так заметно...
Re[2]: Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 09:11
Оценка:
IB>см. функцию NEWSEQUENTIALID() — это уникальный GUID, такой же как от NewID(), но каждое следующее значение этой функции гарантировано больше предыдущего. Единственное ограничение просто так его вызвать нельзя он обязательно должен быть дефолтным констрейнтом в таблице. Получать вставленное значение можно через INSERT ... OUTPUT ... INTO.
Нужен последовательный int, гуид не подходит, или я чего то не понял?

IB>А таблица с identity не катит, обязательно надо апдейтить?

Незнаю, возможно катит, как этим воспользоваться?
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[2]: Счётчик на базе
От: Lloyd Россия  
Дата: 24.10.06 09:18
Оценка: +1
Здравствуйте, IB, Вы писали:

IB>см. функцию NEWSEQUENTIALID() — это уникальный GUID, такой же как от NewID(), но каждое следующее значение этой функции гарантировано больше предыдущего. Единственное ограничение просто так его вызвать нельзя он обязательно должен быть дефолтным констрейнтом в таблице. Получать вставленное значение можно через INSERT ... OUTPUT ... INTO.


А что такое "больше" для гуида?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Счётчик на базе
От: IB Австрия http://rsdn.ru
Дата: 24.10.06 09:25
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

L>А что такое "больше" для гуида?

Тоже самое, что и для всего остального GUID1 < GUID2, при условии что GUID2 получили позже чем GUID1.
Мы уже победили, просто это еще не так заметно...
Re[4]: Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 09:27
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Lloyd, Вы писали:


L>>А что такое "больше" для гуида?

IB>Тоже самое, что и для всего остального GUID1 < GUID2, при условии что GUID2 получили позже чем GUID1.

не очень понятно как на основе NEWSEQUENTIALID можно счётчик реализовать, и как при его помощи от блокировок избавиться
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[3]: Счётчик на базе
От: IB Австрия http://rsdn.ru
Дата: 24.10.06 09:32
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Нужен последовательный int, гуид не подходит, или я чего то не понял?

Кому нужен?

Tom>Незнаю, возможно катит, как этим воспользоваться?

Очень просто. Создается глобальная табличка с Identity столбцом. Когда нужно получить новый ID вставляешь туда что-нибудь и получаешь SCOPE_IDENTITY(). Блокировки до конца транзакции есть, но они никому не мешают можешь в этой же табличке еще какую-нибудь общую информацию хранить... Можешь подчищать ее периодически, как захочется.

NEWSEQUENTALGUID() в этом плане лучше тем, что никаких приседаний с дополнительными таблицами вообще не требует и его свойства распространяются на несколько серверов, при условии что на серверах есть сетевая карта.
Мы уже победили, просто это еще не так заметно...
Re[5]: Счётчик на базе
От: IB Австрия http://rsdn.ru
Дата: 24.10.06 09:34
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>не очень понятно как на основе NEWSEQUENTIALID можно счётчик реализовать, и как при его помощи от блокировок избавиться

Во всех таблицах где тебе нужно использовать уникальное значение больше предыдущего объявляешь столбец (RowID uniqueidentifier DEFAULT NEWSEQUENTALGUID(), ...) все.
Во всех этих столбцах значения будут уникальные и больше предыдущих даже в других таких же таблицах.
Мы уже победили, просто это еще не так заметно...
Re[4]: Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 09:36
Оценка:
Tom>>Нужен последовательный int, гуид не подходит, или я чего то не понял?
IB>Кому нужен?
Мне в качестве счётчика нужен int а не GUID

Tom>>Незнаю, возможно катит, как этим воспользоваться?

IB>Очень просто. Создается глобальная табличка с Identity столбцом. Когда нужно получить новый ID вставляешь туда что-нибудь и получаешь SCOPE_IDENTITY(). Блокировки до конца транзакции есть, но они никому не мешают можешь в этой же табличке еще какую-нибудь общую информацию хранить... Можешь подчищать ее периодически, как захочется.

Подчищать...( Хотя как вариант — вполне.

IB>NEWSEQUENTALGUID() в этом плане лучше тем, что никаких приседаний с дополнительными таблицами вообще не требует и его свойства распространяются на несколько серверов, при условии что на серверах есть сетевая карта.


DECLARE @id uniqueidentifier
SET @id = NEWSEQUENTIALID()
SELECT @id


Ошибка:
Msg 302, Level 16, State 0, Line 2
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
Msg 302, Level 16, State 0, Line 3
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[6]: Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 09:38
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Tom, Вы писали:


Tom>>не очень понятно как на основе NEWSEQUENTIALID можно счётчик реализовать, и как при его помощи от блокировок избавиться

IB>Во всех таблицах где тебе нужно использовать уникальное значение больше предыдущего объявляешь столбец (RowID uniqueidentifier DEFAULT NEWSEQUENTALGUID(), ...) все.
IB>Во всех этих столбцах значения будут уникальные и больше предыдущих даже в других таких же таблицах.

Понял, но не получиться, значение счётчика часто запрашивается из back end-а итп... Надо всё таки именно счётчик в прямом смысле.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[5]: Счётчик на базе
От: IB Австрия http://rsdn.ru
Дата: 24.10.06 09:40
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Мне в качестве счётчика нужен int а не GUID

Ну раз нужен...

Tom>Подчищать...( Хотя как вариант — вполне.

Всяко лучше чем отдельное подключение...

Tom>Ошибка:

Ты внимательно читаешь? Я же писал:

Единственное ограничение просто так его вызвать нельзя он обязательно должен быть дефолтным констрейнтом в таблице.

Плюс полезно смотреть документацию, прежде чем использовтаь...
Мы уже победили, просто это еще не так заметно...
Re: Счётчик на базе
От: Au1  
Дата: 24.10.06 11:24
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>SQL2005, нужно на базе реализовать простой счётчик, который при обращении каждый раз возвращает увеличенное значение.

Tom>Требования:
Tom>1. Генерируемые значения должны быть уникальны
Tom>2. После генерации нового значение желательно что бы никаких блокировок на базе не оставалось

Tom>Сейчас это реализованно давольно тупо, одна таблица с одной колонкой и одним рядом в котором лежит значение текущее и хранимка которая его увеличивает, проблема в том, что после UPDATE-а этого значение ессно остаются висеть блокировки. Вот от них и надо как то избавиться. Думаем что возможно написать CLR стору, которая будет создавать новую конекцию и генерировать новое значение в ней а потом возвращать назад. Так как это будет новая конекция/транзакция локи будут сразу сняты после её окончания. Вот думаю:


Tom>1. Как лучше бы всё это реализовать

Tom>2. То что я придумал возможно?
Tom>3. То что я придумал извращение?

Tom>Ы?


Если честно, я не знаю как это сделано в SQL2005. В Oracle есть такие объекты, которые зовут sequence. И достаточно сделать select <seq_name>.NEXTVAL into :XXX from dual; Можно еще делать select CURVAL.

Неужто майкрософты не стали делать такой простой удобный объект?
Re[3]: Счётчик на базе
От: _d_m_  
Дата: 24.10.06 11:27
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, IB, Вы писали:


IB>>см. функцию NEWSEQUENTIALID() — это уникальный GUID, такой же как от NewID(), но каждое следующее значение этой функции гарантировано больше предыдущего. Единственное ограничение просто так его вызвать нельзя он обязательно должен быть дефолтным констрейнтом в таблице. Получать вставленное значение можно через INSERT ... OUTPUT ... INTO.


L>А что такое "больше" для гуида?


GUID — это целое 16-байтное число
Re[4]: Счётчик на базе
От: Lloyd Россия  
Дата: 24.10.06 11:35
Оценка: :)
Здравствуйте, _d_m_, Вы писали:

IB>>>см. функцию NEWSEQUENTIALID() — это уникальный GUID, такой же как от NewID(), но каждое следующее значение этой функции гарантировано больше предыдущего. Единственное ограничение просто так его вызвать нельзя он обязательно должен быть дефолтным констрейнтом в таблице. Получать вставленное значение можно через INSERT ... OUTPUT ... INTO.


L>>А что такое "больше" для гуида?


___>GUID — это целое 16-байтное число


Неужели? А nvarchar(100) — это наверное целое двухсотбайтное число?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Счётчик на базе
От: Tom Россия http://www.RSDN.ru
Дата: 24.10.06 11:44
Оценка:
Au1>Если честно, я не знаю как это сделано в SQL2005. В Oracle есть такие объекты, которые зовут sequence. И достаточно сделать select <seq_name>.NEXTVAL into :XXX from dual; Можно еще делать select CURVAL.

Au1>Неужто майкрософты не стали делать такой простой удобный объект?

Неа, был бы Оракл вопрос бы не возникнул
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[5]: Счётчик на базе
От: _d_m_  
Дата: 24.10.06 12:05
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>А что такое "больше" для гуида?


___>>GUID — это целое 16-байтное число


L>Неужели? А nvarchar(100) — это наверное целое двухсотбайтное число?


Надо признавать свои ошибки, а не упорствовать в невежестве. Вот дернул тебе несколько ссылок, что впрочем, ты мог сделать и сам:

msdn.microsoft.com
здесь 2
здесь 3
здесь 4
Re[4]: Счётчик на базе
От: ksg71 Германия  
Дата: 24.10.06 12:44
Оценка: +1
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Lloyd, Вы писали:


L>>А что такое "больше" для гуида?

IB>Тоже самое, что и для всего остального GUID1 < GUID2, при условии что GUID2 получили позже чем GUID1.

а гарантирует ли сервер, что следующий GUID будет сгенерирован "позже" предыдущего,
а если это произойдет "условно одновременно"?

к примеру код


Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
Console.WriteLine(g1.CompareTo(g2));
Console.WriteLine(g2.CompareTo(g1));


дает от раза к разу разные результаты
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.