Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PowerBuilder Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
savosin_sergey
Номер коннекшена (через который будет производиться insert) всегда уникальен, среди всех подключённых пользователей. У одного пользователя можут быт два коннекта, но с разными @@spid.

А если пользователь по два приложения запустит?
savosin_sergey
Так что коллизий не наблюдается

Это главное достоинство метода?
26 апр 05, 13:24    [1498113]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Estets
Member

Откуда: Химки
Сообщений: 604
Вот наша процедура для MS/Syabse без всяких наворотов;)

create procedure dbo.ap_getid @id numeric out    
as     
declare @site_id numeric(2,0)
begin     
   select @site_id=id from t_sites where is_local=1     
   if @@error!=0 return    
   if @site_id is null begin     
      raiserror 40000 'Неизвестна площадка'     
      return     
   end      
   insert t_idgenerator (site_id) values (@site_id)     
   if @@error!=0 return     
   select @id = @@identity + @site_id*10000000000000000    
end

Таблица t_idgenerator имеет IDENTITY поле.
Таблица t_sites используется для разделения диапазона по разным серверам.
26 апр 05, 13:35    [1498166]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
Estets
Вот наша процедура для MS/Syabse без всяких наворотов;)
...
Таблица t_idgenerator имеет IDENTITY поле.
Таблица t_sites используется для разделения диапазона по разным серверам.
Вот нечто подобное и я имел ввиду
26 апр 05, 13:40    [1498191]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
Estets
Таблица t_idgenerator имеет IDENTITY поле.
Таблица t_sites используется для разделения диапазона по разным серверам.

А почему не использовать для этого identity seed?
26 апр 05, 14:01    [1498287]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Estets
Member

Откуда: Химки
Сообщений: 604
Исторически сложилось ;)
Вообще-то планировалось размножение баз дампами с изменением номера локального сервера.
26 апр 05, 14:54    [1498595]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
Локшин Марк
А если пользователь по два приложения запустит?

Будет два SQLCA и два разных номера соединений
Локшин Марк
Это главное достоинство метода?

Это необходимое условие работы метода.

2 Estets:
Estets
select @id = @@identity + @site_id*10000000000000000
какой же длины у вас ключевые поля? если шаг между серверами=10^17
select @site_id=id from t_sites where is_local=1
что такое is_local=1? и где название таблицы? или у вас все таблицы получают "сквозной" идентификатор?

Локшин Марк
А почему не использовать для этого identity seed?

Да на самом деле (это относится к MsSqlServer2000) можно использовать признак identity у колонки в таблице (чтобы она автоматически увеличивала значение) + функцию SCOPE_IDENTITY() -- она возвращает последнее значение identity-колонки в таблице, в которой произощёл последний insert..

я на этом сервере на форуме, посвящённом MsSqlServer-у читал всякие предложения по генерации уникальных значений.. там тоже было предложение с использованием временной таблицы и обсуждались какие-то проблемы..
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=103151&hl=
26 апр 05, 15:07    [1498653]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
ЗоринАндрей
Member

Откуда: Санкт-Петербург
Сообщений: 3004
savosin_sergey
какой же длины у вас ключевые поля? если шаг между серверами=10^17
а если еще вспомнить что PB воспринимает не более 18 значащих разрядов, то вообще засада. и на десяток site_id может не хватить.
26 апр 05, 15:23    [1498759]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
ЗоринАндрей
Member

Откуда: Санкт-Петербург
Сообщений: 3004
А GUID кстати никто не пробовал использовать в качестве PK?
26 апр 05, 15:24    [1498762]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
savosin_sergey
Будет два SQLCA и два разных номера соединений

А когда запустят по 4 копии, вот тут-то диапазоны и перекроются.
savosin_sergey
Да на самом деле (это относится к MsSqlServer2000) можно использовать признак identity у колонки в таблице (чтобы она автоматически увеличивала значение) + функцию SCOPE_IDENTITY() -- она возвращает последнее значение identity-колонки в таблице, в которой произощёл последний insert.

А чем более ранние версии SQL сервера не угодили. Вы описали принцип заполнения переменной @@IDENTITY, а она и раньше была.
savosin_sergey
Это необходимое условие работы метода.

А в чем его преимущества?
26 апр 05, 15:38    [1498818]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
ЗоринАндрей
А GUID кстати никто не пробовал использовать в качестве PK?
Да, пробовал два раза (в двух проектах). Работает :-)
26 апр 05, 15:46    [1498866]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
Локшин Марк
savosin_sergey
Это необходимое условие работы метода.
А в чем его преимущества?
Старший приказал (с) :-)
26 апр 05, 15:50    [1498885]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
ASCRUS
Member

