Как я и обещал, теперь у нас будет более сложная структура данных. Некоторое время обдумывая, что можно предложит вашему вниманию, я решил остановиться на следующей идее – мы рассмотрим систему для работы приемной комиссии.
По идее у нас будет список абитуриентов, которые поступают на определенную специальность. Для каждой специальности существует определенный список предметов, по которым абитуриент сдает экзамены. Само собой, что оценки за сдачу предмета сохраняются.
Конечно же возникает сразу соблазн расширить нашу систему еще больше – например, ввести проходной балл на каждую специальность, ввести возможность изменять список сдаваемых предметов для специальности во времени – каждый год список может быть новым. Ну и так далее. Но надо соблюсти меру – тем более, что у нас и так получится неплохая система, которая будет включать в себя достаточно распространенные отношения между сущностями. Так что нарисуем схему нашей базы данных:
Т.к. теперь наше приложение будет более солидным, то давайте внимательно рассмотрим таблицы, поля и связи между таблицами.
- APPLICANT – таблица со списком абитуриентов
- APPLICANT_ID – уникальный идентификатор, который будет автоматически создаваться базой данных.
- PROFESSION_ID – специальность, на которую собирается поступать абитуриент. Здесь важно обратить внимание, что у нас появилась связь с таблицей PROFESSION. Каждый абитуриент поступает на определенную специальность. Но надо также отметить, что много студентов могут поступать на одну и ту же специальность. (Можно видеть, что будет сгенерирован Foreign Key – (FK)).
- LAST_NAME, FIRST_NAME, MIDDLE_NAME — соответственно фамилия, имя, отчество.
- ENTRANCE_YEAR – год поступления абитуриента.
- PROFESSION – таблица специальностей
- PROFESSION_ID — уникальный идентификатор, который будет автоматически создаваться базой данных
- PROFESSION_NAME – название специальности
- SUBJECT — список предметов, который будут сдавать абитуриенты
- SUBJECT_ID — уникальный идентификатор, который будет автоматически создаваться базой данных.
- SUBJECT_NAME – наименование предмета
- APPLICANT_RESULT — таблица с результатами сдачи экзаменов
- APPLICANT_RESULT_ID — уникальный идентификатор, который будет автоматически создаваться базой данных.
- APPLICANT_ID – ссылка на абитуриента. Здесь у нас тоже есть связь – для одного студента может быть много результатов. (Можно видеть, что будет сгенерирован Foreign Key – (FK)).
- SUBJECT_ID – ссылка на предмет, который сдавал абитуриент. Здесь мы можем вести ограничение – один абитуриент не может сдавать один и тот же предмет дважды. (Можно видеть, что будет сгенерирован Foreign Key – (FK)).
- MARK – оценка за экзамен
- SPECIALITY_SUBJECT — таблица связи между предметами и специальностями
- SPECIALITY_SUBJECT_ID — уникальный идентификатор, который будет автоматически создаваться базой данных.
- PROFESSION_ID – ссылка на специальность. (Можно видеть, что будет сгенерирован Foreign Key – (FK)).
- SUBJECT_ID – ссылка на предмет. (Можно видеть, что будет сгенерирован Foreign Key – (FK)).
Т.к. для одной специальности надо сдавать много предметов и одновременно один предмет может сдаваться для нескольких специальностей, то мы получаем достаточно сложную связь – многие ко многим. И такая связь реализуется с помощью дополнительной таблицы, в которой прописываются связи между предметами и специальностями. Думаю, что разобраться здесь не очень сложно.
Как видим, несмотря на то, что у нас не так уж много таблиц, связей у нас предостаточно. Причем есть разные связи – и многие ко многим, и один к одному.
Ниже приведен SQL-скрипт, который можно запустить на MySQL для генерации всех наших таблиц. Скопируйте и запишите в файлApplicant.sql. Причем со всеми необходимыми индексами и связями. Для запуска можно набрать такую команду:
mysql –u root –p < Applicant.sql
Ну и сам скрипт. Как нормальный разработчик, я нарисовал всю схему при помощи пакета, а потом получил SQL. Советую пользоваться такими штуками – их достаточно много. Мне лично нравится ERStudio. Хотя и PowerDesigner тоже неплохо.
Applicant.sql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
DROP DATABASE IF EXISTS db_applicant; CREATE DATABASE db_applicant DEFAULT CHARACTER SET 'utf8' DEFAULT COLLATE 'utf8_unicode_ci'; USE db_applicant; -- -- TABLE: APPLICANT -- CREATE TABLE APPLICANT( APPLICANT_ID INT NOT NULL AUTO_INCREMENT, PROFESSION_ID INT NOT NULL, LAST_NAME VARCHAR(30) NOT NULL, FIRST_NAME VARCHAR(30) NOT NULL, MIDDLE_NAME VARCHAR(30) NOT NULL, ENTRANCE_YEAR INT NOT NULL, PRIMARY KEY (APPLICANT_ID) )ENGINE=INNODB; -- -- TABLE: APPLICANT_RESULT -- CREATE TABLE APPLICANT_RESULT( APPLICANT_RESULT_ID INT NOT NULL AUTO_INCREMENT, APPLICANT_ID INT NOT NULL, SUBJECT_ID INT NOT NULL, MARK INT, PRIMARY KEY (APPLICANT_RESULT_ID) )ENGINE=INNODB; -- -- TABLE: PROFESSION -- CREATE TABLE PROFESSION( PROFESSION_ID INT NOT NULL AUTO_INCREMENT, PROFESSION_NAME VARCHAR(50) NOT NULL, PRIMARY KEY (PROFESSION_ID) )ENGINE=INNODB; -- -- TABLE: SPECIALITY_SUBJECT -- CREATE TABLE SPECIALITY_SUBJECT( SP_SB_ID INT NOT NULL AUTO_INCREMENT, PROFESSION_ID INT NOT NULL, SUBJECT_ID INT NOT NULL, PRIMARY KEY (SP_SB_ID) )ENGINE=INNODB; -- -- TABLE: SUBJECT -- CREATE TABLE SUBJECT( SUBJECT_ID INT NOT NULL AUTO_INCREMENT, SUBJECT_NAME VARCHAR(50) NOT NULL, PRIMARY KEY (SUBJECT_ID) )ENGINE=INNODB; -- -- INDEX: Ref22 -- CREATE INDEX Ref22 ON APPLICANT(PROFESSION_ID); -- -- INDEX: Ref33 -- CREATE INDEX Ref33 ON APPLICANT_RESULT(SUBJECT_ID); -- -- INDEX: Ref14 -- CREATE INDEX Ref14 ON APPLICANT_RESULT(APPLICANT_ID); -- -- INDEX: Ref25 -- CREATE INDEX Ref25 ON SPECIALITY_SUBJECT(PROFESSION_ID); -- -- INDEX: Ref36 -- CREATE INDEX Ref36 ON SPECIALITY_SUBJECT(SUBJECT_ID); -- -- TABLE: APPLICANT -- ALTER TABLE APPLICANT ADD CONSTRAINT RefPROFESSION2 FOREIGN KEY (PROFESSION_ID) REFERENCES PROFESSION(PROFESSION_ID); -- -- TABLE: APPLICANT_RESULT -- ALTER TABLE APPLICANT_RESULT ADD CONSTRAINT RefSUBJECT3 FOREIGN KEY (SUBJECT_ID) REFERENCES SUBJECT(SUBJECT_ID); ALTER TABLE APPLICANT_RESULT ADD CONSTRAINT RefAPPLICANT4 FOREIGN KEY (APPLICANT_ID) REFERENCES APPLICANT(APPLICANT_ID); -- -- TABLE: SPECIALITY_SUBJECT -- ALTER TABLE SPECIALITY_SUBJECT ADD CONSTRAINT RefPROFESSION5 FOREIGN KEY (PROFESSION_ID) REFERENCES PROFESSION(PROFESSION_ID); ALTER TABLE SPECIALITY_SUBJECT ADD CONSTRAINT RefSUBJECT6 FOREIGN KEY (SUBJECT_ID) REFERENCES SUBJECT(SUBJECT_ID); |
Ну что же – база данных у нас есть, и мы готовы переходить к следующему шагу – созданию классов на уровне Persistence Layer. Здесь мы познакомимся с наиболее популярным пакетом – Hibernate. Итак, вперед — Часть 16 — Hibernate. Начало пути.