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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Две связаные таблицы, каскадное обновление чтоли ? 
:(
    Опции темы
nIkTo
Дата 24.8.2010, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Существуют две таблицы tasks и jobs вот примерная структура :
Код

create table `tasks` (
    `taskID` int not null auto_increment,
    `status` tinyint not null,
    `total` int not null,
    `done` int not null,
    primary key (`taskID`)
);

create table `jobs` (
    `jobID` int not null auto_increment,
    `taskID` int not null,
    `body` varchar(20) not null,
    `status` tinyint not null,
    primary key (`jobID`),
    foreign key (`taskID`) references `tasks` (`taskID`) on delete cascade
);


Необходимо :
При изменении поля status (установится равным 2) таблицы jobs, обновить поле done (общее количество записей в таблице jobs с taskID=taskID и status=2) в таблице tasks для taskID у которого отработал job (status стал равен 2)

Как это сделать ?
PM   Вверх
skyboy
Дата 24.8.2010, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



можно при помощи триггера, можно при помощи multi table update, можно дополнительным запросом с клиента. это в общем.
а в частности - лично я не вижу картины целиком.
вот есть некий task. с каждым task'ом связано неопределенное количество job'ов. И вот у одного из job, надо что-то менять в связанном task'e. Т.е. выполнили только один job, но task отмечаем выполненным. так?
или все же надо отследить ситуацию "все job имеют status=2 - значит, помечаем task выполненным записью в поле done"?
PM MAIL   Вверх
nIkTo
Дата 25.8.2010, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



skyboy, в поле done содержится количество выполненных job для данного task
PM   Вверх
skyboy
Дата 25.8.2010, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



"ленивый" способ - добавить триггер на изменение(изменение значения поля jobs.status).
"нормализованный" - убить поле "done" с количеством связанных выполненных jobs - считать такое количество каждый раз "на лету"
PM MAIL   Вверх
nIkTo
Дата 25.8.2010, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Вот думаю так реализовать:
Код

create table `test`.`tasks` (
  `taskID` int not null auto_increment,
  `status` tinyint not null,
  `total` int not null,
  `done` int not null,
  primary key (`taskID`)
);

create table `test`.`jobs` (
  `jobID` int not null auto_increment,
  `taskID` int not null,
  `status` tinyint not null,
  primary key (`jobID`),
  foreign key (`taskID`) references `tasks` (`taskID`) on delete cascade
);

DELIMITER |
create trigger `test`.`task_done` after update on `test`.`jobs`
  for each row begin
    set @taskID = new.`taskID`;
    set @total = (select `total` from `test`.`tasks` where `taskID` = @taskID);
    set @done = (select count(*) from `test`.`jobs` where `status` = 2 and `taskID` = @taskID);
    
    if @done = @total then
      update `test`.`tasks` set `done` = @done, `status` = 2 where `taskID` = @taskID;
    else
      update `test`.`tasks` set `done` = @done where `taskID` = @taskID;
    end if;
  end;
|
DELIMITER ;


Добавлено через 9 минут и 6 секунд
А не лучше сделать триггер вот так (точнее что будет быстрее отрабатывать) ?
Код

DELIMITER |
create trigger `test`.`task_done` after update on `test`.`jobs`
  for each row begin
    set @taskID = new.`taskID`;
    set @total = (select `total` from `test`.`tasks` where `taskID` = @taskID);
    set @done = (select `done` from `test`.`tasks` where `taskID` = @taskID)+1;
    
    if @done = @total then
      update `test`.`tasks` set `done` = @done, `status` = 2 where `taskID` = @taskID;
    else
      update `test`.`tasks` set `done` = @done where `taskID` = @taskID;
    end if;
  end;
|
DELIMITER ;

PM   Вверх
Neox_GeForce
Дата 31.8.2010, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 283
Регистрация: 14.11.2007
Где: Украина

Репутация: нет
Всего: нет



Может лутше обновлять реально с клиента?
Какие будут нагрузки на БД ? И в твоем случае триггер изменяет значение другой таблицы, мне кажется это не очень эффективно.



--------------------
user posted image
Челябинские программисты настолько суровы, что обходятся без компиляторов.
Челябинские программисты настолько суровы, что считают ассемблер недопустительной роскошью - они вручную магнетизируют участки жесткого диска.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0459 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.