Откуда: МО Электросталь
Сообщений: 5994
PL99
ЗоринАндрей
А GUID кстати никто не пробовал использовать в качестве PK?
Да, пробовал два раза (в двух проектах). Работает :-)

Ну их эти GUID ... попробовали в одном новом разрабатывающемся проекте ASA, потом плюнули, домен на unsigned int перевели с GLOBAL AUTOINCREMENT и решили больше никогда не связываться. Из реальных проблем - неоправданно большой размер PK и FK, неудобство ручного написания запросов (без Copy-Paste никуда), из за "скачущих" значений GUID неоптимальное хранение веток индексов в БД, из за этого проседания на join-ах при выборках, плюс еще кое какие мелкие баги самой ASA при работе с GUID, которые я им заявил, но исправить они еще не успели (например невозможность подключения таблицы удаленного сервера ASA, в которой есть GUID или выполнение SELECT * INTO Table). Единственное, где не было нареканий - так как использовалась ASA 9.0.2, то PB видел их как string и проблем в клиентской части не было. Так что я зарекся от их использования, GLOBAL AUTOINCREMENT на целых числах гораздо приятнее и привычнее получается.
26 апр 05, 16:02    [1498971]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Estets
Member

Откуда: Химки
Сообщений: 604
savosin_sergey


2 Estets:
Estets
select @id = @@identity + @site_id*10000000000000000
какой же длины у вас ключевые поля? если шаг между серверами=10^17
select @site_id=id from t_sites where is_local=1
что такое is_local=1? и где название таблицы? или у вас все таблицы получают "сквозной" идентификатор?

Идентификатор numeric(18,0), Две цифры под сервер, 16 под Increment
SSNNNNNNNNNNNNNNNN

Таблица t_sites примерно такая:
id srv_name is_local
1 'Server1' 1
1 'Server2' 0
1 'Server3' 0

