Вы находитесь на странице: 1из 19

Федеральное государственное автономное образовательное учреждение

высшего образования
"Национальный исследовательский университет
"Высшая школа экономики"

Московский институт электроники и математики им. А.Н Тихонова

Департамент компьютерной инженерии

ПРОЕКТИРОВАНИЕ БАЗЫ ДАННЫХ АВТОПРОКАТА

Выполнили:
Гордеева Карина БИВ205
Жданова Наталья БИВ205

Москва
2022
1. Инфологическое проектирование
1.1. Анализ предметной области
–2–
База данных создаётся для обслуживания клиентов пункта аренды
автомобилей. БД должна содержать данные о клиентах, сотрудниках,
имеющихся автомобилей и историях поездок всех клиентов.
Цель создания БД – упрощение контроля над выданными автомобилями и
ведение статистики.
В соответствии с предметной областью система строится с учётом
следующих особенностей:
– Каждый сотрудник может создавать несколько записей в истории
поездок, каждая запись создана только одним сотрудником.
– Каждый клиент может быть вписан в несколько записей в истории
поездок, каждая запись содержит информацию только об одном клиенте.
– Каждая машина может относиться к нескольким записям в истории
поездок, каждая запись содержит информацию только об одной машине.
– Каждые машина, сотрудник и клиент однозначно определяются своим
номером.
– Каждая машина не может одновременно бронироваться несколькими
клиентами.
– Каждый клиент не может одновременно бронировать несколько машин.
Создадим ER-модель нашей предметной области. Идентифицирующие
атрибуты выделяются полужирным шрифтом, многозначные – курсивом,
составные подчеркнем:
1) Машина. Атрибуты: номер машины, модель, VIN, стоимость
проката, количество топлива, коробка передач.
2) Сотрудник. Атрибуты: фамилия, имя, отчество, номер телефона, дата
рождения, пол, дата вступления в должность, должность.
3) Клиент. Атрибуты: фамилия, имя, отчество, номер телефона, дата
рождения, пол, серия и номер водительского удостоверения, дата
выдачи водительского удостоверения.
4) История поездок. Атрибуты: дата начала аренды, дата завершения
аренды.
5) Штраф. Атрибуты: стоимость, причина, дата фиксации, дата
вынесения постановления, дата оплаты, сумма оплаты, УИН.

Исходя из выявленных сущностей, построим ER–диаграмму (Рис. 1).


Пометки у линий отражают кардинальность связи: 1:1, 1:N и N:M.
–3–

Рис. 1. ER-диаграмма ПрО «Компания по прокату автомобилей»


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

1.2. Анализ информационных задач и круга пользователей системы


Определим группы пользователей, их основные задачи и запросы к БД:
1. Клиент – регистрируется через администратора, смотрит информацию про
машины, общается с сотрудником для брони машины, смотрит историю
своих поездок и полученные штрафы:
● просмотр свободных машин (для этого доступ к таблице машина и ко
всем зависящим от неё);
● просмотр истории своих поездок (для этого доступ к истории поездок и
ко всем зависящим от неё).
2. Сотрудник – общается с клиентом, проверяет данные брони, заполняет
новую поездку, в дальнейшем консультирует всех клиентов по поводу их
прошлых поездок:
● просмотр занятых и свободных машин (для этого доступ к таблице
машина и ко всем зависящим от неё);
● просмотр информации обо всех поездках (для этого доступ к истории
поездок и ко всем зависящим от неё);
● составление и редактирование своих поездок (для этого доступ к
добавлению и редактированию своих записей в истории поездок).
3. Администратор салона – заполняет и меняет информацию о машинах и
клиентах, актуализирует информацию об уплате штрафов:
● заполнение, актуализация и удаление данных о машинах и клиентах (для
этого доступ к заполнению, редактированию и удалению записей в
таблицах машина и клиент, а также ко всем, зависящим от них таблицам);
–4–
● заполнение и актуализация данных о штрафах (для этого доступ к
добавлению и изменению записей в таблице штрафы).
4. Владелец салона – фиксирует имеющиеся должности, нанимает
сотрудников в салон, контролирует работу сотрудников, фиксирует
штрафы:
● заполнение, редактирование и удаление информации о сотрудниках,
должностях и штрафах (для этого доступ ко всему в таблице
сотрудников, должностей и штрафов);
● просмотр всей базы (для этого доступ на просмотр всех таблиц).
2. Логическое проектирование реляционной БД

