Дизайн БД для использования подтипа или нет?
В базе данных, которую я проектирую, есть 3 основные таблицы: BOOKS
, ARTICLES
, NOTES
.
Каждая книга или статья может иметь несколько заметок, мой оригинальный дизайн был таким, как это, и это означает, что и заметки о книгах, и заметки о статьях идут в таблице заметок. Ниже приведены столбцы таблицы NOTES
:
-
note_id
-
note_type
-
note_type_id
-
note_content
note_type
может быть "книгой" или "статьей"; note_type_id
является FK для book_id, если note_type является "книгой" ИЛИ идентификатором статьи, если note_type является "статьей".
Теперь я начинаю задаваться вопросом, правильно ли это (или наилучшим образом нормализованный) дизайн. Альтернативный подход заключается в использовании 5 таблиц
книги/статьи/заметки/book_notes/article_notes
Таким образом, я могу отдельно хранить заметки и примечания к статье, столбцы похожи на
'notes' {note_id, note_content}
'book_notes' {book_id, note_id}
'article_notes' {articel_id, note_id}
Какой из них правильный или лучше?
Ответы
Ответ 1
Может быть, немного другой подход - супертип/подтип обычно используется, когда у вас есть очень специфичные столбцы для каждого подтипа, как в супертипе Person с подтипами Patient и Doctor. Person хранит все данные, общие для людей, а Patient и Doctor содержат очень конкретные столбцы для каждого из них. В этом примере ваши book_notes
и article_notes
не сильно отличаются друг от друга.
Я бы предпочел иметь публикацию супертипа с подтипами Book и Article. Тогда вы можете иметь только одну таблицу заметок с FK для публикации. Учитывая, что номер PK в публикации равен номеру [PK, FK] книги (статьи), вы можете делать соединения с примечаниями по публикации, книге или статье. таким образом, вы можете просто добавить другую публикацию, например, журнал, добавив новую таблицу подклассов и ничего не изменяя в отношении заметки.
Например:
TABLE Publication (
ID (PK)
, Title
, -- more columns common to any publication
)
TABLE Book (
ID (PK) = FK to Publication
, ISBN
, -- more columns specific to books only
)
TABLE Article (
ID (PK) = FK to Publication
, -- more columns specific to articles only)
TABLE Note (
ID (PK)
, PublicationID = FK to Publication
, NoteText
)
Первичный ключ для таблиц Book
и Article
также служит внешним ключом для Publication
.
Теперь, если мы добавим еще одну публикацию, журнал:
TABLE Magazine (
ID (PK) = FK to Publication
, -- more columns specific to magazines only
)
Мы не должны каким-либо образом изменять Note
- мы добавили столбцы, относящиеся только к журналам.
![pub_model_01]()
Ответ 2
С определенной точки зрения в долгосрочной перспективе гораздо лучше использовать
books/book_notes/articles/article notes
в качестве принципа разработки для вашей базы данных.
Когда вы рассматриваете резервные копии, манипулирование данными и переносимость данных с течением времени, наличие атрибутов одного объекта в собственной таблице начинает окупаться.
В абсолютном выражении ничто не является "лучшим", это зависит от контекста. Люди привыкли вкладывать что-либо в шкаф, который подходит, академические разработчики баз данных склонны создавать шкаф на зубную щетку.
В вашем контексте вы можете решить, что дополнительные накладные расходы на sql insert/select/update/delete для трех таблиц заметок вместо одного не стоит. В долгосрочной перспективе, если вы сначала идете с дизайном "1 стол для заметок", а затем решите, что вам не нравится, разделение его на 3 не похоже на переписывание войны и мира.
Ответ 3
NOTE_TYPE
может быть либо "книгой", либо "статьей"; NOTE_TYPE_ID
- это FK для book_id IF. note_type - это "книга" ИЛИ идентификатор статьи, если note_type является "статьей".
Это отношение называется дугой, представленной в логической модели данных.
Хорошо, если вы не предвидите дублирование заметок. Не только между книгами, но и статьями.
Ответ 4
Это зависит от того, что вы хотите сделать с подтипом. В ваших основных таблицах книги и статьи кажутся подтипами "публикаций" . Однако для "публикаций" нет таблицы. Это потому, что вам не нужно искать публикации или потому, что вы не думали в терминах "реляционного моделирования обобщения-специализации"? Если вы посмотрите на эту фразу в Интернете, вы увидите некоторые хорошие статьи по этому вопросу.
Предполагая, что вам не нужна обобщенная таблица "публикаций" , вам, вероятно, также не нужна обобщенная таблица "примечаний". Будете ли вы искать заметки, где не имеет значения, к какой публикации относится ссылка? Как долго это будет, прежде чем вы захотите добавить третий или четвертый вид публикации?
Все это влияет на дизайн "концептуально лучше". Если вы хотите что-то концептуально лучше, то вы оптимизируете, осознаете ли вы это или нет. Вы можете быть оптимизированы в отношении другой степени доброты, чем скорость или простота.
Ответ 5
Похоже, ваш основной фокус должен быть на Примечания. Учитывая этот оператор, я бы создал структуру данных SuperType - SubType.
Примечания будет содержать все, что делает уникальную ноту (SuperType), и только те элементы из Книги и Статьи, которые являются общими для всех (SubType).
Примечание. Поля SuperType:
- NoteID
- NoteContent
- NoteTypeId (1 = Книга 2 = статья)
Общие подтипы:
Записать уникальные поля: (NoteTypeId = 1)
- ISBN
- Издательство
- Цена
- Etc
Статья Уникальные поля: (NoteTypeId = 2)
- Webite
- Права на разнесение
- Etc
Это позволяет peolpe искать или просматривать все Примечания по содержанию, типу, типу, автору и дате. Затем для получения дополнительной информации переходите к деталям SubType.
Это также обеспечивает рост, поэтому вы можете легко добавлять другие подтипы по мере необходимости. Например, блоги (NoteTypeId = 3), FaceBookPages (NoteTypeId = 4) и т.д.