Обновление вместо вставки.

Модераторы: kdv, CyberMax

pum
Сообщения: 7
Зарегистрирован: 03 фев 2007, 15:49

Сообщение pum » 26 апр 2007, 22:16

В моей модели суррогатные ПК используются, но речь о не них сейчас не идет. Говорю о УНИКАЛЬНОМ СОСТАВНОМ КЛЮЧЕ/ПОЛЕ (Он же альтернативный ключ , АК, уникальный, УК, UK. Состоящий из нескольких полей одной таблицы, в которую добавляем данные). Дублировать ничего не надо. Просто, если новая запись будет не уникальной (по этому уникальному ключу), то надо провесли некоторые действия с имеющейся записью.
Это можно сделать простым SELECT (найти запись, повторив условия отбора). Но нужно, по возможности (для увеличения скорости ввода), убрать все лишние SELECT. При попытке вставить неуникальную запись, произойдет исключение, а это может выясниться только при создании уникального индекса новой записи (когда и выяснится, что она не уникальна). В общем, как получить rdb$db_key (именно той записи, на которой произошел сбой) на этом (после него СРАЗУ) этапе в этой процедуре?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 26 апр 2007, 22:57

еще раз:
www.ibase.ru/devinfo/testiu.htm

вариант 3, с обработкой ошибок, БЕЗ селекта - САМЫЙ МЕДЛЕННЫЙ!
я вообще фигею - ссылку на статью дали, нет, человек про "скорость ввода" начинает, и про "без селекта"...
то надо провесли некоторые действия с имеющейся записью.
и как ты это собираешься сделать, не читая запись и не зная остальных столбцов записи? Тебе же надо чего-то там сделать, или сравнить. А с чтением у тебя есть
1. прочитанная запись
2. вставляемая/обновляемая запись

и делай с этим чего хочешь.

pum
Сообщения: 7
Зарегистрирован: 03 фев 2007, 15:49

Сообщение pum » 27 апр 2007, 22:19

Хорошо, просто ответьте на несложный для Вас вопрос:
"В ТАБЛИЦЕ ЕСТЬ УНИКАЛЬНЫЙ КЛЮЧ. КАК УЗНАТЬ RDB$DB_KEY ИМЕЮЩЕЙСЯ ЗАПИСИ В МОМЕНТ, КОГДА БЫЛА ПРЕДПРИНЯТА ПОПЫТКА ВСТАВКИ ЗАПИСИ С ТАКИМ ЖЕ ЗНАЧЕНИЕМ УНИКАЛЬНОГО КЛЮЧА, И ПОЛУЧЕН ОТКАЗ." И все, больше ни о чем не прошу.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 27 апр 2007, 23:10

Ты уж прости, НО НАФИГ ТЕБЕ УПАЛ RDB$DB_KEY (кстати, кого?) ЕСЛИ ТЫ ЗНАЕШЬ ЗНАЧЕНИЕ УНИКАЛЬНОГО КЛЮЧА?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 апр 2007, 12:51

КАК УЗНАТЬ RDB$DB_KEY ИМЕЮЩЕЙСЯ ЗАПИСИ В МОМЕНТ, КОГДА БЫЛА ПРЕДПРИНЯТА ПОПЫТКА ВСТАВКИ ЗАПИСИ С ТАКИМ ЖЕ ЗНАЧЕНИЕМ УНИКАЛЬНОГО КЛЮЧА, И ПОЛУЧЕН ОТКАЗ."
никак. rdb$db_key это физический номер записи. узнать его можно только посредством select.
Также см. ответ Merlin-а.

p.s. мне интересно, сколько можно упираться против совершенно очевидных вещей? :)

p.p.s. допек ты меня. Объясняю. insert/update/delete могут обломиться по разным причинам. блокировка версии, constraint и т.п. При этом сервер только сообщает об ошибке, больше ничего. Никакие столбцы "ошибочной" записи, которая уже есть на диске, он не сообщает, никогда.

Даже если ты выполнил ПРЕДВАРИТЕЛЬНО select, и такой записи на диске НЕ ОКАЗАЛОСЬ, а потом ты делаешь insert, и получаешь key violation, то это может означать:
1. кто-то вставил запись но не сделал commit
2. твоя транзакия snapshot не может видеть даже committed изменения
3. для транзакции read_committed это означает, что в промежутке между select и insert кто-то успел вставить такую же запись.

pum
Сообщения: 7
Зарегистрирован: 03 фев 2007, 15:49

Сообщение pum » 29 апр 2007, 21:04

А что Вы посоветуете, если вставка каждой записи делается в рамках одной (отдельной) распределенной транзакции (между несколькими БД) и процент совпадений еще ниже (оцениваю его максимум в 10%). Число записей на порядок выше.
Какой механизм эффективнее применять?

Большое Спасибо за ответы.

Значит обходного пути нет.

P.S.
to Merlin: RDB$DB_KEY (кстати, там написано, КОГО) мне нужен для следующего. НЕ ХОЧУ (не хотел, а приходится) делать SELECT по значению уникального ключа. Искал способ как этого не делать, а сразу получать его после сбоя.

to kdv: Вы в p.p.s забыли сказать, что сервер не просто сообщает, еще пытается обработать ошибку, если есть обработчик.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 30 апр 2007, 00:30

pum писал(а):НЕ ХОЧУ (не хотел, а приходится) делать SELECT по значению уникального ключа.
Странный ты.
Обычно стараются всё сделать в рамках PK, не трогая системные вещи, и залазя туда только в случае крайне жёстких требований к оптимизации.
Если каждая запись будет работать в рамках отдельной транзакции, и это жёсткое твоё условие, то тебе вообще пофиг, как делать. Потому как накладные расходы на старт/коммит транзакции перекроют любые твои выкрутасы.

pum
Сообщения: 7
Зарегистрирован: 03 фев 2007, 15:49

Сообщение pum » 30 апр 2007, 12:16

Спасибо.
А что посоветуете?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 01 май 2007, 23:34

По поводу вставки уже всё сказано. PK ничем не хуже чем RDB$DBKEY, и даже лучше во многих ситуациях.
По поводу транзакций - что-то не верится, что одна запись является в твоей задаче единичным логическим блоком, чтобы так работать. Транзакция переводит базу из одного логически целостного состояния в другое. У тебя это так?

Ответить