Дополнительные таблицы или неспецифические внешние ключи?

StackOverflow https://stackoverflow.com/questions/39915

Вопрос

В системе существует несколько типов объектов, и у каждого есть своя таблица в базе данных.Пользователь должен иметь возможность комментировать любой из них.Как бы вы оформили таблицу (ы) комментариев?Я могу придумать несколько вариантов:

  1. Одна таблица комментариев со столбцом FK для каждого типа объекта (ObjectAid, ObjectBID и т.д.)
  2. Несколько таблиц комментариев, по одной для каждого типа объекта (ObjectAComments, ObjectBComments и т.д.)
  3. Один общий FK (ParentObjectID) с другим столбцом для указания типа ("ObjectA")

Что бы вы выбрали?Есть ли лучший метод, о котором я не думаю?

Это было полезно?

Решение

@палмси

В значительной степени, но вариация этого шаблона, которую я видел чаще всего, избавляет от ObjectAID et al. ParentID становится как PK, так и FK для Parents.Это дает вам что-то вроде:

  • Parents

    • ParentID
  • ObjectA

    • ParentID (FK и PK)
    • ColumnFromA NOT NULL
  • ObjectB

    • ParentID (FK и PK)
    • ColumnFromB NOT NULL

Comments остался бы прежним.Тогда вам просто нужно ограничить генерацию идентификаторов, чтобы случайно не получить ObjectA ряд и ObjectB строка, в которой оба указывают на одно и то же Parents ряд;самый простой способ сделать это - использовать ту же последовательность (или что угодно еще), которую вы используете для Parents для ObjectA и ObjectB.

Вы также видите множество схем с чем-то вроде:

  • Parents
    • ID
    • SubclassDiscriminator
    • ColumnFromA (nullable)
    • ColumnFromB (nullable)

и Comments останется неизменным.Но теперь вы не можете применить все свои бизнес-ограничения (все свойства подклассов обнуляются) без написания триггеров или выполнения этого на другом уровне.

Другие советы

Можно ли спроектировать схему так, чтобы таблицы с комментариями (из-за отсутствия лучшего слова) следовали одному из стандартных шаблонов моделирования наследования? Если это так, вы можете указать FK таблицы комментариев на общую родительскую таблицу.

@ Хэнк Гей

Так что-то вроде:

  1. ObjectA
    • ObjectAID
    • ParentID
  2. ObjectB
    • ObjectBID
    • ParentID
  3. Комментарии
    • CommentID
    • ParentID
  4. родители
    • ParentID

Будьте осторожны с общими внешними ключами, которые не указывают точно на одну таблицу. Производительность запросов значительно снижается, если вам нужно разделить условие where для типа и указать несколько разных таблиц. Если у вас есть только несколько типов, и число типов не будет расти, то нормально иметь отдельные внешние ключи, допускающие обнуляемость, для разных таблиц, но если у вас будет больше типов, лучше придумать другую модель данных (например, предложение @ palmsey).

Одна из вещей, которые мне нравится делать, - это иметь отдельные таблицы, которые связывают общую таблицу со всеми индивидуальными таблицами.

Итак, для объектов Foo и Bar, а затем комментариев к Foo & Bar у вас будет что-то вроде этого:

  • Фу
    • Идентификатор Foo (PK)
  • Бар
    • Идентификатор бара (PK)
  • Комментарий
    • Идентификатор комментария (PK)
    • Текст комментария
  • Описание
    • Идентификатор Foo (PK FK)
    • Идентификатор комментария (PK FK)
  • Штрих - код
    • Идентификатор бара (PK FK)
    • Идентификатор комментария (PK FK)

Эта структура:

  1. Позволяет вам иметь общую таблицу комментариев
  2. Не требует базы данных с наследованием таблиц
  3. Не загрязняет таблицы Foo и Bar информацией, связанной с комментариями
  4. Позволяет вам прикрепить комментарий к множественный объекты (которые могут быть желаемыми)
  5. Позволяет вам при желании присоединить другие свойства к соединению Foo / Bar и Comment.
  6. По-прежнему сохраняет отношения со стандартом (т.е.:быстрые, простые, надежные) внешние ключи
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top