Осложненное добавление новой записи в БД
Модератор: Модераторы
Осложненное добавление новой записи в БД
Привет, друзья.
Кто как решает проблему добавления новой записи в БД, если при этом возникает одновременная необходимость добавить отношения многие-ко-многим? Поясню. Есть запись допустим об объекте. Пока она новая, она не имеет уникального индекса, то есть сначала нужно запись сохранить, чтобы в таблице сопоставления ссылок отношений таблиц можно было добавлять записи уже с использованием нового индекса.
Я пока сделал так, как в 1С: основные поля таблицы заполняются, затем пользователь должен сохранить запись в БД, только после этого он снова открывает на редактирование и добавляет необходимые связи.
Я думал, с помощью каких-то объектных оберток можно это удобнее организовать. Сижу курю документацию к tiOPF, но чтобы перейти на эти рельсы мне нужно будет полностью весь проект перелопатить(((( одновременно изучаю C#, быть может там что лучше.
Кто как решает проблему добавления новой записи в БД, если при этом возникает одновременная необходимость добавить отношения многие-ко-многим? Поясню. Есть запись допустим об объекте. Пока она новая, она не имеет уникального индекса, то есть сначала нужно запись сохранить, чтобы в таблице сопоставления ссылок отношений таблиц можно было добавлять записи уже с использованием нового индекса.
Я пока сделал так, как в 1С: основные поля таблицы заполняются, затем пользователь должен сохранить запись в БД, только после этого он снова открывает на редактирование и добавляет необходимые связи.
Я думал, с помощью каких-то объектных оберток можно это удобнее организовать. Сижу курю документацию к tiOPF, но чтобы перейти на эти рельсы мне нужно будет полностью весь проект перелопатить(((( одновременно изучаю C#, быть может там что лучше.
и..и? Ну а что не так?Пока она новая, она не имеет уникального индекса, то есть сначала нужно запись сохранить, чтобы в таблице сопоставления ссылок отношений таблиц можно было добавлять записи уже с использованием нового индекса.
Обёртки, большей частью, пишутся для себя. Иногда "в общем". Но что то, что то один леший требует знакомства. И всё это из-за скрипта и 6 строк кода (которые плавно перетекут в процедуру и образуют 1 строку)? Плюс некоторые вещи можно решить на стороне сервера.
а смена коня повлияет на трамплин?одновременно изучаю C#, быть может там что лучше
pupsik писал(а):и..и? Ну а что не так?
хочется без промежуточного сохранения. Как вариант, конечно, наплодить дополнительных компонентов, которые не будут DB look up компонентами, а обычными, и из них потом уже копировать выбранные данные в саму БД.
pupsik писал(а):а смена коня повлияет на трамплин?
ДА, хотя бы из-за того, чтоб перестать сталкиваться с недопиленными для лазаруса компонентами (хотя бы html-читалка или встроенный webbrowser), кривыми поддержками печати на принтерах, и отсутствия приятного для кодинга экспорта в форматированные и редактируемые документы (хотя тут я уже решил все проблемы с помощью html шаблонов).
P.S.
Сразу после создания новой записи сохранить и уже сохраненную начать редактировать я не могу, т.к. встроил уже многочисленные проверки корректности введенных данных..
alexs писал(а):В нормальных базах обычно можно заранее знать (получить) ID будущей записи
А про mysql если поподробнее?
Добавлено спустя 9 минут 15 секунд:
При этом, если пользователь передумает запись сохранять, но добавит несколько связей, то их еще придется удалять ((( даже не знаю, может оставить как есть всё
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
java73 писал(а):А про mysql если поподробнее?
Код: Выделить всё
SELECT LAST_INSERT_ID();
//ВАЖНО!
//если есть вероятность работы с таблицей несколькими пользователями, то обязательно управлять транзакциями, иначе вы можете получить ID записи, добавленной кем-то другим, а не вами.
java73 писал(а):При этом, если пользователь передумает запись сохранять, но добавит несколько связей, то их еще придется удалять ((( даже не знаю, может оставить как есть всё
Транзакции?
LAST_INSERT_ID ну вернёт оно последнюю запись. И..и? Один пользователь узнал индекс, пока дошло до сохранения остальные десяток записей добавили. Что станет с индексом?
п.с.
Чёт всегда думал что смена наездника может повлиять на качество. Ну да ладно. Это не столь важно.
а нет варианта использовать отдельную таблицу для идентификации записи, и от неё "отталкиваться"?Сразу после создания новой записи сохранить и уже сохраненную начать редактировать я не могу..
п.с.
Чёт всегда думал что смена наездника может повлиять на качество. Ну да ладно. Это не столь важно.
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
pupsik писал(а):LAST_INSERT_ID ну вернёт оно последнюю запись. И..и? Один пользователь узнал индекс, пока дошло до сохранения остальные десяток записей добавили. Что станет с индексом?
Я основываюсь на: https://dev.mysql.com/doc/refman/5.7/en ... ue-id.html
В частности:
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
А на чем основан ваш вывод?
То есть я предлагал стартовать транзакцию, вставить запись, получить ID и спокойно делать с ним, что душе угодно (например,создавать связанные записи в других таблицах). Если мы передумали сохранять, то просто откатить транзакцию. Как может измениться кем-то ID уже вставленной записи да еще и в чужой транзакции?
p.s. или я не правильно понял смысл абзаца?
Угу... Сморозил глупость.
Но не катит...
Т.е. вы предложили:
1. старт транзакции
2. сохранение записи
3. получения индекса
4. откат или сохранение.
Но..:
Но не катит...
Т.е. вы предложили:
1. старт транзакции
2. сохранение записи
3. получения индекса
4. откат или сохранение.
Но..:
а это п.2. Или я не верно понял?хочется без промежуточного сохранения.
- alexs
- долгожитель
- Сообщения: 4066
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
java73 писал(а):А про mysql если поподробнее?
Вот это тот случай
Как я понял - стоит задача сформировать несколько связанных между собой данных на стороне клиента в разные таблицы. Автоинкрементные колонки вам не подойдут.
Лучше всего ID объектов генерить с помощью механизма генераторов/последовательностей.
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
pupsik писал(а):а это п.2. Или я не верно понял?
Наверное криво написал...
п.2 читать как создание записи в таблице (в рамках открытой транзакции).
Это не "промежуточное сохранение". Это резервирование ID для последующего использования в связанных таблицах. В случае отката транзакции запись просто перестанет существовать.
alexs писал(а):Как я понял - стоит задача сформировать несколько связанных между собой данных на стороне клиента в разные таблицы. Автоинкрементные колонки вам не подойдут.
Просветите, пожалуйста, отчего так категорично? Ведь мы можем сделать поле с автоинкрементом первичным ключем.
- alexs
- долгожитель
- Сообщения: 4066
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
wofs писал(а):Просветите, пожалуйста, отчего так категорично? Ведь мы можем сделать поле с автоинкрементом первичным ключем.
А как автоинкрементными полями получить гарантированно уникальные значения ключей без физического добавления записей?
Т.е. если параллельно идёт работа нескольких процессов по формированию пакетов данных? И чтобы этот пакет сохранить единым махом?
Простейший пример
Создаём карточку товара, которая содержит атрибуты
Т.е. есть основная запись и подчинённые -которые ссылаются на основную. Т.е. при создании новой карточки просим у генератора следующее значение
Потом (после редактирования) добавляем основную запись и подчинённые.
Ну или не добавляем.
Я понимаю что для этого примера автоинкрементные поля применять не сложно. Но значение ключ от основной записи увидим только после её добавления.
А в случае с генератором - значение PK увидим тогда, когда нам удобно.
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
alexs писал(а):Но значение ключ от основной записи увидим только после её добавления.
А в чем трагедия добавления записи и ее удаление по откату транзакции в случае нежелания сохранить?
p.s. Притом, что у ТС Mysql, а там целый велосипед с генераторами.
-
Mirage
- энтузиаст
- Сообщения: 881
- Зарегистрирован: 06.05.2005 20:29:07
- Откуда: Russia
- Контактная информация:
"Не имеет уникального индекса" означает "не имеет ID"? Почему бы не использовать общепринятую терминологию...
А в чем проблема-то? Ну создал сущность, создал доп. сущности.
При нажатии "Сохранить" все сущности отправились на сохранение: основная, те, что многие-ко-многим, теперь, имея ID всех записей, сохраняем их в таблицу связей.
В качестве бонуса, если что-то при сохранении упало, транзакция откатится и мусора в БД не останется.
ORM типа mORMot сделает это автоматически, но и вручную тоже не особо сложно.
А в чем проблема-то? Ну создал сущность, создал доп. сущности.
При нажатии "Сохранить" все сущности отправились на сохранение: основная, те, что многие-ко-многим, теперь, имея ID всех записей, сохраняем их в таблицу связей.
В качестве бонуса, если что-то при сохранении упало, транзакция откатится и мусора в БД не останется.
ORM типа mORMot сделает это автоматически, но и вручную тоже не особо сложно.