2.1. Преобразование ER–диаграммы в схему базы данных


На основании ER-диаграммы (рис. 1) построим схему реляционной БД.

Рис. 2. Схема РБД

2.2. Составление реляционных отношений


Отношения приведены в Таблицах 1-5. Для каждого отношения указаны
атрибуты с их внутренним названием, типом и длиной. Типы данных
обозначаются так: N – числовой, C – символьный тип фиксированной длины, V
– символьный тип переменной длины, D – дата, T – время, I – интервал, B –
логический тип, S – автоинкрементирующееся числовое значение.

Потенциальным ключом отношения МАШИНА являются атрибуты


Номер машины и VIN код, так как первый из них короче, он и будет первичным
ключом.
–5–
Таблица 1. Схема отношения МАШИНА (car)
Содержание поля Имя поля Тип, длина Примечания
Номер машины cnumber C(9) Первичный ключ
Модель машины model V(30) Обязательное поле
Обязательное поле,
VIN код vin C(17) уникальный
Стоимость аренды за сутки rental_rate N(6) Обязательное поле, >0
Количество топлива в Обязательное поле, >=0,
процентах fuel_quantity N(3) <=100
Обязательное поле, m или
Тип коробки передач gearbox C(1) a

Потенциальными ключом отношения СОТРУДНИК является поле Номер


телефона, но номер телефона у человека может измениться, поэтому введём
суррогатный первичный ключ.
Таблица 2. Схема отношения СОТРУДНИК (employee)
Содержание поля Имя поля Тип, длина Примечания
Уникальный идентификатор id S Первичный ключ
Обязательное
Номер телефона phone N(11) уникальное поле
Фамилия surname V(20) Обязательное поле
Имя name V(20) Обязательное поле
Необязательное
Отчество patronymic V(20) поле
Обязательное поле,
<сегодняшняя
Дата рождения b_date D дата - 18 лет
Обязательное поле,
Пол gender C(1) “м” или “ж”
Обязательное поле,
≤сегодняшняя
Дата вступления в должность entry_date D дата
Должность job_title V(30) Обязательное поле
–6–
В отношении КЛИЕНТ два потенциальных ключа: Номер телефона и
Серия и номер водительского удостоверения, но каждый из этих атрибутов
может меняться у человека, поэтому введём суррогатный первичный ключ.
Таблица 3. Схема отношения КЛИЕНТ (client)
Содержание поля Имя поля Тип, длина Примечания
Уникальный идентификатор id S Первичный ключ
Обязательное
Номер телефона phone N(11) уникальное поле
Фамилия surname V(20) Обязательное поле
Имя name V(20) Обязательное поле
Отчество patronymic V(20) Необязательное поле
Обязательное поле,
<сегодняшняя дата -
Дата рождения b_date D 18 лет
Обязательное поле,
Пол gender C(1) “м” или “ж”
Серия и номер
водительского Обязательное
удостоверения license C(11) уникальное поле
Обязательное поле,
Дата выдачи водительского ≤сегодняшняя
удостоверения dl_date D дата

Потенциальных ключей отношения ИСТОРИЯ ПОЕЗДОК нет, поэтому


