Добавить в избранное   Сделать стартовой   Главная   E-mail   Форум   Мой блог 
   
Cертификации

Errors

ETL

FAQ (по темам)

GIS

Web

wiki

Администрирование

Безопасность

Книги
Oracle, ...

Новости

ОС

Программирование

Проектирование БД

Производительность

Скачать

Советы

Тестирование

Установка

FAQ - по базам данных
FAQ - по базам данных
Установка СУБД
Oracle
Sybase
MySQL
PostgreSQL
MS SQL Server
Interbase, Firebird
Другие DB
Администрирование
Oracle
MySQL
Sybase
PostgreSQL
MS SQL Server
Interbase, Firebird
IBM DB2
Другие DB
Проектирование БД
Статьи
ETL
Теория БД
ErWin
Designer 2000
PowerDesigner
Хранилища данных
CASE средства
OLAP
Бизнес - анализ (BI)
Производительность
Oracle
MSSQL
Interbase, Firebird
IBM DB2
MySQL
PostgreSQL
SYBASE
Безопасность БД
Oracle
MS SQL Server
Инъекция SQL
Программирование
Transact-SQL
PL/SQL
C++
XML
SQL
PostgreSQL
MDX
Java
VBA Excel
Книги по базам
Oracle
Заказ книг
ОС
Установка и настройка
UBUNTU
ОС
Установка и настройка
UBUNTU
FAQ
FAQ - по базам данных
Главная arrow SQL arrow Как правильно писать SQL-запросы

Как правильно писать SQL-запросы

Печать E-mail
 

   Последние два года я программирую "тяжелую" web-ориентированную систему, и мне приходится постоянно писать запросы для баз данных(Oracle). За это время у меня выработался определенный вкус в этом деле. Хочу поделиться своими соображениями, которые, конечно, не претендуют на абсолютную верность. Многие считают, что везде, где можно использовать "чистый" SQL вместо объектно-ориентированного подхода, нужно его использовать. Это заблуждение. Вы не поверите, сколько времени оно отняло у меня. Поясню. Предположим, что необходимо получить информацию о пользователе и некоторых объектах, которые с ним связаны.

Примерный вид решения на SQL:
SQLObject object = executeQuery (
"SELECT u.name user_name, dep.name dep_name\n" +
"FROM USERS u, DEPARTMENTS dep\n" +
" WHERE u.user_id = ?\n" +
" AND u.department_id = dep.department_id",
userID )

Примерный вид решения с использованием API:

User user = new User(userID);
Department department = user.getDepartment();

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

От подзапросов можно отказаться в 99% случаев. Обычно подзапросами активно пользуются начинающие программисты. Вот типичный случай его использования: для пользователя из предыдущего случая нужно вывести название департамента, к которому он приписан, но при этом те пользователи, которые проходят стажировку, не приписаны к департаменту, и для них нужно вывести null.
С подзапросом (поверите, так очень многие пишут):

SELECT u.name user_name, (SELECT dep.name FROM DEPARTMENT dep WHERE u.department_id = dep.department_id) dep_name
FROM USERS u
WHERE u.user_id = ?

Без подзапроса:

SELECT u.name user_name, dep.name dep_name
FROM USERS u
LEFT JOIN DEPARTMENTS dep
ON u.department_id = dep.department_id
AND u.user_id = ?

В Oracle можно красивее:

SELECT u.name user_name, d.name dep_name
FROM USERS u, DEPARTMENTS dep
WHERE u.user_id = ?
AND dep.department_id(+) = u.department_id


Везде, где можно, используйте Prepared Statements. Во-первых, это безопаснее, а во-вторых, быстрее. Иногда отсутствие Prepared Statement в часто выполняющемся запросе может очень сильно сказаться на производительности базы данных. Пример. Нужно часто получать информацию о конкретном пользователе.
Решение без Prepared Statement:

String name = executeSimpleQuery("SELECT u.name FROM USERS u WHERE u.user = " + userID);

Решение с Prepared Statement:

String name = executePreparedQuery("SELECT u.name FROM USERS u WHERE u.user = ?", userID);

Почему второй вариант лучше (вопросов безопасности касаться пока не буду, т. к. могу дать несколько неверное объяснение)? Дело в том, что поступающие запросы анализируются СУБД и сохраняются в кэше. Два запроса без Prepared Statement с разными userID будут считаться разными, а анализ запроса с Prepared Statement поведется один раз (при условии, что его не вытеснят из кэша). Это первый аспект. Второй аспект состоит в том, что если в одном из запросов вы не стали использовать Prepared Statement, то его частая обработка будет вытеснять из кэша другие, уже проанализированный запросы, что сведёт всю систему кэширования на нет.

Используйте грамотные алиасы, особенно, когда во "FROM" стоит много таблиц. Также, не стоит забывать использовать комментарии в запросах.

Автор: rachiu

 
 
« Пред.   След. »
Взаимосвязанные статьи
     

Последние добавленные статьи
Поиск
Ссылки
Главная
Скачать
Курсы
Роль АБД (SYSDBA)
Карта сайта
Автостекла
Контакты
Войти на сайт
Популярные статьи
Online - тесты
1Z0-042
Rambler's Top100 МЕТА - Украина. Рейтинг сайтов хостинг от freehost.com.ua

Все права защищены.SYSDBA 2010 | Если у Вас есть хороший материал пришлите его нам.