Есть ли причина не присоединять Foreign Key к Foreign Key? - PullRequest
1 голос
/ 11 ноября 2009

У меня есть следующие таблицы:

Финансовые

  • PK_FinancialID
  • FK_SchoolID

Школа

  • PK_SchoolID

Класс

  • PK_ClassID
  • FK_SchoolID
  • ИмяКласс

И у Class, и у Financial есть связи по внешнему ключу со школой. Я хочу сделать запрос, который бы отображал все классы, связанные с финансовыми строками, которые соответствуют определенным критериям.

Изначально я думаю построить запрос следующим образом:

Select Class.ClassName
From Class
Join School on Class.FK_SchoolID = School.PK_SchoolID
Join Financial on Financial.FK_SchoolID = Schol.PK_SchoolID
Where Financial ... -- define criteria

Однако, так как Financial и Class объединяются в столбце PK_SchoolID, должна быть возможность переписать запрос следующим образом (вырезать таблицу School и напрямую соединить Class и Financial):

Select Class.ClassName
From Class
Join Financial on Financial.FK_SchoolID = Class.FK_SchoolID
Where Financial ... -- define criteria

Какой подход предпочтительнее с точки зрения sql? Повысит ли включение таблицы «Школьный» производительность, поскольку на реальную запись PK ссылаются (и, таким образом, можно ссылаться на Кластерный индекс)? Или это не имеет значения? Что-то, чего мне не хватает?

Платформа: Sql Server 2005. Все таблицы имеют свои столбцы PK и FK, должным образом объявленные и определенные.

Ответы [ 5 ]

3 голосов
/ 11 ноября 2009

Если вам не нужна Школа, не вступайте в Школу. Если вы не хотите, чтобы этот запрос выполнялся быстро, создайте индекс по FK_SchoolID таблицы Financial. Похоже, что у вас есть отношение n-1-1 между Class-School-Financial, поэтому вы должны даже создать уникальный индекс для Financial. Вы не должны (в большинстве случаев) добавлять дополнительные таблицы, чтобы сделать запрос быстрее, просто оптимизируйте используемый.

EDIT

Если вы выбираете только ClassName, возможно, вам нужно:

Select Class.ClassName
From Class
Where Exists 
    (select * from Financial 
    where (Financial.FK_SchoolID = Class.FK_SchoolID) and (...))

Это может быть быстрее, чем другие решения и более понятно.

2 голосов
/ 11 ноября 2009

Да, индекс наиболее определенно влияет на производительность.

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

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

1 голос
/ 11 ноября 2009

Мне кажется, что оба ваших примера неверны. Тот факт, что школа указана как финансовая, и что школа предлагает классы, не означает, что определенный класс является финансовым классом - это может быть художественный класс из другого курса. Кажется, что это слабость всей модели, не имеющая ничего общего с вашей техникой SQL - или, может быть, я не понимаю основную модель и все ваши особые ограничения. Однако вот пример похожей модели:

  • Одна школа может предложить множество курсов ; курс может быть предложен несколькими школами .
  • Каждая школа может иметь конкретное название и описание для «общего» * ​​1016 * курса .
  • Один сертификат требует несколько курсов ; курс может потребоваться для многих сертификатов .

certification_model_01

1 голос
/ 11 ноября 2009

Попробуйте следующее:

Select Class.ClassName
From Class
Inner Join Financial on Financial.FK_SchoolID = Class.FK_SchoolID
Where Financial....yourcriteria

Нет необходимости присоединяться к школьному столу.

0 голосов
/ 11 ноября 2009

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

Что касается производительности: я не совсем уверен, но я бы сказал, что это будет быстрее, потому что у вас будет на один стол меньше, но я не эксперт в этой области ...

...