2014-10-31 3 views
0

В MySQL ... Это может быть не самый лучший пример отношений, которые мне нужны, но это то, что я пытаюсь сделать в своей БД (это очень упрощено из моей полной модели данных).Как смоделировать эти отношения (избегая циклов)?

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

  • 'DB.author': author_id, author_name
  • 'DB.book': book_id, book_name, AUTHOR_ID (это выявление отношения)

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

  • 'DB.reader': reader_id, reader_name, favorite_author_id, favorite_book_id

Я не могу просто удалить favorite_author_id колонку, потому что favorite_book_id может быть пустым. Можно ли моделировать эти отношения и избегать циклов?

ответ

0

Возможно, есть reader_favorite стол с reader_id, favorite_type и favorite value где favorite_type может быть книги или автора. Затем вы можете ВЛЕВО РАБОТЫ от reader до reader_favorite, а затем LEFT JOIN для обоих book и author из таблицы reader_favorite.

Вы тогда только обременены убедившись, что если читатель имеет вход для обоих book и author любимых типов в reader_favorite таблице, что эти два значения совпадают, но это было уже вопрос так: никакого вреда, нет фол.

0

Вы можете попробовать иметь отдельную таблицу: избранное: object_id, object_type (или что-то в этом роде), тогда у вас будет один столбец в таблице чтения для любимого id. Это также было бы несколько более растяжимым, хотя это все еще не очень приятно.

Другой вариант (в целом) могут быть ограничения (и сохраняя описанную структуру), хотя для я считаю, что это проблематично с MySQL

0

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

CREATE TABLE `author` (
    `author_id` int(11) NOT NULL AUTO_INCREMENT, 
    `author_name` varchar(20) NOT NULL, 
    PRIMARY KEY (`author_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; 

CREATE TABLE `book` (
    `book_id` int(11) NOT NULL AUTO_INCREMENT, 
    `book_name` varchar(25) NOT NULL, 
    `author_id` int(11) NOT NULL, 
    PRIMARY KEY (`book_id`,`author_id`), 
    KEY `fk_book_author` (`author_id`), 
    CONSTRAINT `fk_book_author` FOREIGN KEY (`author_id`) REFERENCES `author` (`author_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1; 

CREATE TABLE `reader` (
    `reader_id` int(11) NOT NULL AUTO_INCREMENT, 
    `reader_name` varchar(20) NOT NULL, 
    `favorite_author_id` int(11) NOT NULL, 
    `favorite_book_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`reader_id`), 
    KEY `fk_reader_favorite_book` (`favorite_book_id`,`favorite_author_id`), 
    KEY `fk_reader_favorite_author` (`favorite_author_id`), 
    CONSTRAINT `fk_reader_favorite_author` FOREIGN KEY (`favorite_author_id`) REFERENCES `author` (`author_id`), 
    CONSTRAINT `fk_reader_favorite_book` FOREIGN KEY (`favorite_book_id`, `favorite_author_id`) REFERENCES `book` (`book_id`, `author_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1; 
Смежные вопросы