Материал: Программа для поддержки процессов выявления проблемных запросов в СУБД Oracle

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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

На рисунке 2.4 приводится пример прототипа интерфейса панели мониторинга.

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

Рисунок 2.4 - Прототип панели мониторинга

.9 Алгоритм визуализация плана исполнения запроса

Алгоритм получения плана исполнения запроса проходит в несколько этапов - вначале для полученного запроса выполняется выражение explain plan for, которое заполняет таблицу plan_table данными плана выполнения, после этого происходит выборка из заполненной plan_table, полученные данные обрабатываются и отображаются пользователю.

Так как все запросы к базе данных выполняются на стороне сервера, а отображение информации происходит на стороне клиента, то для передачи данных будет использоваться JSON (JavaScript Object Notation) - текстовый формат для обмена данными.

Рисунок 2.5 - Алгоритм визуализации плана исполнения запроса

.10 Проектирование схемы БД приложения

База данных хранит информацию о пользователях и доступных им соединениях к БД.

Рисунок 2.6 - Схема базы данных

Таблица user содержит информацию о пользователе, которая включает в себя:- уникальный идентификатор пользователя;- имя пользователя;- электронная почта;_hash - хеш-код пароля пользователя;- статус пользователя;_key - ключ аутентификации;_at - дата создания аккаунта;_at - дата последнего изменения аккаунта.

Таблица connection содержит информацию о данных, необходимых для соединения к базе данных пользователя:- уникальный идентификатор;- имя пользователя для доступа к БД;- пароль;- хост;_name - имя БД;_selected - флаг, указывающий соединение, с которым ведется работа.

3. РЕАЛИЗАЦИЯ ПП

.1 Разработка основных контроллеров приложения

Контроллер обеспечивает взаимодействие между пользователем и приложением, используя для этого модель и представление для реализации необходимых реакций.

В Yii2 контроллеры содержат в себе действия - функции, которые реализуют основной функционал, пользователь может обращаться к действиям для получения необходимых данных. Один контроллер может иметь одно и более действий.

Основные действия приложения реализуют два контроллера - SiteController и QueryController.реализует основные действия, к которым обращается обычный пользователь:- в зависимости от прав пользователя отображает стартовую страницу. Для авторизированного пользователя - это панель мониторинга, для посетителя отображается посадочная страница (landing page);- отображает форму регистрации;, actionLogout используются пользователями для входа в учетную запись или выхода из неё.- контактная форма.необходим для обмена данными, передает со стороны

сервера JSON, который затем обрабатывается на стороне клиента с помощью языка JavaScript.

Ниже приводится действие actionIndex контроллера SiteController.

public function actionIndex()

{(!\Yii::$app->user->isGuest)

{

$currentConnection = ConnectionController::getSelectedConnection();

$this->render('dashboard',[

'curConnection' => $currentConnection,

]);

}

$this->render('landing');

}

.2 Использование интерфейса OCI8 для работы с БД Oracle

Расширение уже входит в версии PHP начиная с 5.3, но также для корректной работы необходимо установить бесплатные библиотеки Oracle Instance Client и системную переменную окружения PATH на папку, в которой находятся библиотеки Oracle.

Для подключения к серверу Orаcle имеется несколько различных функций, стандартная функция - oci_connect(). При вызове этой функции создается соединение к БД Oracle и возвращается ресурс, который нужно использовать для дальнейшей работы с БД.

Подключение к серверу - дорогостоящая операция по времени выполнения. Функция oci_connect использует кэш, который очищается каждый раз после выполнения скрипта, или после того, как соединение закрывается.

Для получения соединения создан вспомогательный класс, получить соединение с БД можно с помощью функции, которой передается модель пользователя:

public static function getConnection($user)

{

$conn = oci_connect($user ->username, $user ->password,

$user ->host . '/' . $user ->db_name);(!$conn)

{

$e = oci_error();_error(htmlentities($e['message'], ENT_QUOTES), _USER_ERROR);

}$conn;

}

.3 Реализация системы регистрации и авторизации пользователей на сайте

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

Аутентификация и авторизация нужны на страницах, доступных лишь некоторым пользователям. Аутентификация - это проверка, является ли пользователь тем, за кого себя выдаёт. Авторизация - это проверка, может ли пользователь, прошедший аутентификацию, выполнять определённые действия.