Только в реальности данный механизм не понадобился ;-( Хотя были планы настроить репликацию.

Угумс в этом есть своя прелесть, в какой бы таблице не находился документ, можно определить его тип по глобальному идентификатору.
26 апр 05, 16:43    [1499198]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
Локшин Марк
А когда запустят по 4 копии, вот тут-то диапазоны и перекроются.

Да, если шаг=300 (в примере gnv_appl.i_step) и если все 100 пользователей запустят по 3-4 копии, то накроется. Хотя можно увеличить шаг до 1000... всё равно если для первичного ключа использовать integer, то 2 млрда / 1000 = 200 000 000 -- нашу систему это устраивает (максимальное наблюдаемое число проводок около 90 млн за год)
Локшин Марк
А чем более ранние версии SQL сервера не угодили. Вы описали принцип заполнения переменной @@IDENTITY, а она и раньше была.

 Так один пользователь считал @@identity (до сохранения), потом другой считал @@identity -- произойдёт совпадение. Можно считывать лишь после сохранения -- с тем, чтобы передать его подчинённым detail'ам..
Локшин Марк
А в чем его преимущества?

Другое преимущество: если использовать автоинкремент, то после сохранения в DW не будет значения уникального поля -- для этого надо сделать retrieve. Если записей много в таблице, то делать retrieve после каждого insert'а -- долгова-то. В этом случае придётся считывать @@identity из базы и присваивать полю DW.. ну или ещё что-нибудь придумывать..
 У нас "ведущий" программер решил уникальное поле генерить на клиенте -- вот и я предложил для обсуждения его метод.
 На соседнем форуме (ссылка на него в начале этой темы) мне совсем другой метод предложили для ввода связанных таблиц..
26 апр 05, 18:30    [1499722]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
PL99
Member

Откуда: Moscow
Сообщений: 1367
savosin_sergey
Другое преимущество: если использовать автоинкремент, то после сохранения в DW не будет значения уникального поля -- для этого надо сделать retrieve. Если записей много в таблице, то делать retrieve после каждого insert'а -- долгова-то. В этом случае придётся считывать @@identity из базы и присваивать полю DW.. ну или ещё что-нибудь придумывать..

Да можно ничего не придумывать, а взять готовое
26 апр 05, 19:15    [1499838]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
2 PL99: спасибо.
26 апр 05, 19:46    [1499900]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
savosin_sergey
Так один пользователь считал @@identity (до сохранения), потом другой считал @@identity -- произойдёт совпадение. Можно считывать лишь после сохранения -- с тем, чтобы передать его подчинённым detail'ам..

За каким извините хреном считывать identity до сохранения? Оно вообще неизвестно что вернет.
savosin_sergey
Другое преимущество: если использовать автоинкремент, то после сохранения в DW не будет значения уникального поля -- для этого надо сделать retrieve. Если записей много в таблице, то делать retrieve после каждого insert'а -- долгова-то. В этом случае придётся считывать @@identity из базы и присваивать полю DW.. ну или ещё что-нибудь придумывать..

Пользователь редко вводит больше 10 записей не сохраняясь. Вы думаете 10 SELECT @@identity сильно просадят производительность?
26 апр 05, 20:59    [1500026]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
savosin_sergey
Хотя можно увеличить шаг до 1000... всё равно если для первичного ключа использовать integer, то 2 млрда / 1000 = 200 000 000 -- нашу систему это устраивает (максимальное наблюдаемое число проводок около 90 млн за год)

Т.е. ваша система расчитана на то, чтобы проработать чуть больше 2-х лет?
Кроме того, вы размениваете тривиальный запрос к переменной connect-а (@@identity) при сохранении (которое не всегда будет), на гарантированный запрос при добавлении строки в DataWindow к таблце, что гораздо более затратно.
Какие еще преимущества, как вам кажется, есть у этого метода? (пока видны одни недостатки).
26 апр 05, 21:13    [1500046]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
2 Локшин Марк:
автор
За каким извините хреном считывать identity до сохранения? Оно вообще неизвестно что вернет.

Уважаемый Марк, ну а когда его, @@identity считывать? не после же сохранения? или я что-то не понимаю.. есть операция dw.update(boolean, boolean), есть операция select @@identity into :iid;.. даже если select @@identity повесить в event updatestart() -- разве гарантируется, что действия в updatestart() выполнятся в той же транзакции, что и реальное сохранение DW?

автор
Пользователь редко вводит больше 10 записей не сохраняясь. Вы думаете 10 SELECT @@identity сильно просадят производительность?

я имел ввиду retrieve DW целиком -- чтобы в неё, в DW, закачались значения автоинкрементного столбца (после dw.update()). И если в таблице много строк, то по-идее, retrieve будет проходить некотрое заметное время.. (даже если он один, общий для всех введённых записей)

автор
Т.е. ваша система расчитана на то, чтобы проработать чуть больше 2-х лет?

Пример с 90млнами строк в год -- это таблица проводок, которая раз в год полностью чистится (остатки в сальдо)(если я не переборщил с числом строк). Таких большие таблице у нас в системе редко встречаются.. но если есть, то можно тип первичного ключа заменить на numeric(20)..

автор
Кроме того, вы размениваете тривиальный запрос к переменной connect-а (@@identity) при сохранении (которое не всегда будет), на гарантированный запрос при добавлении строки в DataWindow к таблце, что гораздо более затратно.

Извините, не понял.. в любом случае надо строку к DW добавлять (вопрос лишь в заполнении или в не заполнении поля с первичным ключём.). И в любом случае после нажатия "Сохранить" придётся делать update. Где гарантированный запрос?

спасибо!
27 апр 05, 10:44    [1500849]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
я
Да, если шаг=300 (в примере gnv_appl.i_step) и если все 100 пользователей запустят по 3-4 копии, то накроется. Хотя можно увеличить шаг до 1000... всё равно если для первичного ключа использовать integer, то 2 млрда / 1000 = 200 000 000 -- нашу систему это устраивает (максимальное наблюдаемое число проводок около 90 млн за год)

чё-то меня дважды проглючило: 2 млрда/300 = около 6.6 млн записей. (может вместить в себя поле integer, если в него записывать значение с шагом 300).
 Второй глюк -- я видел таблицу самое большое в 9 млн строк. Для неё действительно надо либо последовательно генерить значения, либо использовать numeric(18). С другой стороны, указанная таблица не вводится в вручную пользователями -- это результат расчёта ХП, и для неё сойдёт обычный автоинкремент..

ЗоринАндрей
а если еще вспомнить что PB воспринимает не более 18 значащих разрядов, то вообще засада. и на десяток site_id может не хватить.
Откуда такая информация?
27 апр 05, 10:55    [1500907]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
savosin_sergey
Уважаемый Марк, ну а когда его, @@identity считывать? не после же сохранения?

именно после
savosin_sergey
или я что-то не понимаю..

безусловно, при том, вам это уже несколько раз объясняли (в т.ч. в соседнем форуме).
savosin_sergey
есть операция dw.update(boolean, boolean), есть операция select @@identity into :iid;.. даже если select @@identity повесить в event updatestart() -- разве гарантируется, что действия в updatestart() выполнятся в той же транзакции, что и реальное сохранение DW?

Да гарантируется, если у вас там на обработке очередная чушь не написана. Транзакциями в PB управляете Вы сами. Если транзакция начата, то пока вы не сделаете commit или rollback все будет в рамках этой транзакции.
Кроме того, если указать для таблицы identity column, то вообще ничего делать не нужно! После вставки каждой строки PB сам запросит значение автоинкремента и запишет его в нужную колонку DW.
savosin_sergey
я имел ввиду retrieve DW целиком -- чтобы в неё, в DW, закачались значения автоинкрементного столбца (после dw.update()). И если в таблице много строк, то по-идее, retrieve будет проходить некотрое заметное время.. (даже если он один, общий для всех введённых записей)

И для чего после сохранения делать retrieve DW целиком, чтобы получить значения автоинкрементов? Их не так получают.
savosin_sergey
Извините, не понял.. в любом случае надо строку к DW добавлять (вопрос лишь в заполнении или в не заполнении поля с первичным ключём.). И в любом случае после нажатия "Сохранить" придётся делать update. Где гарантированный запрос?

Следите внимательно, объясняю последний раз.
При добавлении пользователем строки в DataWindow вам всегда необходимо будет исполнить запрос типа select max(field) from table
Вам это будет необходимо сдезать до записи в таблицу. Этот запрос необходимо будет исполнять всегда при вставке, в отличае от select @@identity, который нужно исполнять только после успешного insert (а еще пользователь может нажать "отмена"), и второй запрос занимает в сотни раз меньше ресурсов, чем первый.
Так что Вам тоже необходимо два запроса к серверу для вставки строки. Первый на select, второй на insert. В случае автоинкремента - первый на insert, второй на select.
Понятно?
27 апр 05, 11:18    [1501018]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
автор
если у вас там на обработке очередная чушь не написана

Товарищ, воздержитесь от грубых выражений. Я на вас не наезжал.
автор
При добавлении пользователем строки в DataWindow вам всегда необходимо будет исполнить запрос типа select max(field) from table

Это сделано на updatestart() -- то есть, только при сохранении ввода пользователем.
27 апр 05, 11:45    [1501137]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Локшин Марк
Member

Откуда: Воронеж
Сообщений: 3154
savosin_sergey
Товарищ, воздержитесь от грубых выражений. Я на вас не наезжал.

То, каким образом у вас автоинкрементное поле вычисляется иначе как чушью назвать сложно. Ну не привели вы ни одного аргумента, почему так сделано. Если все приложение написано в том же духе, то может быть и на сохранение там свой "улучшенный" алгоритм написан.
savosin_sergey
Это сделано на updatestart() -- то есть, только при сохранении ввода пользователем.

Хорошо, тогда запросов получится столько же. Но в этом случаее вообще не понятно, зачем Вам значение ключа до сохранения, если все-равно оно вычисляется непосредственно перед процедурой сохранения. Т.е. два документа шапка-подвал в одном окне не сохраняя у вас ввести нельзя?
27 апр 05, 12:10    [1501258]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
Estets
Member

Откуда: Химки
Сообщений: 604
автор
ЗоринАндрей
а если еще вспомнить что PB воспринимает не более 18 значащих разрядов, то вообще засада. и на десяток site_id может не хватить.

savosin_sergey
Откуда такая информация?


Гм из горького опыта. На самом деле PB (по крайней мере 6.5, хотя не думаю что в старших версиях что-то изменилось) воспринимает только 17 значащих разрядов.
27 апр 05, 12:50    [1501415]     Ответить | Цитировать Сообщить модератору
 Re: генерация primary key до вставки  [new]
savosin_sergey
Member

Откуда: Москва
Сообщений: 451
Локшин Марк
Кроме того, если указать для таблицы identity column, то вообще ничего делать не нужно! После вставки каждой строки PB сам запросит значение автоинкремента и запишет его в нужную колонку DW.

Что-то у меня не получилось. Сервер msSqlServer2000 (personal), таблица примерно такая:
create table bu_test (id int identity, data varchar(50))
Делаю на ней DW (grid), указываю identity column = id. После update() в соответствующей колонке значение поля id не появляется (для этого надо делать retrieve()). Даже на updateend() getItemNumber(getrow(), 'id') возвращает ноль (getRow() я проверял -- возвращает правильную строку). То ли не в том буфере искал, то ли настроил я что-то не так.

Коннекты проверялись такие:
1. DBMS="OLE DB", DBParm = "PROVIDER='SQLOLEDB'..."
2. DBMS = "MSS Microsoft SQL Server", DBParm = ""

Поле id я пробовал указывать в Updateble Columns, пробовал не указывать.. короче, надо не гадать, а знать, как это делать, чтобы работало!

В pbodb90.ini в разделе [MS_SQLSERVER_SYNTAX] указано GetIdentity='Select @@identity'.



В обоих случая нету значения identity-поля, как это утверждалось здесь. Хотя бы из-за этого генерация id-поля вручную имеет право на жизнь, как работающий вариант. Альтернатива считыванию @@identity до сохранения..
27 апр 05, 18:32    [1503200]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / PowerBuilder Ответить