Настройка схемы MySQL «многие ко многим» - PullRequest
3 голосов
/ 29 апреля 2011

Я настраиваю базу данных mysql с постами и тегами, которая выглядит следующим образом:

posts    
+-------------+--------------+------+-----+-------------------+----------------+
| Field       | Type         | Null | Key | Default           | Extra          |
+-------------+--------------+------+-----+-------------------+----------------+
| id          | int(11)      | NO   | PRI | NULL              | auto_increment |
[...]

tags
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| tag   | varchar(255) | NO   | UNI | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

post_tag_map
+------------+---------+------+-----+---------+-------+
| Field      | Type    | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| post_id    | int(11) | NO   | PRI | NULL    |       |
| tag_id     | int(11) | NO   | PRI | NULL    |       |
+------------+---------+------+-----+---------+-------+

Теги будут разделены между несколькими сообщениями; «красный» может использоваться постами 5 и 10.

Мой вопрос: как предотвратить удаление тега, если он используется более чем одним сообщением, и удалить его, если это не так?

Примечание: Я использую Foreign Keys, которые, как я думал, решат эту проблему, но, похоже, не работают:

CREATE TABLE `post_tag_map` (
  `post_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL,
  PRIMARY KEY (`post_id`,`tag_id`),
  FOREIGN KEY (`post_id`) REFERENCES posts(`id`),
  FOREIGN KEY (`tag_id`) REFERENCES tag(`id`)
)  

Ответы [ 3 ]

3 голосов
/ 29 апреля 2011

Вы хотите объявить внешние ключи следующим образом:

FOREIGN KEY (post_id) REFERENCES posts(id)
   ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tag(id)
   ON DELETE CASCADE

«Каскад при удалении» - это то, что инициирует автоматическое удаление. Обратите внимание, что каскад НЕ будет распространяться «вверх» на другую сторону таблицы ссылок. Если вы удалите тег, исчезнут только соответствующие записи в post_tag_map, но посты, к которым они были прикреплены, останутся одни.

3 голосов
/ 29 апреля 2011

Вы можете удалить все таблицы за один раз, используя такой оператор delete.

DELETE FROM post_tag_map, posts, tags
WHERE post.id = post_tag_map.post_id
AND tags.id = post_tag_map.tag_id
AND tags.id = 256;

Однако MySQL не дает никаких гарантий относительно порядка, в котором будет выполняться удаление. Если у вас есть внешние ключиэто может помешать удалению.

Поэтому либо не используйте предложение FOREIGN KEY **or** declare them with a ON DELETE CASCADE`.

Помните, что MyISAM не поддерживает внешние ключи, поэтому у вас есть только возможность удаления нескольких элементов.

Подробнее о возможности удаления из нескольких источников здесь: http://dev.mysql.com/doc/refman/5.1/en/delete.html

0 голосов
/ 29 апреля 2011

Возможно, вам потребуется добавить в декларации FOREIGN KEY:

http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...