ВВЕДЕНИЕ
В результате проектирования информационной системы ГИБДД должны быть получены база данных и прикладная программа, обеспечивающая интерфейс между пользователем и базой данных. В процессе выполнения работы необходимо решить следующие задачи:
- Спроектировать схему данных
- Согласно полученной схеме создать необходимые таблицы, предварительно определив тип данных каждого их поля
- Реализовать указанные в задании запросы
- Создать представления, имеющие смысл для данной предметной области
- Создать пользователей и роли для управления доступом к различным объектам базы данных
- Создать триггеры и ограничения целостности для поддержания целостности данных в базе данных
ПРОЕКТИРОВАНИЕ ИНФОРМАЦИОННОЙ СИСТЕМЫ ГИБДД
Проектирование схемы данных
Полученная схема данных представлена на рисунке 2.1:
Рисунок 1.1 Схема данных |
Рассмотрим полученные таблицы:
Таблица | Описание |
PTS | Общие характеристики, которые присущи каждому виду транспорта |
PTS_type | Справочник типов транспортных средств |
Charasteristics | Перечень характеристик с их числовым, либо строковым значением |
PTS-Characteristics | Смежная таблица, для того, чтобы обеспечить связь “многие ко многим” между PTS и Characteristics. |
TO | Содержит всю информацию о прохождении техосмотра, включая период его прохождения |
Numbers | Хранит перечень свободных и занятых номеров |
Serial | Справочник серий номеров ТС |
Regions | Справочник регионов номеров ТС |
Streers | Справочник улиц |
PTS_users | Смежная таблица, для того, чтобы обеспечить связь “многие ко многим” между PTS и Users |
Users | содержит всю информацию о владельце, включая также то, является ли он юридическим лицом. |
Organisations | Содержит информацию об организациях |
Stealing | Содержит информацию о автомобилях, находившимся в розыске |
Reasons | Справочник причин розыска |
DTP_Type | Справочник типов ДТП |
Reason_DTP | Справочник причин ДТП |
DTP | Содержит всю информацию о дтп |
Number_DTP | Смежная таблица, для того, чтобы обеспечить связь “многие ко многим” между PTS и DTP. |
Таблица 1.1 Описание таблиц |
Рассмотрим каждую таблицу:
PTS:
· ID - Идентификатор
· SignalingID – Идентификатор сигнализации (может быть NULL)
· Type – Идентификатор типа ТС
· NumberID – Идентификатор номера ТС
· Firm – фирма изготовитель
· Model – модель ТС
· Year – год производства ТС
· Color – цвет
· Engine_number – номер двигателя (может принимать NULL для ТС без двигателя)
· Chassis_number – номер шасси
· Stand_number – номер кузова
Рисунок 1.2 типы данных PTS |
PTS_Types:
· ID – Идентификатор
· Name – Тип ТС
Рисунок 1.3 типы данных PTS_Types |
Charasteristics:
· ID – Идентификатор
· Name – название характеристики
· Str – строковое значение характеристики
· Chisl – числовое значение характеристики
Рисунок 1.4 типы данных Charasteristics |
PTS-Characteristics:
· PTSID – Идентификатор ТС
· CharacteristicID – Идентификатор характеристики
Рисунок 1.5 типы данных PTS - Charasteristics |
TO:
· ID – Идентификатор
· Date – дата прохождения ТО
· PTS_ID – Идентификатор ТС
· Passed – информация о своевременном прохождении ТО
· Cost - стоимость прохождения
· Period – период прохождения ТО
Рисунок 1.6 типы данных TO |
Numbers:
· Avto_type – Идентификатор типа ТС
· Number – номер ТС
· ID – Идентификатор
· Date – Дата выдачи номера
· SeriallD – Идентификатор серии номера ТС
· RegionID – Идентификатор региона номера ТС
Рисунок 1.7 типы данных Charasteristics |
Serial:
· ID – Идентификатор
· Name – серия номера ТС
Рисунок 1.8 типы данных Serial |
Regions:
· ID – Идентификатор
· Name – регион номера ТС
Рисунок 1.9 типы данных Regions |
Streers:
· ID – Идентификатор
· Name – название улицы
Рисунок 1.10 типы данных Streets |
PTS_users:
· PTS_ID – Идентификатор ТС
· UserID – Идентификатор пользователя
Рисунок 1.11 типы данных PTS_users |
Users
· ID – Идентификатор
· First_name – имя
· Second_name – фамилия
· Father_name – отчество
· Birthday – день рождения
· Organisation – идентификатор организации(может принимать NULL если пользователь частное лицо)
Рисунок 1.11 типы данных Users |
Organisations:
· ID – Идентификатор
· Name – название организации
· StreetID – идентификатор улица расположения организации
· Manager – Директор организации
Рисунок 1.12 типы данных Organisations |
Stealing:
· ID – Идентификатор
· PTS_ID – идентификатор ТС
· ReasonID – идентификатор причины розыска ТС
· Date – дата начала розыска
· StreetID – идентификатор улицы
· Found – найдено ли ТС
Рисунок 1.13 типы данных Stealing |
Reasons
· ID – Идентификатор
· Name – причина розыска
Рисунок 1.14 типы данных Reasons |
DTP_Type:
· ID – Идентификатор
· Name – Тип ДТП
Рисунок 1.15 типы данных DTP_Type |
Reason_DTP:
· ID – Идентификатор
· Name – Причина ДТП
Рисунок 1.16 типы данных Reason_DTP |
DTP:
· ID – Идентификатор
· ReasonID – Идентификатор причины ДТП
· Date – Дата ДТП
· Type – Идентификатор типа ДТП
· Arial – комментарий к месту ДТП
· StreetID – Идентификатор улицы
Рисунок 1.17 типы данных DTP |
Number_DTP:
· PTSID – Идентификатор ТС
· DTP_ID – Идентификатор ДТП
· Leave – Информация о пострадавших
Рисунок 1.18 типы данных Number_DTP |
Создание запросов
Подготовим SQL-скрипт для создания хранимых процедур, которые будут выполнять запросы, описанные в техническом задании:
1. Получить перечень и общее число организаций, которым выделены номера либо с указанной серией, либо за указанный период.
SELECT Organisations.Name, Organisations.Arial, Organisations.Addres, Organisations.Manager
FROM Serial, Numbers, PTS, Users, Organisations, PTS_users
WHERE Serial.ID = Numbers.SerialID
and Numbers.ID = PTS.NumberID
and PTS.ID = PTS_users.PTS_ID
and PTS_users.UserID = Users.ID
and Users.Organisation = Organisations.ID
and Serial.Name = 'CTO'
SELECT COUNT (Organisations.Name) as [Общее число организаций]
FROM Serial, Numbers, PTS, Users, Organisations, PTS_users
WHERE Serial.ID = Numbers.SerialID
and Numbers.ID = PTS.NumberID
and PTS.ID = PTS_users.PTS_ID
and PTS_users.UserID = Users.ID
and Users.Organisation = Organisations.ID
and Serial.Name = 'CTO'
SELECT Organisations.Name, Organisations.Arial, Organisations.Addres, Organisations.Manager
FROM Serial, Numbers, PTS, Users, Organisations, PTS_users
WHERE Serial.ID = Numbers.SerialID
and Numbers.ID = PTS.NumberID
and PTS.ID = PTS_users.PTS_ID
and PTS_users.UserID = Users.ID
and Users.Organisation = Organisations.ID
and Numbers.[Date] BETWEEN '07.10.2007' AND '14.08.2013'
Результат выполнения запроса:
Рисунок 1.19 Пример выполнения запроса
2. Получить сведения о владельце автотранспортного средства по государственному номеру автомашины.
SELECT Users.Second_name, Users.First_name, Users.Father_name, Users.Birthdate
FROM Numbers, PTS, USERS, PTS_users
WHERE Numbers.ID = PTS.NumberID
and PTS.ID = PTS_users.PTS_ID
and PTS_users.UserID = Users.ID
and Users.Organisation is NULL
and Numbers.Number = '125'
SELECT Users.Second_name, Users.First_name, Users.Father_name, Users.Birthdate, Organisations.Name, Organisations.Addres, Organisations.Arial, Organisations.Manager
FROM Numbers, PTS, USERS, PTS_users, Organisations
WHERE Numbers.ID = PTS.NumberID
and PTS.ID = PTS_users.PTS_ID
and PTS_users.UserID = Users.ID
and Users.Organisation = Organisations.ID
and Numbers.Number = '323'
Результат выполнения запроса:
Рисунок 1.20 Пример выполнения запроса
3. Получить "досье" на автомобиль по государственному номеру - номера двигателя, кузова и шасси, участвовал ли в ДТП, прошел ли техосмотр.
SELECT PTS.Firm, PTS.Engine_number, PTS.Chassis_number, PTS.Stand_number, DTP.Data as [Дата аварии], [To].Passed as [Техосмотр]
FROM Numbers, PTS, Number_DTP, DTP, [To]
WHERE Numbers.ID = PTS.NumberID
and Number_DTP.PtsID = PTS.ID
and DTP.ID = Number_DTP.DTP_ID
and Numbers.ID = Pts.NumberID
and Numbers.Number = '72'
and [To].PTS_ID = PTS.ID
Результат выполнения запроса:
Рисунок 1.21 Пример выполнения запроса
4. Получить перечень и общее число владельцев машин, не прошедших вовремя техосмотр.
SELECT Users.Second_name, Users.First_name, Users.Father_name, Users.Birthdate
FROM [TO], PTS, Users, PTS_users
WHERE Users.ID = PTS_users.UserID
and PTS_users.PTS_ID = PTS.ID
and [TO].PTS_ID = PTS.ID
and [TO].Passed = 'false'
SELECT COUNT (Users.Second_name) as [Общее число владельцев]
FROM [TO], PTS, Users, PTS_users
WHERE Users.ID = PTS_users.UserID
and PTS_users.PTS_ID = PTS.ID
and [TO].PTS_ID = PTS.ID
and [TO].Passed = 'false'
Результат выполнения запроса:
Рисунок 1.22 Пример выполнения запроса
5. Получить статистику по любому типу ДТП за указанный период.
SELECT COUNT(DTP.ID) as [Количество ДТП], COUNT(Number_DTP.PtsID)
as [Количество участников], COUNT(Number_DTP.Leave) as[Количество пострадавших]
FROM DTP, DTP_Types, Number_DTP
WHERE DTP_Types.Name = 'Наезд на велосипедиста'
and DTP.[Type] = DTP_Types.ID
and DTP.ID = Number_DTP.DTP_ID
and DTP.Data BETWEEN '06.07.2013' and '02.10.2015'
Результат выполнения запроса:
Рисунок 1.23 Пример выполнения запроса
6. Получить результаты анализа ДТП: самые опасные места в городе, самая частая причина ДТП
SELECT TOP 5 ДТП.Name, Количество
FROM (SELECT count(DTP.ReasonID) AS Количество, Reason_DTP.Name
FROM Reason_DTP, DTP
WHERE Reason_DTP.ID = DTP.ReasonID
GROUP BY Reason_DTP.Name) AS ДТП
ORDER BY Количество desc
SELECT TOP 5 ДТП.Name, Количество
FROM (SELECT count(DTP.StreetID) AS Количество, Streets.Name
FROM Streets, DTP
WHERE Streets.ID = DTP.StreetID
GROUP BY Streets.Name) AS ДТП
ORDER BY Количество desc
Результат выполнения запроса:
Рисунок 1.24 Пример выполнения запроса
7. Получить данные о количестве ДТП, совершаемых водителями в нетрезвом виде и доля таких происшествий в общем количестве ДТП.
SELECT B_DTP.[Количество проишествий], A_DTP.[Количество проишествий по причине], A_DTP.[Количество проишествий по причине]*100/B_DTP.[Количество проишествий] as [Доля проишествий(%)]
FROM (SELECT COUNT(DTP.ID) as [Количество проишествий по причине] FROM DTP, Reason_DTP WHERE DTP.ReasonID = Reason_DTP.ID and Reason_DTP.ID = '2') AS A_DTP,
(SELECT COUNT(DTP.ID) as [Количество проишествий] FROM DTP, Reason_DTP WHERE DTP.ReasonID = Reason_DTP.ID) AS B_DTP
Результат выполнения запроса:
Рисунок 1.25 Пример выполнения запроса
8. Получить список машин, отданных в розыск, будь то скрывшиеся с места ДТП или угнанные.
SELECT PTS_type.name as [Type],PTS.Firm, PTS.Color, Numbers.Number, Serial.Name as [Serial], Regions.Name as [Region], PTS.Engine_number, PTS.Engine_number, PTS.Stand_number, Stealing.[Date] as [Stealing date], Reasosns.Name as [Причина]
FROM Stealing, PTS, Numbers, Regions, PTS_type, Serial, Reasosns
WHERE Stealing.PTS_ID = PTS.ID
and PTS.NumberID = Numbers.ID
and Serial.ID = Numbers.SerialID
and Regions.ID = Numbers.RegionID
and PTS_type.id = PTS.[Type]
and Stealing.ReasonID = Reasosns.ID
and Stealing.Found = 'false'
Результат выполнения запроса:
Рисунок 1.26 Пример выполнения запроса
9. Получить данные об эффективности розыскной работы: количество найденных машин в процентном отношении.
SELECT steel_table.steel as [Найденные автомобили], nsteel_table.nsteel as [Общее количество], steel_table.steel*100/nsteel_table.nsteel as[Процент найденных]
FROM (SELECT COUNT(Stealing.ID) as steel FROM Stealing WHERE Stealing.Found = 'true') as steel_table,
(SELECT COUNT(Stealing.ID) as nsteel FROM Stealing) as nsteel_table
Результат выполнения запроса:
Рисунок 1.27 Пример выполнения запроса
10. Получить перечень и общее число угонов за указанный период.
SELECT PTS.Firm, PTS.Color, Numbers.Number, Serial.Name, Stealing.[Date], Stealing.Citi, Stealing.Street
FROM Stealing, PTS, Numbers, Serial, Reasosns
WHERE Serial.ID = Numbers.SerialID
and Numbers.ID = PTS.NumberID
and PTS.ID = Stealing.PTS_ID
and Reasosns.ID = '2'
and Stealing.[Date] BETWEEN '03.09.2013'AND'21.12.2015'
Результат выполнения запроса:
Рисунок 2.28 Пример выполнения запроса
11. Получить статистику по угонам: самые угоняемые марки машин, самые надежные сигнализации и т.п.
SELECT TOP 5 Угон.Firm, Количество
FROM (SELECT COUNT(PTS.ID) AS количество, PTS.Firm
FROM PTS, Stealing
WHERE Stealing.PTS_ID = PTS.ID
and Stealing.ReasonID = '2'
GROUP BY PTS.Firm) as Угон
ORDER BY Количество desc
SELECT TOP 5 Сигнализация.Name, Количество
FROM (SELECT COUNT(PTS.ID) AS количество, Signalling.Name
FROM PTS, Stealing, Signalling
WHERE Stealing.PTS_ID = PTS.ID
and Signalling.ID = PTS.SignallingID
and Stealing.ReasonID = '2'
GROUP BY Signalling.Name) as Сигнализация
ORDER BY Количество desc
Результат выполнения запроса:
Рисунок 1.29 Пример выполнения запроса
Создание триггеров
Подготовим SQL-скрипты для создания следующих триггеров:
1. Триггер для проверки корректного ввода даты выдачи номера тс:
CREATE TRIGGER Проверка_даты_выдачи_номера
ON Numbers
AFTER INSERT, UPDATE
AS
IF EXISTS (
SELECT *
FROM Numbers, Users
WHERE Users.Birthdate > Numbers.[Date])
BEGIN
ROLLBACK
PRINT 'Неверная дата выдачи номера'
END
Проверка триггера:
UPDATE Numbers
SET Date = '1970-06-03'
WHERE Date = '2006-06-03'
Результат:
2. Триггер для проверки корректного ввода даты аварии:
CREATE TRIGGER Проверка_даты_аварии
ON DTP
AFTER INSERT, UPDATE
AS
IF EXISTS (
SELECT *
FROM DTP, PTS
WHERE PTS.[Year] > DTP.Data)
BEGIN
ROLLBACK
PRINT 'Неверная дата аварии'
END
Проверка триггера:
UPDATE DTP
SET Data = '2015-12-12'
WHERE Data = '1999-08-09'
Результат:
3. Триггер для проверки даты пропажи (кража, либо владелец скрылся с места дтп):
CREATE TRIGGER Проверка_даты_пропажи
ON Stealing
AFTER INSERT, UPDATE
AS
IF EXISTS (
SELECT *
FROM Stealing, PTS
WHERE PTS.[Year] > Stealing.[Date])
BEGIN
ROLLBACK
PRINT 'Неверная дата пропажи транспортного средства'
END
Проверка триггера:
UPDATE Stealing
SET Date = '2015-08-09'
WHERE Date = '1999-08-09'
Результат: