2

Я только начал применять все, что я читал о связях с таблицами, но я немного смущен тем, как вставлять данные в таблицы с отношениями MANY-TO-MANY, учитывая, что есть третья таблица.Внешний ключ или композитный ключ?

Прямо сейчас у меня есть эти столы.

Заголовок

name 
code PK 
units 
description 

учебный год

schoolyearId PK 
yearStart 
yearEnd 

schoolyearsubjects (многие ко многим таблице)

id PK 
code FK 
schoolyearId FK 

Но проблема с вышеупомянутой таблицей schoolyearsubjects заключается в том, что я не знаю, как я могу вставить schoolyearId из графического интерфейса. На скриншоте GUI, как только «Сохранить» кнопка нажата, TRANSACTION содержащий INSERT заявления (для вставки на subject) и (для вставки на schoolyearsubjects) будет выполняться. Если я придерживаюсь вышеуказанного, мне придется вставить учебное пособие. schoolyearId определенно не будет отображаться в графическом интерфейсе.

enter image description here

Я имею в виду изменения столбцов schoolyearsubjects и schoolyear к этому:

учебный год

--composite keys (yearStart, yearEnd) 
yearStart (PK) 
yearEnd (PK) 

schoolyearsubjects (многие ко многим таблицы)

id PK 
code (FK) 
yearStart (FK) --is this possible? 
yearEnd (FK) --is this possible? 

1.) Является ли решение для изменения столбцов и создания составного ключа, поэтому я могу просто вставить значения yearStart и yearEnd вместо schoolyearId?

2.) Является ли мой соединительный/соединительный стол школьным языком правильным?

3.) Что вы можете посоветовать?

Буду признателен за любую помощь.

Спасибо.

+1

Мне кажется, что база данных не проблема (вы можете либо работать с техническими идентификаторами, либо с помощью естественных составных клавиш, оба из них прекрасны). Это графический интерфейс. Что вы хотите сделать? Добавить новую тему? Добавить новый учебный год? Связать предмет с учебным годом? Кажется, вы смешиваете эти вещи, которые должны быть отдельными действиями. –

+0

Спасибо за замечание. Я хотел бы связать учебный год с предметами. Но объединение предметов должно происходить при создании темы. Любое предложение? – p3ace

+0

Я не совсем понимаю проблему. Вы говорите об этом графическом интерфейсе, как если бы он был каким-то образом создан и не написан вами. Это так? Для чего еще вы не можете просто позволить пользователю выбрать учебный год из списка (список или combobox со строками «2015/2016», «2016/2017» и т. Д.), Попросите их ввести тему, начать транзакцию , создать и выполнить оператор, чтобы сохранить тему, создать и выполнить инструкцию для сохранения школьных объектов и совершить? –

ответ

1

Для меня школьный период - это период, и здесь нет необходимости использовать здесь суррогатный ключ. Это всегда делает вещи более запутанными, и для них всегда сложнее разрабатывать графический интерфейс (я говорю о том, как мы моделируем периоды как разработчики).

Если вы перестали думать, периоды воспринимаются как нечто уникальное. У вас будет период, равный другому? Остановись и подумай. Даже если у вас есть, это произойдет в годах или в разное время. Таким образом, у нас уже есть первичный ключ для школьного возраста. Исключить «школьный ПК» из школьного возраста. Используйте комбинированный ключ здесь с yearStart и yearend. Таким образом, ваше учебный год предприятие (в дальнейшем, таблица) будет как:

  • yearStart PK
  • КОНЕЦ PK

В промежуточной таблице, вы будете иметь 3 поля как составной первичный ключ (также внешний ключ):

  • yearStart PK FK (от учебного года)
  • КОНЦА PK FK (от учебного года)
  • Код PK FK (от предмета)

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

Теперь, чтобы нарисовать графический интерфейс, вам нужно будет использовать только поле выбора (поле со списком). В этом случае вы будете иметь каждый элемент как текст, что-то вроде «от года X до Y» (период). Ваши пользователи могут очень хорошо понимать и выбирать.

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

Если, однако, у вас нет периодов как нечто уникальное, то «yearStart» и «yearEnd» являются полями в субъекте субъекта, и нет учебного объекта. Честно говоря, сущность «schoolyear» должна существовать только в том случае, если вы хотите повторно использовать ее записи для отношений с другими записями других таблиц. Я не говорю, что это так или нет. Остерегайтесь. Если вы сделаете это, вы скажете, что каждый период имеет только один предмет (как поля).Я не знаю, это именно то, что вы хотите. Мы всегда должны помнить самое главное в деле формирования ER-диаграмма:

  • КОНТЕКСТ

Проверьте контекст. Что он спрашивает? Если у вас есть какие-либо вопросы, прокомментируйте. Если вы можете предложить мне больше контекста, я могу помочь вам больше.

+0

Спасибо за совет. – p3ace

0

Если у вас есть параметры @code, @yearStart и @yearEnd со значениями из UI:

INSERT INTO schoolyearsubjects (code, yearStart, yearEnd) 
SELECT @code, y.yearStart, y.yearEnd 
    FROM schoolyear y 
WHERE @yearStart <= y.yearStart 
     AND y.yearEnd <= @yearEnd; 

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

INSERT INTO schoolyearsubjects VALUES ('code red', '2016', '2017'); 
INSERT INTO schoolyearsubjects VALUES ('code red', '2016', '2017'); 
INSERT INTO schoolyearsubjects VALUES ('code red', '2016', '2017'); 

похоже, что это приведет к трем фактическим дублирующим строкам.

+0

Во-первых, спасибо за совет. Я все еще пытаюсь поглотить и проанализировать это. С schoolyearsubjects я подумываю о том, чтобы хранить учебный год по предметным кодам, поскольку один предмет может принадлежать к разным школьным годам, а в учебном году может быть много предметов. Хорошо, я посмотрю на это и посмотрю, какие изменения можно сделать. Еще раз спасибо. – p3ace

+0

О да, ты прав. Это дублирование. Могу ли я просто добавить ограничение UNIQUE, чтобы исправить это? Просто убедившись, что я делаю это правильно. – p3ace

0

С вашей текущей схемой вы можете вставить schoolyearId с просьбой следующим образом:


    INSERT INTO schoolyearsubjects (id, code, schoolyearId) 
    VALUES (${id}, 
      ${code_from_GUI}, 
      (SELECT schoolyearId 
       FROM schoolyear 
       WHERE yearStart=${start_from_GUI} AND yearEnd=${end_from_GUI}) 
      ); 

Для этого, чтобы работать, уникальное ограничение на (yearStart, КОНЕЦ) в таблице учебного года требуется.

Что касается прочих вопросов:
1) Вы можете использовать составной ключ в школьном столе, он будет работать в любом случае.
2) Школьные объекты правильны, так как позволяют писать запросы присоединения. Если вы избавитесь от столбцов schoolyearId, то вам вряд ли понадобится школьная таблица, так как все данные, которые вы, возможно, захотите получить, будут находиться в таблице schoolyearsubjects.
3) Этот article может помочь решить, какой тип ключа использовать.