Осложненное добавление новой записи в БД

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Re: Осложненное добавление новой записи в БД

Сообщение wofs » 15.03.2018 20:08:15

alexs писал(а):При большой интенсивности операций - зачем лишняя нагрузка на сервер?

В MySQL использование предложенной вами схемы выльется в переизобретение велосипеда, по моему скромному мнению. Я может и недостаточно хорошо знаю MySQL, но я не встречал в нем возможность работы с генераторами как в том же FireBird.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Осложненное добавление новой записи в БД

Сообщение Снег Север » 15.03.2018 21:59:15

alexs писал(а):Лучше всего ID объектов генерить с помощью механизма генераторов/последовательностей.
Не надо этой херни в MySQL. А для решения задачи топикстартера существуют триггеры - MySQL их поддерживает минимум с версии 5.1.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: Осложненное добавление новой записи в БД

Сообщение olegy123 » 15.03.2018 22:25:28

В принципе можно сделать так
делаем функцию/процедуру
Блокируем таблицу-счетчика на чтение,
читаем значение счетчика, прибавляем
заносим в счетчик новое значение
Разблокируем таблицу..
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Осложненное добавление новой записи в БД

Сообщение sign » 16.03.2018 08:26:35

pupsik писал(а):LAST_INSERT_ID ну вернёт оно последнюю запись. И..и? Один пользователь узнал индекс, пока дошло до сохранения остальные десяток записей добавили. Что станет с индексом?

Читайте про триггеры.

Триггеры в MySQL
Триггер — это хранимая процедура, которая не вызывается непосредственно, а исполняется при наступлении определенного события ( вставка, удаление, обновление строки ).
Поддержка триггеров в MySQL началась с версии 5.0.2


Синтаксис создания триггера:
Код: Выделить всё
CREATE
    [DEFINER = { user | CURRENT_USER }]
    TRIGGER trigger_name trigger_time trigger_event
    ON tbl_name FOR EACH ROW trigger_body

Где
trigger_name — название триггера;
trigger_time — время срабатывания триггера. BEFORE — перед событием. AFTER — после события;
trigger_event — событие:

insert — событие возбуждается операторами insert, data load, replace;
update — событие возбуждается оператором update;
delete — событие возбуждается операторами delete, replace. Операторы DROPTABLE и TRUNCATE не активируют выполнение триггера;
tbl_name — название таблицы;
trigger_body — выражение, которое выполняется при активации триггера.

Пример: создадим две таблицы test и log, напишем триггер, который после добавления каждой записи в 1-ю таблицу будет вести лог этого события:

-- таблица, за которой мы будем следить
Код: Выделить всё
CREATE TABLE `test` (
`id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`content` TEXT NOT NULL
);

-- лог
Код: Выделить всё
CREATE TABLE `log` (
`id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`msg` VARCHAR( 255 ) NOT NULL,
`time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`row_id` INT( 11 ) NOT NULL
);
-- триггер
DELIMITER |
CREATE TRIGGER `update_test` AFTER INSERT ON `test`
FOR EACH ROW BEGIN
   INSERT INTO log Set msg = 'insert', row_id = NEW.id;
END;

На столбцы таблицы, к которой привязан триггер можно ссылаться с помощью псевдонимов OLD и NEW. OLD.col_name указывает на столбец с именем col_name до изменения или удаления данных. NEW.col_name относится к колонке новой строке после вставки или существующей - сразу после её обновления.
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Осложненное добавление новой записи в БД

Сообщение alexs » 16.03.2018 09:30:43

wofs писал(а):В MySQL использование предложенной вами схемы выльется в переизобретение велосипеда

Ну я сразу оговорился про нормальные БД :-)

А по теме вопроса - автору темы лучше всего наверное подойдут хранимые процедуры/функции
В неё в качестве параметра передавать исходные данные, а в ней уже распихивать по таблицам.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4051
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Осложненное добавление новой записи в БД

Сообщение pupsik » 16.03.2018 10:50:12

Читайте про триггеры.
хм.. читайте ветку...

java73 обёртки....обёртки. Главное структура :) Хотя и обёртка мелькнула. Только мельком. Возможно из-за того что проще и быстрее без оных.

Кстати: wofs вы сами пользуетесь LAST_INSERT_ID? Просто мускул - малость не моё. А судя из названия события да и много чего ещё... Чёт терзают сомнения.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: Осложненное добавление новой записи в БД

Сообщение serbod » 16.03.2018 11:11:06

Я использую синтетический номер строки таблицы (первичный ключ) состоящий из двух частей:
Код: Выделить всё
$XXXXNNNNNNNNNNNN  где
  $XXXX - код создателя записи (экземпляра программы, если их несколько)
  $NNNNNNNNNNNN - порядковый номер записи


при старте, для каждой таблицы из базы запрашиваются максимальный номер из диапазона WHERE RowID > $XXXX000000000000 AND RowID < $XXXXFFFFFFFFFFFF и дальше всякий раз при создании новой записи увеличивается на 1. Этим обеспечивается уникальность номеров и связи между таблицами еще до записи в БД. В базу пишется уже готовый первичный ключ, его не нужно потом запрашивать.

Есть еще вариант использовать GUID в качестве первичного ключа, и этот вариант является оптимальным для базы Oracle. 1С-Предприятие 8.x тоже использует GUID в качестве ключей записей.
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Осложненное добавление новой записи в БД

Сообщение Снег Север » 16.03.2018 11:19:14

Короче - для MySQL задача топикстартера решается через автоинкрементный первичный ключ и триггеры. Может еще, дополнительно, использовать хранимые процедуры - для проверок/чисток. Всё сверх того - от лукавого. И никакой зависимости от языка-обертки, разумеется, нет.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: Осложненное добавление новой записи в БД

Сообщение wofs » 16.03.2018 12:11:34

pupsik писал(а):Кстати: wofs вы сами пользуетесь LAST_INSERT_ID? Просто мускул - малость не моё. А судя из названия события да и много чего ещё... Чёт терзают сомнения.

Я на программиста не учился, в школе информатики не было. Когда потребовалось организовать систему подчинённых справочников в связке php+MySQL - открыл документацию по используемой БД и наткнулся на рекомендацию использовать ласт ИД, автоинкремент и транзакции.
За годы эксплуатации того приложения косяков не всплыло. Скоро буду переносить на один из фреймворков (писалось на чистом PHP) организую первичные ключи по рекомендациям в этой теме. Триггеры я в те времена не использовал.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Осложненное добавление новой записи в БД

Сообщение MaratIsk » 16.03.2018 15:16:12

делаю так
генерирую GUID для master-а на клиенте
при добавлении новых записей в details присваиваю GUID master-а полю по которому FK
и далее одной процедурой произвожу запись в бд
MaratIsk
новенький
 
Сообщения: 93
Зарегистрирован: 20.08.2009 18:15:20

Re: Осложненное добавление новой записи в БД

Сообщение Mirage » 16.03.2018 23:17:14

Так объяснит кто-нибудь в чем проблема-то? Интересно аж...
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Осложненное добавление новой записи в БД

Сообщение Снег Север » 17.03.2018 09:48:42

Mirage писал(а):Так объяснит кто-нибудь в чем проблема-то? Интересно аж...
На самом деле никаких проблем нет, просто топикстартер явно не в курсе про элементарные возможности мускула. А генерировать индексы на основе GUID - бггг...
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: Осложненное добавление новой записи в БД

Сообщение alexs » 17.03.2018 10:12:06

Снег Север писал(а):А генерировать индексы на основе GUID - бггг...

Абсолютно согласен.
Из за особенностей железа - очень не надёжное решение.
Лично сталкивался 3 раза - были дубликаты. Причём один раз было очень совсем не хорошо.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4051
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Осложненное добавление новой записи в БД

Сообщение MaratIsk » 17.03.2018 11:24:35

суть не в использовании GUID
можно и значение счетчика использовать

Добавлено спустя 8 минут 48 секунд:
кстати, опишите как возникли дубликаты?
MaratIsk
новенький
 
Сообщения: 93
Зарегистрирован: 20.08.2009 18:15:20

Re: Осложненное добавление новой записи в БД

Сообщение alexs » 17.03.2018 12:13:02

Точно также пыл PK на основе GUID - в итоге была коллизия при загрузке данных. Долго разбирались - как из разных подразделений такое могло прийти. Насколько помню - морда к БД бала написана на основе библиотек от MS. Вот они и дали такую бяку. Причём - нам даже потом удалось воспроизвести.
Более подробно уже не расскажу - лет 10 назад было.
С тех пор для распределённых систем всегда в качестве PK два поля - код филиала и уникальный ID, сгенерённый в самом филиале.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4051
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru