Создание отношений между таблицами MySql

Я пытаюсь создать отношения между четырьмя таблицами в MySql:

mainnodes (ID)
subnodes (ID)
tagrelationship (NODEID & TAGID)
tag (ID)

Таблица «tagrelationship» ссылается на «основные узлы», поэтому, когда я пытаюсь вставить, я могу выбирать записи из таблицы «основные узлы», однако я также хочу иметь возможность выбирать из таблицы «подузлов».

Я попытался настроить структуру таблицы для «отношения тегов» следующим образом:

CREATE  TABLE IF NOT EXISTS `database`.`tagrelationship` (
`NODEID` INT(11) NOT NULL ,
 `TAGID` INT(11) NOT NULL ,
PRIMARY KEY (`TAGID`, `NODEID`) ,
INDEX `TAGS_TAGRELATIONSHIP` (`TAGID` ASC) ,
INDEX `SUB_TAGRELATIONSHIP` (`NODEID` ASC) ,
CONSTRAINT `TAGS_AGRELATIONSHIP`
  FOREIGN KEY (`TAGID` )
  REFERENCES `database`.`tags` (`ID` )
  ON DELETE CASCADE,
CONSTRAINT `MAINNODES_CMSTAGRELATIONSHIP`
  FOREIGN KEY (`NODEID` )
  REFERENCES `database`.`mainnodes` (`ID` )
  ON DELETE CASCADE,
CONSTRAINT `SUBNODES_CMSTAGRELATIONSHIP`
  FOREIGN KEY (`NODEID` )
  REFERENCES `database`.`subnodes` (`ID` )
  ON DELETE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;

Это выполняется нормально, но я могу выбирать записи только из таблицы «подузлов», а не из обоих.

Как я могу этого добиться?

Спасибо


person Rob Fyffe    schedule 21.03.2012    source источник


Ответы (1)


Проблема в том, что ваш второй NODEID CONSTRAINT перезаписывает первый.

Это полиморфное отношение, которое вы хотите создать, поэтому одним из возможных решений, которое по-прежнему использует преимущества ограничений внешнего ключа базы данных, является использование полиморфной «супертаблицы» как для mainnodes, так и для subnodes, называемой чем-то вроде nodes:

CREATE  TABLE IF NOT EXISTS `database`.`nodes` (
`ID` INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ID`))

Затем каждая из ваших «подтаблиц» ссылается на это с ограничением внешнего ключа:

CREATE  TABLE IF NOT EXISTS `database`.`mainnodes` (
...
`NODEID` INT(11) NOT NULL,
CONSTRAINT `MAINNODE_NODE_RELATIONSHIP`
  FOREIGN KEY (`NODEID` )
  REFERENCES `database`.`nodes` (`ID` )
  ON DELETE CASCADE,
...)

CREATE  TABLE IF NOT EXISTS `database`.`subnodes` (
...
`NODEID` INT(11) NOT NULL,
CONSTRAINT `SUBNODE_NODE_RELATIONSHIP`
  FOREIGN KEY (`NODEID` )
  REFERENCES `database`.`nodes` (`ID` )
  ON DELETE CASCADE,
...)

Наконец, ваша таблица tagrelationship может просто ссылаться на супертаблицу nodes:

CREATE  TABLE IF NOT EXISTS `database`.`tagrelationship` (
...
CONSTRAINT `TAGS_AGRELATIONSHIP`
  FOREIGN KEY (`TAGID` )
  REFERENCES `database`.`tags` (`ID` )
  ON DELETE CASCADE,
CONSTRAINT `NODES_CMSTAGRELATIONSHIP`
  FOREIGN KEY (`NODEID` )
  REFERENCES `database`.`nodes` (`ID` )
  ON DELETE CASCADE,
...)

Простое, но менее надежное решение состоит в том, чтобы просто удалить последние два ограничения, на которые может ссылаться NODEID, и использовать код вашего приложения для обеспечения соблюдения ограничения.

person Ben Lee    schedule 21.03.2012
comment
Спасибо за ответ. Когда я добавляю индекс в таблицу узлов, я получаю следующее предупреждение: Индексы PRIMARY и NODE_ID кажутся равными, и один из них может быть удален. Это еще нормально? - person Rob Fyffe; 21.03.2012
comment
@ Роберт, ой, моя ошибка. Да, там должен быть только ПЕРВИЧНЫЙ индекс. Обновил мой ответ. - person Ben Lee; 21.03.2012
comment
Без проблем. Я не уверен, что мой подход сработает сейчас. В основном я пытаюсь настроить раздел пользовательского контента в Umbraco. Не уверен, есть ли у вас опыт работы с ним, но в основном, когда он создает узел/документ по умолчанию, кажется, что он добавляет записи в 3 таблицы в следующем порядке: umbraconode cmscontent cmsdocument Затем таблица «tagsrelationship» ссылается на таблицу «umbraconode». В учебниках по umbraco они создали одну таблицу для узлов пользовательского контента и вообще не ссылаются на приведенные выше таблицы. Не уверен, что таблица должна быть связана с 3 таблицами выше или нет. - person Rob Fyffe; 21.03.2012
comment
Извините, я не знаком с Umbraco. - person Ben Lee; 21.03.2012