Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Доброго дня ALL! озадачили вот такой проблемой. Есть PK: id_base integer, id_item bigint надо сделать аналог autoincrement для поля id_item но нумерация должна идти в пределах id_base. Судя по прочитанному такого в ASA нет (да и в других СУБД вряд-ли). Значит надо самому эмулировать этот процесс. Вопрос: КАК? Главная особенность autoincrement в том что я могу вставлять записи не дожидаясь пока другой коннект даст commit (в случае rollback этой другой сессии просто будет дыра в id_item что не страшно). Тесты с тригерами на вставку и select max(id_item) with (readuncommited) к успеху не привели - два коннекта получают одинаковые значения и торжественно вылетает PK is not unique ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 17:01 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov wrote: > Тесты с тригерами на вставку и select max(id_item) with (readuncommited) > к успеху не привели - два коннекта получают одинаковые значения и > торжественно вылетает PK is not unique Тебе нужно запихнуть вставку в цикл и вставлять до тех пор, пока не вставит. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 17:15 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
> Тебе нужно запихнуть вставку в цикл и вставлять до тех пор, пока не вставит. Интересное решение. Интересно, а на уровне тригерной логики такое провернуть реально? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 17:22 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov пишет: > Судя по прочитанному такого в ASA нет (да и в других СУБД вряд-ли). Такая реализация есть в MySQL. Кривая, правда. > Тесты с тригерами на вставку и select max(id_item) with (readuncommited) > к успеху не привели - два коннекта получают одинаковые значения и > торжественно вылетает PK is not unique Надо уровень изоляции транзакции повышать до SERIALIZABLE. Иначе такая схема работать не будет. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 17:51 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Для АСА 9 и выше (не знаю про более нижние версии) посмотрите в сторону функции GET_IDENTITY() Помню такое, что она резервирует ключ (хотя может и ошибаюсь) давно было. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 18:02 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
PaulJBДля АСА 9 и выше (не знаю про более нижние версии) посмотрите в сторону функции GET_IDENTITY() Помню такое, что она резервирует ключ (хотя может и ошибаюсь) давно было. Это работает и справедливо если у тебя ключ состоит только из autoincrement поля. MasterZiv > Тесты с тригерами на вставку и select max(id_item) with (readuncommited) > к успеху не привели - два коннекта получают одинаковые значения и > торжественно вылетает PK is not unique Надо уровень изоляции транзакции повышать до SERIALIZABLE. Иначе такая схема работать не будет. Вот тут как раз мне нельзя поднимать уровень изоляции. Т.к. пока одна сессия вставляет (процес от миллисек до минуты) другая должна спокойно писать свои данные. Повторю - поле autoincrement это позволяет (примерно я себе представляю алгоритм работы этого процесса - счетчик, но не вижу путей для его реализации собственными силами, т.к. я не могу менять измененный данные пока не пройдет commit). Буду экспеерментировать с внешними процедурами ;((( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 18:22 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov wrote: > Интересное решение. Ничего интересного - баян ещё тот. Кстати, абсолютно незаменимая вещь, если у тебя первичный ключ не autoincrement. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 18:30 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov пишет: > Надо уровень изоляции транзакции повышать до SERIALIZABLE. > Иначе такая схема работать не будет. > > Вот тут как раз мне нельзя поднимать уровень изоляции. Т.к. пока одна > сессия вставляет (процес от миллисек до минуты) другая должна спокойно > писать свои данные. А это не значит обязательно, что другая сессия не вставит свои данные. Она не сможет вставить конфликтующие данные. И без повышения ничего работать не будет. Так что тут IDENTITY рулит. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2007, 20:04 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
MasterZiv v_smirnov пишет: А это не значит обязательно, что другая сессия не вставит свои данные. Она не сможет вставить конфликтующие данные. И без повышения ничего работать не будет. Так что тут IDENTITY рулит. Posted via ActualForum NNTP Server 1.4 Не забываем про условия моей задачи. "In SQL Anywhere, the IDENTITY column and the AUTOINCREMENT default setting for a column are identical." У меня ДВА поля в ключе и AUTOINCREMENT должен идти для каждого id_base свой!!! Пока вопрос решается так: Реализовали свой счетчик для такой таблицы + внешняя процедура со своим коннектом (и как следствие своей транзакцией). Многократную вставку реализовать на тригерной логике похоже невозможно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2007, 08:40 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Не совсем понятна задача. В ASA10 в таблице добавил два поля, на каждое указал autoinrement и оба включил их первычный ключ. Или нужно как то по другому? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2007, 15:38 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
VolokolaНе совсем понятна задача. В ASA10 в таблице добавил два поля, на каждое указал autoinrement и оба включил их первычный ключ. Или нужно как то по другому? PK: id_base integer, id_item bigint надо сделать аналог autoincrement для поля id_item но нумерация должна идти в пределах id_base. id_base константа для логической базы. на одном сервере может быть несколько логических баз. пример - id_base = 2 - база №2. id_item - от 1 до ... в пределах id_base=2 id_base = 4 - база №4. id_item - от 1 до ... в пределах id_base=4 etc ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2007, 16:18 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Если кол-во значений id_base не много(а даже и много), то можно пойти по проверенному варианту: сделать таблицу пулов ключей Таблица Poolkey: 2 Поля: id_base и id_item При появлении новой id_base добавлять туда запись insert into Poolkey values(id_base,1) А новый ключ для каждой записи запрашивать через процедуру, которой передавать @id_base. Процедура сделает типа: select @id_item=id_item from Poolkey where id_base=@id_base update Poolkey set id_item=id_item+1 where id_base=@id_base И возвращает @id_item(@id_base уже есть). Естественно все это в транзакции с нужным уровнем изоляции. Ключ получили, можно вставлять. Если не вставили, то будут пропуски, но это я понял, автору не критично. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2007, 20:34 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
antand А новый ключ для каждой записи запрашивать через процедуру, которой передавать @id_base. Процедура сделает типа: Именно так и сделано (пулл id-ов) за исключением одного нюанса. Процедура внешняя ... Причина по которой процедура была вынесена за пределы СУБД проста - у нее (процедуры) в таком исполнении свои транзакции что немаловажно для решения задачи, а именно: 1. Вставка может идти как 1 сек так и несколько минут. 2. Если делать внетренней процедурой то после Update запись будет заблокирована на запись до завершения транзакции и как следствие другой коннект не сможет получить новый ид... 3. насколько я понял алгоритм работы - обновление счетчика autoincrement поля именно так и происходит, в своей транзакции (реализована внутренними средствами СУБД и аналог реализовать стандартными средствами похоже невозможно). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 09:40 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Я поступал примерно также, только привязку делал по времени current_time=current timestamp, и вставлял 1 и current_time, после чего делал select sum() where time1<= current_time, ну а в основной таблице стоял триггер after на удаление записи, где вначале менялись ключи с номером большим удаленного, уменьшались на 1, после чего удалялась одна запись в вспомогательной таблице. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 09:58 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov 1. Вставка может идти как 1 сек так и несколько минут. 2. Если делать внетренней процедурой то после Update запись будет заблокирована на запись до завершения транзакции и как следствие другой коннект не сможет получить новый ид... 3. насколько я понял алгоритм работы - обновление счетчика autoincrement поля именно так и происходит, в своей транзакции (реализована внутренними средствами СУБД и аналог реализовать стандартными средствами похоже невозможно). Все должно работать нормально при правильной реализации без всяких внешних процедур. Вставка может идти хоть 2 часа, только это не значит что нужно транзакцию получения ключей на 2 часа растягивать. Получите все ключи до вставки. Причем можно и за одну транзакцию(один вызов процедуры) получить сразу несколько ключей для всех вставляемых записей(передать в процедуру еще один параметр - кол-во) Она за раз сдвинет счетчик на кол-во, возвратит "последний" ключ, а остальные из него получите сами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 12:01 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov PK: id_base integer, id_item bigint надо сделать аналог autoincrement для поля id_item но нумерация должна идти в пределах id_base. id_base константа для логической базы. на одном сервере может быть несколько логических баз. пример - id_base = 2 - база №2. id_item - от 1 до ... в пределах id_base=2 id_base = 4 - база №4. id_item - от 1 до ... в пределах id_base=4 etc ... Для этого в ASA существует global autoincrement. Ставите опцию базы GLOBAL_DATABASE_ID равной id_base, на id_Item указываем global autoincrement и partition size - который вам нужен. ASA определяет ранг значения счетчика по формулам: от (DBID * PartitionSize + 1) по ((DBID + 1) * PartitionSize). Например, если мы укажем размером интервала 1000, то для БД с кодом 2 диапазон допустимых значений для глобального счетчика будет от 2001 до 3000. С уважением Вадим. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 14:24 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Все должно работать нормально при правильной реализации без всяких внешних процедур. Вставка может идти хоть 2 часа, только это не значит что нужно транзакцию получения ключей на 2 часа растягивать. Получите все ключи до вставки. Это хорошо если можно реализовать на уровне процедур или апликации. Т.е. если заранее известно сколько надо вставить. В случае когда идет поток вставок с неизвестным кол-вом в одной транзакции такой подход неприемлем. А вот для одиночной вставки, либо вставки фиксированного значения вначале вычислить иды в отдельной транзакции ...вполне подходит. 2 Volokola - использовать global autoincrement не хочу, не нравится мне. Для меня он имеет больше минусов чем плюсов ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2007, 23:54 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
Если смотреть в сторону таблицы PoolKey, то для одной id_base выделить по несколько непересекающихся диапазонов. Тогда используя readpast можно бужет поддерживать несколько одновременных транзакций ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 12:15 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
v_smirnov В случае когда идет поток вставок с неизвестным кол-вом в одной транзакции такой подход неприемлем. Тогда можно поподробнее. Как у Вас организован это поток вставок? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 12:41 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
antandТогда можно поподробнее. Как у Вас организован это поток вставок? Не у меня ;) ... Алгоритм хитрый - внешний клиент начинает вставлять данные, при чем именно в момент вставки (тригером) принимается решение о дополнительной вставке в эту же таблицу. (пришла одна запись - сохранить как 2..3..N). Т.е. если даже клиент скажет что у него всего 30 строк на вставку высчитать сколько это на самом деле не представляется возможным. Такая логика, что поделать. Либо переделывать ее (логику) либо внешняя функция (счетчик) в отдельной транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.11.2007, 17:35 |
|
||
|
autoincrement по составному PK
|
|||
|---|---|---|---|
|
#18+
>>Тесты с тригерами на вставку и select max(id_item) with (readuncommited) к >>успеху не привели - два коннекта получают одинаковые значения и >>торжественно вылетает PK is not unique Это потому, что триггер делал BEFORE. А надо сделать AFTER. У меня именно так и реализован такой же функционал. Для варианта, когда на каждую base_id приходится всего несколько штук item_id, держать пул ключей не обязательно, достаточно проиндексировать base_id и триггером делать установку поля item_id. К тому же, у себя я еще такой финт делал: на поле item_id стоял автоинкремент, но триггер на вставке его перезабивал новым значением. Таким образом получилось возможным делать вставку в таблицу с указанием base_id без item_id, а затем делать select @@identity, чтобы получить item_id... Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2007, 12:03 |
|
||
|
|

start [/forum/topic.php?fid=55&msg=34963536&tid=2011792]: |
0ms |
get settings: |
7ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
42ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
82ms |
get tp. blocked users: |
2ms |
| others: | 288ms |
| total: | 462ms |

| 0 / 0 |
