Лишние таблицы или неспецифические внешние ключи? - PullRequest
1 голос
/ 02 сентября 2008

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

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

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

Ответы [ 5 ]

1 голос
/ 02 сентября 2008

@ palmsey

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

  • Parents

    • ParentID
  • ObjectA

    • ParentID (ФК и ПК)
    • ColumnFromA NOT NULL
  • ObjectB

    • ParentID (ФК и ПК)
    • ColumnFromB NOT NULL

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

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

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

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

1 голос
/ 02 сентября 2008

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

0 голосов
/ 20 сентября 2008

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

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

  • Foo
    • Foo ID (PK)
  • Бар
    • Бар ID (PK)
  • Комментарий
    • Идентификатор комментария (PK)
    • Текст комментария
  • FooComment
    • Foo ID (PK FK)
    • Идентификатор комментария (PK FK)
  • BarComment
    • Бар ID (ПК ФК)
    • Идентификатор комментария (PK FK)

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

  1. Позволяет вам иметь общую таблицу комментариев
  2. Не требуется БД с наследованием таблицы
  3. Не загрязняет таблицы Foo и Bar информацией, связанной с комментариями
  4. Позволяет прикрепить комментарий к нескольким объектам (которые могут быть желательны)
  5. Позволяет вам присоединить другие свойства к соединению Foo / Bar и Comment, если это необходимо.
  6. Сохраняет связь со стандартными (т. Е. Быстрыми, простыми, надежными) внешними ключами
0 голосов
/ 02 сентября 2008

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

0 голосов
/ 02 сентября 2008

@ Хэнк Гей

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

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