Внешний ключ CASCADE DELETE для таблицы с несколькими родителями? - PullRequest
1 голос
/ 07 февраля 2012

Я очень плохо знаком с внешними ключами и операциями CASCADE, и меня интересует следующий сценарий:

Допустим, у меня есть две совершенно разные родительские таблицы (HUMAN и ALIEN) с совершенно разными данными.Теперь я хочу создать дочернюю таблицу с именем SPACESHIP, поскольку и люди, и инопланетяне могут иметь космические корабли с FK, который будет указывать либо на строку в HUMAN, либо на строку в ALIEN, в надежде, что если я удалю либочеловеческий ряд или ряд пришельцев, он будет каскадно удалять соответствующие строки космического корабля, принадлежащие соответствующему родителю.Есть ли хороший способ сделать это с FK и CASCADE DELETE?Или я должен просто иметь столбец в HUMAN и ALIEN с именем spaceship_id и обрабатывать удаление космических кораблей вручную / через триггер?Какой-то другой курс действий?

Помогите!

Ответы [ 2 ]

2 голосов
/ 07 февраля 2012

Эту проблему можно решить, добавив таблицу супертипа (назовем ее Being), которая имеет в качестве подтипов две таблицы Human и Alien. Тогда ограничение FOREIGN KEY будет ссылаться на эту таблицу супертипа.

Супертип:

CREATE TABLE Being
( BeingId  INT AUTO_INCREMENT
, ... other stuff about beings
, PRIMARY KEY (BeingId)
) ENGINE = InnoDB ;

подтипы:

CREATE TABLE Human
( BeingId  INT                           --- not AUTO_INCREMENT
, ... other stuff about humans
, PRIMARY KEY (BeingId)
, CONSTRAINT Being_Human_fk
    FOREIGN KEY (BeingId)
      REFERENCES Being(BeingId)
      ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB ;

CREATE TABLE Alien
( BeingId  INT                           --- not AUTO_INCREMENT
, ... other stuff about aliens
, PRIMARY KEY (BeingId)
, CONSTRAINT Being_Alien_fk
    FOREIGN KEY (BeingId)
      REFERENCES Being(BeingId)
      ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB ;

и таблица Spaceship:

CREATE TABLE Spaceship
( SpaceshipId
, SpaceshipName
, OwnerId
, ... other stuff about spaceships
, PRIMARY KEY (SpaceshipId)
, CONSTRAINT Being_Spaceship_fk
    FOREIGN KEY (OwnerId)
      REFERENCES Being(BeingId)
      ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB ;
0 голосов
/ 07 февраля 2012

Если вы используете InnoDB механизм хранения, то вы можете использовать внешние ключи, потому что в настоящее время их поддерживает только InnoDB. В противном случае вы можете использовать триггеры или удалить родительские и дочерние записи, используя один запрос, например ::

DELETE HUMAN, SPACESHIP
 FROM HUMAN
 JOIN SPACESHIP
   ON HUMAN.id = SPACESHIP.id
WHERE HUMAN.id = 1; 
...