Новая структура данных

Как я и обещал, теперь у нас будет более сложная структура данных. Некоторое время обдумывая, что можно предложит вашему вниманию, я решил остановиться на следующей идее – мы рассмотрим систему для работы приемной комиссии.
По идее у нас будет список абитуриентов, которые поступают на определенную специальность. Для каждой специальности существует определенный список предметов, по которым абитуриент сдает экзамены. Само собой, что оценки за сдачу предмета сохраняются.
Конечно же возникает сразу соблазн расширить нашу систему еще больше – например, ввести проходной балл на каждую специальность, ввести возможность изменять список сдаваемых предметов для специальности во времени – каждый год список может быть новым. Ну и так далее. Но надо соблюсти меру – тем более, что у нас и так получится неплохая система, которая будет включать в себя достаточно распространенные отношения между сущностями. Так что нарисуем схему нашей базы данных:

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

Т.к. для одной специальности надо сдавать много предметов и одновременно один предмет может сдаваться для нескольких специальностей, то мы получаем достаточно сложную связь – многие ко многим. И такая связь реализуется с помощью дополнительной таблицы, в которой прописываются связи между предметами и специальностями. Думаю, что разобраться здесь не очень сложно.
Как видим, несмотря на то, что у нас не так уж много таблиц, связей у нас предостаточно. Причем есть разные связи – и многие ко многим, и один к одному.
Ниже приведен SQL-скрипт, который можно запустить на MySQL для генерации всех наших таблиц. Скопируйте и запишите в файл Applicant.sql. Причем со всеми необходимыми индексами и связями. Для запуска можно набрать такую команду:

mysql –u root –p < Applicant.sql

Ну и сам скрипт. Как нормальный разработчик, я нарисовал всю схему при помощи пакета, а потом получил SQL. Советую пользоваться такими штуками – их достаточно много. Мне лично нравится ERStudio. Хотя и PowerDesigner тоже неплохо.

Applicant.sql

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. Начало пути.