введём служебное поле для суррогатного первичного ключа – Уникальный
идентификатор.
Таблица 4. Схема отношения ИСТОРИЯ ПОЕЗДОК (history)
Содержание поля Имя поля Тип, длина Примечания
Первичный ключ
Уникальный идентификатор id S
Обязательное поле,
Дата начала аренды start_date D <end_date
Дата завершения аренды end_date D >start_date
Обязательное поле,
внешний ключ (к
Идентификатор сотрудника e_id INT employee)
–7–
Обязательное поле,
Идентификатор клиента cl_id INT внешний ключ (к client)
Обязательное поле,
Номер машины c_cnumber C(9) внешний ключ (к car)
Потенциальных ключей отношения ШТРАФ нет, поэтому введём
служебное поле для суррогатного первичного ключа – Уникальный
идентификатор.
Таблица 5. Схема отношения ШТРАФ (fine)
Содержание поля Имя поля Тип, длина Примечания
Первичный ключ
Уникальный идентификатор id S
Стоимость cost N(6) Обязательное поле, >0
Причина reason V(128) Обязательное поле
Обязательное поле,
внешний ключ (к
Идентификатор поездки h_id INT history)
Обязательное поле,
Дата фиксации record_date D <=сегодняшняя дата
Обязательное поле,
Дата вынесения judgement_da <=сегодняшняя дата,
постановления te D >=дата фиксации
<=сегодняшняя дата,
>=дата вынесения
Дата оплаты cost_date D постановления

Сумма оплаты total_cost N(6) >0

УИН uin C(25)

2.3. Нормализация полученных отношений (до 4НФ)


МАШИНА. В таблице МАШИНА присутствуют атрибуты, которые
зависят не от первичного ключа: стоимость зависит от пары атрибутов – модель
машины и тип коробки передач, поэтому вынесем стоимость, модель и тип
коробки в отдельное отношение и введём суррогатный первичный ключ для
идентификации (к тому же будет добавлено ограничение целостности
UNIQUE(brand, model), чтобы каждая пара значений марка-модель была
уникальной). Составной атрибут модель разделим на несколько простых: марка
и модель, после чего вынесем в отдельную таблицу. После нормализации
–8–
отношение МАШИНА превратится в три отношения, которые приведены в
Таблицах 6-9.
Таблица 6. Схема отношения МАРКА МАШИНЫ (car_brand) – справочная
Содержание поля Имя поля Тип, Примечания
длина
Название name V(30) Первичный ключ

Таблица 7. Схема отношения МОДЕЛЬ МАШИНЫ (car_model) – справочная


Содержание поля Имя поля Тип, Примечания
длина
Модель model V(30) Первичный ключ
Марка brand V(30) Обязательное поле,
внешний ключ (к car_brand)

Таблица 8. Схема отношения ИНФОРМАЦИЯ О МАШИНЕ (car_info)


Содержание поля Имя поля Тип, длина Примечания

Уникальный идентификатор id S Первичный ключ


Обязательное поле,
внешний ключ (к
Модель машины model V(30) car_model)
Обязательное поле, “м”
Тип коробки передач gearbox C(1) или “а”
Стоимость rental_rate N(6) Обязательное поле, >0

Таблица 9. Схема отношения МАШИНА (car)


Содержание поля Имя поля Тип, длина Примечания
Номер машины cnumber C(9) Первичный ключ
Обязательное поле,
внешний ключ (к
Информация о машине ci_id S car_info)
Обязательное поле,
VIN код vin C(17) уникальный
Количество топлива в Обязательное поле, >=0,
процентах fuel_quantity N(3) <=100
–9–
СОТРУДНИК. В отношении СОТРУДНИК присутствует атрибут
должность, который соответствует справочной таблице, поэтому введем ее.
После нормализации отношение СОТРУДНИК превратится в два отношения,
которые приведены в Таблицах 10-11.
Таблица 10. Схема отношения ДОЛЖНОСТЬ (job_title)
Содержание поля Имя поля Тип, Примечания
длина
Название name V(30) Первичный ключ
Таблица 11. Схема отношения СОТРУДНИК (employee)
Содержание поля Имя поля Тип, длина Примечания
Уникальный идентификатор id S Первичный ключ
Обязательное
Номер телефона phone N(11) уникальное поле
Фамилия surname V(20) Обязательное поле
Имя name V(20) Обязательное поле
Отчество patronymic V(20)
Обязательное поле,
<сегодняшняя дата -
Дата рождения b_date D 18 лет
Обязательное поле,
Пол gender C(1) “м” или “ж”
Обязательное
поле,
≤сегодняшняя
Дата вступления в должность entry_date D дата
Обязательное поле,
внешний ключ (к
Должность jt_name V(30) job_title)

КЛИЕНТ. Отношение КЛИЕНТ уже соответствует 4НФ, поэтому


оставим его в исходном виде (Таблица 3).
ИСТОРИЯ ПОЕЗДОК. Отношение ИСТОРИЯ ПОЕЗДОК уже
соответствует 4НФ, поэтому оставим его в исходном виде (Таблица 4).
ШТРАФ. Отношение ШТРАФ уже соответствует 4НФ, поэтому оставим
его в исходном виде (Таблица 5).
Схема базы данных после нормализации приведена на рис. 3.
– 10 –

Рис. 3. Окончательная схема РБД автопроката


В результате нормализации циклов не появилось.

2.4. Определение дополнительных ограничений целостности


● Номер машины должен соответствовать стандарту A000AA000, то есть в
таблице МАШИНА атрибут номер машины должен соответствовать
регулярному выражению “\A[ABEKMHOPCTYX]\d{3}[ABEKMHOPCTYX]
{2}\d{3}\Z”.
● VIN номер машины должен соответствовать стандарту VIN, то есть в
таблице МАШИНА атрибут VIN код должен соответствовать регулярному
выражению “\A[A-HJ-NPR-Z0-9]{13}\d{4}\Z”.
● Номер телефона должен быть записан в определённом шаблоне, то есть в
таблицах СОТРУДНИК и КЛИЕНТ атрибуты номер телефона должны
соответствовать регулярному выражению “\A7\d{10}\Z”.
● Серия и номер водительского удостоверения должны содержать только 4
цифры, пробел и еще 6 цифр, то есть в таблице КЛИЕНТ атрибут серия и
номер водительского удостоверения должен соответствовать регулярному
выражению “\A\d{4} \d{10}\Z”.
– 11 –
● УИН должен содержать только 25 цифр, то есть в таблице ШТРАФ атрибут
УИН должен соответствовать регулярному выражению “\A\d{25}\Z”.
Данные ограничения нельзя реализовать в схеме отношения, поэтому их
необходимо проверять через внешнее приложение или специальную процедуру
контроля данных – триггер.

2.5. Описание групп пользователей и прав доступа


Используя сокращения (таблица 13), опишем для каждой группы
пользователей права доступа к каждой таблице (таблица 14).
Таблица 11. Обозначения прав доступа
Обозначение Расшифровка
I (insert) добавление данных
S (select) чтение данных
U (update) модификация данных
D (delete) удаление данных

Таблица 12. Права доступа к таблицам для групп пользователей


Группы пользователей (роли)
Таблицы Клиент Сотрудн Администрат Владелец
ик ор салона салона
Марка машины S S SUID S
(car_brand)
Модель машины S S SUID S
(car_model)
Информация о машине S S SUID S
(car_info)
Машина (car) S S SUID S
Должность (job_title) S S SUID
Сотрудник (employee) S S SUID
Клиент (client) S* S SUID S
История поездок S* SU*I*D* S S
(history)
Штраф (fine) S* S SUI SUID
Прим.: * – только свои
Ограничение прав сотрудника и клиента на доступ только к своим
данным будет осуществлено через представления. Права назначает
администратор БД.
3. Реализация проекта базы данных
3.1. Создание таблиц

1. Отношение car_brand (марка машины) – справочная:


create table car_brand (
name varchar(30) primary key
– 12 –
);
2. Отношение car_model (модель машины) – справочная:
create table car_model (
id serial primary key,
brand varchar(30) references car_brand(name) not null,
model varchar(30) not null,
unique(brand, model)
);

3. Отношение car_info (информация о машине):


create table car_info (
id serial primary key,
model serial references car_model (id),
gearbox char(1) not null check (gearbox='м' or gearbox='a'),
rental_rate numeric(6) not null check (rental_rate>0)
);

4. Отношение car (машина):


create table car (
cnumber char(9) primary key,
ci_id serial not null references car_info(id),
vin char(17) unique not null,
fuel_quantity numeric(3) not null check (fuel_quantity>=0 and
fuel_quantity<=100)
);

5. Отношение job_title (должность) – справочная:


create table job_title (
name varchar(30) primary key
);

6. Отношение employee (сотрудник):


