мягкое удаление при обновлении в MySQL с несколькими схемами - PullRequest
0 голосов
/ 28 ноября 2018

Я нахожусь в такой ситуации:

Фон

  1. У меня есть 2 схемы базы данных с именами "prod" и "stg".
  2. «prod» содержит 2 таблицы, которые называются «parent» и «child»
  3. «stg» имеет только таблицу «parent»
  4. Определение «родительской» таблицы одинаково во всех «prod» иСхемы "stg".
  5. В случае удаления записей "родительская" таблица определяется как мягкое удаление (логическое удаление, т. е. для delete_flg установлено значение "1"), тогда как для "дочерней" таблицы выполняется истинное удаление (физически).удалить запись)

Цель

Я пытаюсь достичь следующей цели: когда и только когда оба «prod». «parent» и «stg»"." parent "удаляются (независимо от того, физически или логически, или не существует на одной стороне), а затем автоматически каскадно удаляют (удаляют физически) запись в таблице" prod "." child ", чей" SP_ID "совпадает сзначение в "parent".

Например, если у меня есть

"prod"."parent"
+----+---------+--------+
| SP_ID | SP_NAME | DELETE_FLG |
+----+---------+--------+
|  1 |       1 |      1 |
+----+---------+--------+



"prod"."parent"
+----+---------+--------+
| SP_ID | SP_NAME | DELETE_FLG |
+----+---------+--------+
|  1 |       1 |      1 |
+----+---------+--------+

"stg"."parent"
+----+---------+--------+
| SP_ID | SP_NAME | DELETE_FLG |
+----+---------+--------+
|  1 |       1 |      0 |
+----+---------+--------+


"prod"."child"
+----+---------+
| SP_ID | JOB_KEY |
+----+---------+
|  1 |       key |
+----+---------+

, если я выполню обновление sql«stg». «parent» устанавливает DELETE_FLG = 1, где SP_ID = 1, что логически удаляет последнюю «существующую» запись в «родительской» таблице с SP_ID 1, тогда запись в «prod». «child» также будет автоматическиphycially удалено mysql.

Вопрос

Я думал о том, чтобы сделать SP_ID в дочерней таблице в качестве внешнего ключа, ссылающегося на тот, что в родительском состоянии (https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html) однако, а) я не знаю, можно ли ссылаться на несколько таблиц в схемах difnet, и б) кажется, что mysql поддерживает только каскадную операцию, то есть удаление на родительском элементе, затем удаление дочернего ИЛИ обновление на родительском, а затем обновлениеребенок.Но в моем случае, я хочу обновить родитель, а затем удалить ребенка.

Может кто-нибудь помочь мне здесь, пожалуйста?Возможно ли это достичь в MySQL?или я должен сделать это на прикладном уровне?

Определение таблицы

CREATE TABLE `prod`.`parent` (
  `SP_ID` varchar(20) NOT NULL COMMENT '',
  `SP_NAME` varchar(100) NOT NULL COMMENT '',
  `DELETE_FLG` tinyint(1) NOT NULL DEFAULT '0' COMMENT '',
  PRIMARY KEY (`SP_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''


CREATE TABLE `prod`.`child` (
  `SP_ID` varchar(20) NOT NULL COMMENT '',
  `JOB_KEY` varchar(11) NOT NULL,
  PRIMARY KEY (`SP_ID`,`JOB_KEY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''



CREATE TABLE `stg`.`parent` (
  `SP_ID` varchar(20) NOT NULL COMMENT '',
  `SP_NAME` varchar(100) NOT NULL COMMENT '',
  `DELETE_FLG` tinyint(1) NOT NULL DEFAULT '0' COMMENT '',
  PRIMARY KEY (`SP_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''

1 Ответ

0 голосов
/ 29 ноября 2018

с подсказкой использования триггеров. Это мое решение, которое работает: добавьте 2 триггера (один после обновления, после удаления) в родительские таблицы prod и stg.

# after update trigger
CREATE DEFINER=`root`@`localhost` TRIGGER `stg`.`parent_AFTER_UPDATE` AFTER UPDATE ON `parent` FOR EACH ROW
BEGIN
IF (
select
count(*)
from(
select 
*
from `prod`.`parent`
where `prod`.`parent`.id = old.id and `prod`.`parent`.delete_flg = 0
Union all
select 
*
from `stg`.`parent`
where `stg`.`parent`.id = old.id and `stg`.`parent`.delete_flg = 0
) as a
) = 0 THEN 
DELETE FROM `prod`.`child` WHERE `prod`.`child`.id = old.id;
END IF;
END



# after delete trigger
CREATE DEFINER=`root`@`localhost` TRIGGER `stg`.`parent_AFTER_DELETE` AFTER DELETE ON `parent` FOR EACH ROW
BEGIN
IF (
select
count(*)
from(
select 
*
from `prod`.`parent`
where `prod`.`parent`.id = old.id and `prod`.`parent`.delete_flg = 0
Union all
select 
*
from `stg`.`parent`
where `stg`.`parent`.id = old.id and `stg`.`parent`.delete_flg = 0
) as a
) = 0 THEN 
DELETE FROM `prod`.`child` WHERE `prod`.`child`.id = old.id;
END IF;
END
...