Регистрации необходима для того, чтобы безопасно хранить данные для подключения к БД, с которой будет работать пользователь. Только зарегистрированный пользователь может использовать функционал системы, также один пользователь может работать с различными БД, он может создать несколько подключений к БД и переключаться между ними.

В Yii встроен механизм авторизации и аутентификации (auth), который может быть гибко настроен под различные задачи.

Основным компонентом auth-фреймвoрка является компонент user, данный объект содержит информацию о текущем пользователе, которую можно получить в любой момент и из любого места программы.

С помощью этого компонента можно производить вход или выход, проверять аутентифицирован ли текущий пользователь и другие подобные действия.

Пароли пользователей не хранятся в открытом виде в БД, в целях безопасности в базе хранится хеш-код пароля.

В Yii2 был реализован механизм хеширования bcrypt, метод generatePasswordHash принимает входной параметр - пароль и возвращает сгенерированный хеш-код:

$hash_password=Yii::$app->getSecurity()->generatePasswordHash(‘123);

В результате выполнения данной операции переменная $hash_password будет иметь значение из 64 символов, примерно следующего вида:

$4z$33$doo.o0q9qN/IrWF4RgoH6ejHyS1d.ElmkayY2vQ58DTApgGhU7Rji.

Также методу generatePasswordHash можно передать второй параметр - сложность шифрования, по умолчанию сложность равна 13, это довольно ресурсоемкий процесс, поэтому для текущей задачи ставить значение выше не имеет смысла.

Повторный вызов данного метода генерирует абсолютно другую последовательность символов.

Для того, чтобы проверить, правильно ли пользователь ввел свой пароль, используется метод validatePassword класса User. При проверке паролей сравниваются их хеши:function validatePassword($password)

{Yii::$app->security->validatePassword($password,

$this->password_hash);

}

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

Рисунок 3.1 - Форма регистрации

.4 Разработка редактора подключений к БД

Для подключения к базе данных необходима следующая информация:

имя пользователя;

пароль;

хост;

имя БД.

Редактор подключений необходим для управления этой информацией,

реализации базовых операций - create, update, insert, delete.

.4.1 Генератор кода

Одним из основных преимуществ и отличий фреймворка YII 2.0 является генератор кода gii. С помощью этого генератора можно создавать модели, контроллеры, формы, представления на основе таблиц базы данных, других моделей, контроллеров, а также модули и расширения. Генератор gii сделан максимально простым в настройке шаблонов, поэтому можно создать свои собственные шаблоны генерации контроллеров и моделей или изменить стандартные.

Последовательность работы с генератором кода следующая:

перейти на страницу генератора кода;

заполнить необходимые параметры для генерации кода;

для предварительного просмотра кода можно нажать кнопку preview будет показан список файлов, которые будут сгенерированы;

Для создания файлов нужно нажать кнопку generate.

.4.2 Использование gii для создания редактора подключений

Вначале нужно создать модель Connection, для этого необходимо указать название модели и таблицу, на основе которой будет сгенерирована модель.

Рисунок 3.2 - фрагмент формы генерации модели

Код будет сгенерирован с указанным пространством имен.

На основе модели можно создать CRUD контроллер, который будет реализовывать основные операции для работы с моделью - create, read, update, delete.

Рисунок 3.3 - фрагмент формы генерации CRUD контроллера

Также с помощью gii можно создать необходимые формы и представления.

На рисунке 3.4 представлена форма для просмотра доступных подключений. Весь код был создан с помощью генератора кода, что существенно ускорило процесс разработки. Для реализации более сложной логики необходимо дописывать, изменять полученный кода.

Рисунок 3.4 - редактор подключений к БД

.5 Разработка панели мониторинга

Панель мониторинга необходима для отображения информации о базе данных Oracle, текущем подключении, а также об объектах пользователя.

Для получения основных сведений о версии БД используется запрос:* FROM v$version;

Для получения информации о размере БД используются таблицы dba_data_files и dba_free_space, полученная информация отображается в виде диаграммы.

Информация об объектах пользователя отображается в HTML таблицах, функционал которых расширен с помощью библиотеки DataTables.js, для отображения такой создано специальное представление SimpleDataTable, которое позволяет избежать дублирования кода:

var SimpleDataTable = Backbone.View.extend({

el: null,

table: null,

url: null,

columns: null,

{

this.el = settings.el;

this.url = settings.url;

this.render(this.url, settings.columns);

},

render: function(url, columns)

{

var sqlTable = this;

var table = this.$el.DataTable( {

"ajax": url,

"columnDefs": [

{ "type": "numeric-comma", targets: 0 }

],

"columns": columns,

});

this.table = table;

},

});

Для создания нового объекта SimpleDataTable нужно передать три

параметра: - идентификатор HTML таблицы;- адрес, по которому выводится JSON информации для представления;- список столбцов таблицы.

Пример создания таблицы, отображающей данные о таблицах пользователя, находящихся в базе данных.

var userTables = new SimpleDataTable({ el: '#user-tables-table', url: USER_TABLES_URL,

columns: [

{ "data": "TABLE_NAME" },

{ "data": "NUM_ROWS" },

{ "data": "AVG_SPACE" },

{ "data": "MAX_TRANS" },

{ "data": "TABLE_LOCK" },

]});

Переменная USER_TABLES_URL содержит ссылку на действие контроллера QueryController.

Для получения информации о таблицах пользователя использовался следующий запрос:

Select table_name, num_rows, avg_space, max_trans, table_lock

from user_tables;

.6 Разработка компонентов для отображения данных SQL-запросов

Для отображения данных SQL-запросов были созданы специальные представления, которые позволили избежать дублирования кода.

К примеру, для получения десяти наиболее длительно выполняющихся запросов используется следующая выборка:

SELECT * FROM (SELECT sql_fulltext, sql_id, elapsed_time, cpu_time,_reads, executions, child_number, first_load_time, last_load_time FROM v$sqlBY elapsed_time DESC) WHERE ROWNUM < 10;

QueryController содержит действие, в котором выполняется данный запрос, и весь результат выводится в формате JSON:

public function actionLongrunningqueries() {(!\Yii::$app->user->isGuest) {

$currentConnection = ConnectionController::getSelectedConnection();

$qm = QueryManager::getInstance( OracleConnectionManager::getConnection($currentConnection));

$queris = $qm->getLongRunningQueries();json_encode($queris);}

}

Компонент, отображающий длительно выполняющиеся запросы, принимает в качестве входного параметра url-адрес действия actionLongrunningqueries(), при загрузке страницы данный компонент, асинхронно обращается по переданному url-адресу, получает JSON и отображает информацию.

На рисунке 3.5 представлен компонент, отображающий десять наиболее длительно выполняющихся запросов.

Рисунок 3.5 - Длительно выполняющиеся запросы

Данные можно отсортировать по любому столбцу, а при нажатии на элемент - строку таблицы, выводится диалоговое окно, в котором отображается полный текст запроса и план выполнения запроса.

Рисунок 3.6 - Диалоговое окно с вкладками, отображающими текст и план выполнения выбранного запроса

.7 Особенности реализации пользовательского интерфейса

имеет систему сеток, которая применятся для создания адаптивной разметки блоков. Система сеток имеет четыре класса:(extra small) - очень маленькие экраны, меньше 768px;(small) - маленькие экраны, от 768px до 992px;(middle) - средние экраны, от 992px до 1200px;(large) - большие экраны, более 1200px.

По умолчанию сетка имеет 12 колонок, но это значение может

изменяться.

Для использования такой разметки вначале нужно создать ряд:

<div>

Внутри такого блока добавляется необходимое количество колонок, это делается с помощью указания класса .col-*-* каждому блоку, внутри которого будет размещаться содержимое, минимальная ширина блока равна одной колонке, максимальная двенадцати колонкам.

Ниже представлен пример разметки, один ряд делится на три колонки.

<div>

<div>

<div>

<div>

</div>

Для каждого из размеров экранов указывается количество колонок, так

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

Пользовательский интерфейс разделен на две большие колонки:

левая колонка - боковое меню;

правая колонка - основное содержимое, которое также делится на колонки.

Для реализации удобного представления меню на маленьких экранах

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

/* styles */ }

Стили, прописанные в теле конструкции @media, будут применяться если рабочая область браузера не превышает 768px.

4. ТЕСТИРОВАНИЕ ПП

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

Чем сложнее ПП, тем больше времени и средств требуется на его тестирование.

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