create table employee (
id serial primary key,
phone numeric(11) unique not null,
– 13 –
surname varchar(20) not null,
name varchar(20) not null,
patronymic varchar(20),
b_date date not null check (extract(years from
age(b_date))>=18),
gender char(1) not null check (gender='м' or gender='ж'),
entry_date date not null check (entry_date<=current_date),
jt_name varchar(30) not null references job_title(name)
);

7. Отношение client (клиент):


create table client (
id serial primary key,
phone numeric(11) unique not null,
surname varchar(20) not null,
name varchar(20) not null,
patronymic varchar(20),
b_date date not null check (b_date<(current_date-18)),
gender char(1) not null check (gender='м' or gender='ж'),
license char(11) unique not null,
dl_date date not null check (dl_date<=current_date)
);

8. Отношение history (история поездок):


create table history (
id serial primary key,
start_date date not null check (start_date<end_date),
end_date date check (end_date>start_date),
e_id serial not null references employee(id),
cl_id serial not null references client(id),
c_cnumber char(9) not null references car(cnumber)
);

9. Отношение fine (штраф):


create table fine (
id serial primary key,
– 14 –
cost numeric(6) not null check (cost>0),
reason varchar(128) not null,
h_id serial not null references history(id),
record_date date not null check (record_date<=current_date),
judgement_date date not null check
(judgement_date<=current_date and
judgement_date>=record_date),
cost_date date not null check (cost_date<=current_date and
cost_date>=judgement_date),
total_cost numeric(6) check (total_cost>0),
uin char(25)
);

Начальный состав данных для справочных таблиц:


1) Таблица МАРКА МАШИНЫ:
insert into car_brand values
('KIA'),
('BMW'),
('LADA'),
('MAZDA'),
('HONDA');

2) Таблица МОДЕЛЬ МАШИНЫ:


insert into car_model (brand, model) values
('KIA', 'Rio'),
('BMW', 'X6'),
('LADA', 'Granta'),
('MAZDA', 'CX-5'),
('KIA', 'Sportage'),
('KIA', 'K5'),
('KIA', 'Sorento'),
('BMW', 'X7'),
('BMW', 'X5'),
('BMW', 'I8'),
('LADA', 'Vesta'),
('LADA', 'XRAY'),
('LADA', 'Largus'),
('MAZDA', 'CX-9'),
('MAZDA', 'RX-5'),
('MAZDA', 'RX-7'),
('MAZDA', 'RX-8'),
('HONDA', 'CR-V'),
('HONDA', 'Civic'),
('HONDA', 'Accord');

3) Таблица ДОЛЖНОСТЬ:
– 15 –
insert into job_title values
('HR'),
('Менеджер по продажам'),
('Администратор данных'),
('Владелец'),
('Региональный представитель'),
('Консультант'),
('Автомеханик'),
('Старший консультант');

3.2. Создание представлений (готовых запросов)


Приведём примеры нескольких готовых запросов (представлений):
1. Вся информация про машину (full_car):
create or replace view full_car as (
select
c.cnumber,
t.model,
t.gearbox,
t.rental_rate,
c.vin,
c.fuel_quantity
from car c
join (
select
ci.id,
cm.brand || ' ' || cm.model as model,
ci.gearbox,
ci.rental_rate
from car_info ci
join car_model cm on ci.model=cm.id
) t on c.ci_id=t.id
);

2. Список занятых машин (occupied_car):


create or replace view occupied_car as (
select
*
from full_car
where cnumber in (
select
c_cnumber
from history
where end_date is null
)
– 16 –
);

3. Список свободных машин сейчас (free_car):


create or replace view free_car as (
select
*
from full_car
where cnumber not in (
select
cnumber
from occupied_car
)
);

4. Список поездок (ride_info):


create or replace view ride_info as (
select
t.*,
count(*) as fine_number
from fine f join (
select
h.id,
h.start_date,
h.end_date,
e.surname || ' ' || e.name || ' ' ||
e.patronymic as e_snp,
e.jt_name,
e.phone as e_phone,
cl.surname || ' ' || cl.name || ' ' ||
cl.patronymic as cl_snp,
cl.phone as cl_phone,
fc.cnumber
from history h
join employee e on h.e_id=e.id
join client cl on h.cl_id=cl.id
join full_car fc on h.c_cnumber=fc.cnumber
) t on t.id=f.h_id
group by
t.id,
t.start_date,
t.end_date,
t.e_snp,
t.jt_name,
t.e_phone,
t.cl_snp,
t.cl_phone,
t.cnumber
– 17 –
);

5. Список клиентов без штрафов (nofine_client):


create or replace view nofine_client as (
select
*
from client
where id in (
select cl_id
from history
where id not in (
select h_id from fine
)
)
);

6. Сотрудник месяца (best_empl):


create or replace view best_empl as (
select
e.*,
count(h.*) as ride_number
from history h
join employee e on e.id=h.e_id
group by
e.id,
e.phone,
e.surname,
e.name,
e.patronymic,
e.b_date,
e.gender,
e.entry_date,
e.jt_name
order by ride_number desc
limit 1
);

7. Отчётность штата сотрудников (staff_report):


create or replace view staff_report as (
select
jt_name,
count(jt_name) as quantity
from employee
group by jt_name
);
– 18 –
Для работы с этими представлениями соответствующим пользователям
нужно определить права доступа к представлениям (Таблица 13).
Таблица 13. Права доступа к представлениям
Представления Группы пользователей (роли)
Клиент Сотрудн Администрат Владелец
ик ор салона салона
Список свободных машин S S S
сейчас (free_car)
Список поездок (ride_info) S* S S
Список занятых машин S S
(occupied_car)
Список клиентов без S
штрафов (nofine_client)
Сотрудник месяца S
(best_empl)
Отчётность штата S
сотрудников (staff_report)
Вся информация про S S S
машину (full_car)
Прим.: * – только свои

3.3. Назначение прав доступа


Права доступа пользователей предоставляются с помощью команды
GRANT. Рассмотрим назначение прав доступа клиентам (роль - customer),
сотрудник (роль - worker), администратору салона (роль - admin) и владельцу
салона (роль - holder):
Таблицы
grant select on car_brand to customer, worker, holder, admin;
grant select, update, insert, delete on car_brand to admin;
grant select on car_model to customer, worker, holder, admin;
grant select, update, insert, delete on car_model to admin;
grant select on car_info to customer, worker, holder;
grant select, update, insert, delete on car_info to admin;
grant select on car to customer, worker, holder;
grant select, update, insert, delete on car to admin;
grant select on job_title to customer, worker;
grant select, update, insert, delete on job_title to holder;
grant select on employee to customer, worker;
grant select, update, insert, delete on employee to holder;
grant select on client to customer, worker, holder;
grant select, update, insert, delete on client to admin;
grant select on history to customer, admin, holder;
– 19 –
grant select, update, insert, delete on history to worker;
grant select on fine to customer, worker;
grant select, update, insert on fine to admin;
grant select, update, insert, delete on fine to holder;

Представления
grant select on free_car to customer, worker, admin;
grant select on ride_info to customer, worker, admin;
grant select on occupied_car to worker, admin;
grant select on nofine_client to admin;
grant select on best_empl to holder;
grant select on staff_report to holder;
grant select on full_car to customer, worker, admin;

3.4. Создание индексов


Система автоматически создаёт индексы по первичным ключам и
уникальным полям.
Анализ готовых запросов показывает, что для повышения эффективности
работы с данными необходимо создать индексы для внешних ключей:
create index ind_ci_model on car_info(model);
create index ind_c_ci_id on car(ci_id);
create index ind_e_jt_name on employee(jt_name);
create index ind_h_e_id on history(e_id);
create index ind_h_cl_id on history(cl_id);
create index ind_h_c_cnumber on history(c_cnumber);
create index ind_f_h_id on fine(h_id);
create index ind_cm_brand on car_model(brand);

3.5. Разработка стратегии резервного копирования


Интенсивность обновления разработанной базы данных очень высокая
(наибольшая нагрузка приходится утром и вечером, в часы пик). Для
обеспечения сохранности необходимо проводить полное резервное
копирование БД раз в час.

Вам также может понравиться