Логическая модель РБД. Бизнес-логика файл-серверной, клиент-серверной и N-уровневой архитектуры
Клиент-сервер с бизнес-логикой на клиенте
В данных системах хранение, выборка и поддержание непротиворечивости данных возлагается на сервер БД, а вся бизнес-логика и логика представления исполняются на клиентских машинах. Так как все операции по манипулированию данными осуществляются только через сервер, производительность и сохранность данных зависит только от сервера БД. Серверы БД изначально рассчитаны на многопользовательский режим работы, имеют эффективные алгоритмы кеширования данных. Современные серверы имеют хорошую масштабируемость.
Клиентская часть обменивается данными с сервером посредством SQL запросов. Обработка информации в клиент-серверных системах ведется на уровне множества кортежей.
Процесс разработки разделяется на создание БД и написание клиентской части с бизнес-логикой.
Достоинства
- Высокая производительность, стабильность и надежность при многопользовательской работе.
- Легко организуется защита данных (шифрование сетевого трафика SSH, SSL)
- Универсальность языка определения и манипулирования данными
Недостатки
- Более высокая цена СУБД. (сервер БД продается отдельно).
- Достаточно высокие требования к квалификации разработчиков
- Навыки администрирования сервера БД
- Повышенные требования к пропускной способности сети
- Повышенные требования к клиентским местам (на них выполняется слой бизнес- логики)
Выводы
При количестве пользователей от 2 до ~50 она является хорошим вариантом. С ростом числа пользователей начинает сказываться недостаточная пропускная способность сети.
Клиент-сервер с бизнес-логикой на сервере
Используется возможность современных серверов БД исполнять хранимые SQL процедуры на сервере, куда и переносится максимально возможная часть бизнес-логики. Требования к серверу БД возрастают, однако резко понижаются требования к клиентским машинам (за счет выноса с них бизнес-логики) и к пропускной способности сети (клиенту передаются только данные, необходимые пользователю).
Достоинства
- Пониженные, по сравнению с предыдущим классом систем, требования к пропускной способности сети и клиентским местам.
- Более простой процесс создания бизнес-логики.
Недостатки
- Повышенные требования к серверу БД.(каждый сеанс "съедает" память из расчета предельной загрузки)
- Невысокая переносимость (мобильность) системы на другие серверы БД.
Выводы
По сравнению с предыдущими классами, позволяет держать большую нагрузку.
N-уровневая архитектура
Основными элементами являются сервера БД, сервер(кластер) приложений и клиентская часть. Главная идея n-уровневой архитектуры заключается в максимальном упрощении клиента (тонкий клиент) , выносе всей бизнес-логики с клиента и сервера БД.
Тонкий клиент представляет собой некоторый терминал типа HTML-browser или эмуляторы X-терминала
Вся бизнес- логика оформляется в виде набора приложений, запускаемых на сервере приложений под управлением ОС типа UNIX.
Сервера БД занимаются только проблемами хранения, добавления, модификации и поддержания непротиворечивости данных.
Сервер приложений соединен с сервером БД при помощи отдельного высокоскоростного сегмента сети.
Достоинства
- Повышенная защищенность.
- Высокая производительность.
- Легкость развития и модификации.
- Легкость администрирования.
- Возможность создания системы с массовым параллелизмом (серверов БД может быть несколько, а сервером приложений могут служить несколько соединенных в кластер компьютеров).
Недостатки
- Высокая сложность.
- Высокая цена решения.
- В некоторых случаях уступает по производительности клиент-серверным системам с бизнес-логикой на сервере.
Выводы
Единственная альтернатива для создания ИС для очень большого количества пользователей.
Практические занятия
Постановка задачи. Проектирование данных на концептуальном и логическом уровнях. Нормализация отношений.
Презентация по ER-моделированию
Подготовка SQL скриптов генерации схемы отношений БД в ERwin. Разработка скрипта для ввода тестовой информации.
Видео-презентация (Для проигрывания требуется Windows Media Player)
Архитектура MS SQL Server 2005. Настройка и использование основных компонент среды. Создание учебной базы данных.
Видео-презентация (Для проигрывания требуется Windows Media Player)
Работа с СУБД MS SQL Server 2005, ORACLE 10g. Примеры соединений с БД, технологии разработки клиенского приложения
Использование технологии Java Database Connectivity (JDBC) для работы с базами данных
Примеры к презентации
SQL-скрипты, проект и исходные коды
package org.mai806.jdbcsample;
import java.sql.*;
public class QuerySample {
public static void main(String[] args) throws Exception {
/* ======== Подключение к MS SQL Server ===== */
// Загрузка драйвера
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
// Соединение с базой данных
Connection connection = DriverManager.getConnection(
"jdbc:sqlserver://localhost:1433;databaseName=o01;",
// localhost - сервер СУБД, o01 - имя базы данных
"sa", "123"); // пользователь, пароль
/* ======== Подключение к Oracle ============
// Загрузка драйвера
Class.forName("oracle.jdbc.OracleDriver");
// Соединение с базой данных
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:orcl",
// localhost - сервер СУБД, orcl - SID базы оракла
"o01", "o01"); // пользователь, пароль
// Создание Statement
PreparedStatement stmt = connection.prepareStatement
("select ID, NAME from PERSON where NAME like ?");
stmt.setString(1, "%S%");
// Выполнение запроса
ResultSet rs = stmt.executeQuery();
// Перебор результата выполнения запроса
while(rs.next()) {
// Пример выбора параметра по номеру или по имени
System.out.println("ID: " +
rs.getLong(1) + "; NAME="+
rs.getString("NAME"));
}
// закрытие использованных ресурсов БД
rs.close();
stmt.close();
connection.close();
}
}
Листинг
P.1.
Выполнение запроса: QuerySample.java
package org.mai806.jdbcsample;
import java.sql.*;
import java.util.ResourceBundle;
public class StoredProcedureSample {
private static Connection connection = null;
public static void main(String[] args) throws Exception {
// Получение соединения из значений параметров в файле properties
ResourceBundle properties = ResourceBundle.getBundle("database");
Class.forName(properties.getString("driver"));
connection = DriverManager.getConnection(
properties.getString("url"),
properties.getString("user"),
properties.getString("password"));
transferAmount(1,2,100.0);
connection.close();
}
/**
* Переводит указанную сумму с одного счета на другой
* @param from счет плательщика
* @param to счет получателя
* @param amount сумма
*/
public static void transferAmount(long from, long to, double amount)
throws Exception {
// Создание Statement
CallableStatement stmt
= connection.prepareCall("{call TransferAmount(?,?,?)}");
// Установка параметров
stmt.setLong(1, from);
stmt.setLong(2, to);
stmt.setDouble(3, amount);
// Выполнение процедуры
stmt.execute();
}
}
Листинг
P.2.
Выполнение хранимой процедуры: StoredProcedureSample.java
package org.mai806.jdbcsample;
import java.sql.*;
import java.util.ResourceBundle;
public class TransactionalSample {
private static Connection connection = null;
public static void main(String[] args) throws Exception {
// Получение соединения из значений параметров в файле properties
ResourceBundle properties = ResourceBundle.getBundle("database");
Class.forName(properties.getString("driver"));
connection = DriverManager.getConnection(
properties.getString("url"),
properties.getString("user"),
properties.getString("password"));
// Ручное управление транзакциями
connection.setAutoCommit(false);
try {
transferAmount(2, 1, 10.0);
} finally {
connection.close();
}
}
/**
* Переводит указанную сумму с одного счета на другой
* @param from счет плательщика
* @param to счет получателя
* @param amount сумма
*/
public static void transferAmount(long from, long to,
double amount) throws Exception {
PreparedStatement stmt = null;
Statement query = null;
try {
stmt = connection.prepareStatement
("update ACCOUNT set AMOUNT=AMOUNT+? where ID=?");
// Забираем сумму со счета плательщика
stmt.setDouble(1, -amount);
stmt.setLong(2, from);
stmt.execute();
// Добавляем сумму на счет получателя
stmt.setDouble(1, amount);
stmt.setLong(2, to);
stmt.execute();
// Пост-проверка: отрицательность счета плательщика
query = connection.createStatement();
ResultSet rs = query.executeQuery(
"select AMOUNT from ACCOUNT where ID="+from+" and AMOUNT<0");
if (rs.next()) {
throw new Exception("На счете №"+from+"
недосточно средств ["+(amount+rs.getDouble(1))+"]
для снятия суммы ["+amount+"]");
}
connection.commit();
System.out.println("Перечисление средств успешно выполнено");
} catch(Exception e) {
e.printStackTrace();
connection.rollback();
} finally {
if (stmt!=null)
stmt.close();
if (query!=null)
query.close();
}
}
}
Листинг
P.3.
Работа с транзакциями: TransactionalSample.java
