Дизайн БД для использования подтипа или нет?

В базе данных, которую я проектирую, есть 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) и т.д.