- •4.5. Упражнения 67
- •Глава 6. Устройство Informix Dynamic Server 165
- •Глава 7. Эксплуатация информационных систем 177
- •Глава 1 Обзор основных архитектур баз данных
- •1.1. Архитектура на основе разделяемых файлов
- •1.2. Архитектура “Хост-терминал”
- •1.3. Архитектура “Клиент-Сервер”
- •1.4. Архитектура с использованием сервера приложений (трехзвенная архитектура)
- •1.5. Упражнения
- •Глава 2 Модели данных
- •2.1. Уровни восприятия данных
- •2.2. Иерархическая модель данных
- •2.3. Сетевая модель данных
- •2.4. Реляционная модель данных
- •2.5. Объектно-реляционная модель данных
- •Глава 3 Реализация информационных систем на основе продуктов Informix Software
- •3.1. Обзор продуктов Informix
- •3.2. Варианты построения систем
- •Internet/Intranet-конфигурация
- •3.3. Выбор оптимальной конфигурации
- •Глава 4 Математические основы реляционных субд
- •4.1. Основные понятия
- •4.2. Ключи
- •4.3. Основные операции над таблицами и их интерпретация
- •4.4. Нормализация
- •4.5. Упражнения
- •Глава 5 Язык sql
- •5.1. Типы данных, доступные в sql
- •5.3. Основные sql-операторы для доступа и модификации данных
- •5.4. Управление транзакциями
- •5.5. Продвинутые варианты оператора поиска
- •5.5.1. Поиск по нескольким таблицам
- •5.5.2. Устранение повторения данных в операторе select
- •5.5.3. Вычисления внутри оператора select
- •5.5.4. Логические выражения в условии sql-операторов
- •5.5.5. Слияние двух выборок
- •5.5.6. Сортировка выборки
- •5.5.7. Вставка в таблицу нескольких строк одновременно
- •5.6. Использование sql в языках программирования
- •5.7. Программирование сервера базы данных
- •5.7.1. Динамический sql
- •5.7.3. Хранимые процедуры
- •5.7.4. Триггеры
- •5.8. Ограничители (задание целостности на уровне схемы)
- •5.9. Разграничение в sql прав пользователей
- •5.9.1. Права доступа
- •5.9.2. Права на уровне базы данных
- •5.9.3. Права на таблицы
- •5.9.4. Права на хранимые процедуры
- •5.9.5. Кто и как следит за соблюдением прав
- •5.9.6. Механизм ролей
- •5.9.7. Псевдотаблицы (view)
- •5.9.7. Синонимы
- •5.10. Управление одновременным доступом к данным
- •5.10.1. Что бывает, когда несколько человек одновременно пытаются обновить одни и теже данные
- •5.10.2. Открытие базы данных только для себя
- •5.10.3. Блокирование таблицы
- •5.10.4. Механизм блокирования записей и уровни изоляции
- •5.10.5. Управление ожиданием снятия блокировок
- •5.10.6. Тупиковые ситуации
- •5.11. Повышение скорости обработки запросов.
- •5.11.1. Индексы
- •5.11.2. Буферизация журнала транзакций
- •5.11.3. Блокировка на уровне записей и страниц
- •5.11.4. Эффективное построение запросов
- •5.11.5. Сортировка и поиск по коротким полям. Классификаторы
- •5.12. Объектное расширение sql в Informix ds/Universal Data Option
- •5.12.1. Зачем нужна поддержка объектов в серверах бд?
- •5.12.3. Внедрение объектно-ориентированной технологии
- •5.12.4. Реализация объектного подхода в Informix
- •Informix ds/Universal Data Option - объектно-реляционная субд
- •5.12.5. Итак…
- •Глава 6. Устройство Informix Dynamic Server
- •6.1. Внутренняя архитектура dsa
- •6.2. Механизм хранения данных
- •6.3. Инсталляция продукта
- •6.4. Запуск и останов сервера
- •6.5. Работа с русским языком
- •Глава 7. Эксплуатация информационных систем
- •Администрирование серверов баз данных
- •7.2. Обеспечение сохранности данных.
- •7.2.1. Технологии постоянного дублирования
- •7.2.2. Архивация
- •7.2.3. Так как же обеспечить сохранность данных?
- •7.3. Архивирование и восстановление данных
- •7.3.1. Что нужно архивировать
- •7.3.2. Утилиты архивации и восстановления
- •7.3.3. Создание архивов утилитой ontape
- •7.3.4. Восстановление из архивов утилитой ontape
- •7.3.5. Как узнать “когда”?
- •7.3.6. Практические советы
- •7.4. Средства контроля за доступом
- •7.4.1 Как работает аудитинг?
- •7.4.2. Конфигурирование списков протоколируемых событий
- •7.4.3. Задание файлов, запуск и остановка механизма аудитинга
- •Анализ протокола
- •7.4.5. Практические советы или Что делать, если вы хотите…
- •7.5. Реагирование на чрезвычайные ситуации
- •7.6. Мониторинг текущего состояния сервера базы данных
- •7.6.1. Кто работает с сервером базы данных
- •7.6.2. Сколько памяти использует сервер бд
- •7.6.3. Сколько свободного места имеется у сервера бд
- •7.7. Достижение требуемой производительности
- •7.7.1. Как узнать, что ждет некоторый запрос
- •7.7.2. Как выяснять причины падения производительности
- •2. Общие принципы предлагаемой технологии
- •3. Как портировать приложение
5.5.2. Устранение повторения данных в операторе select
Отношение или таблица- это множество. Следовательно, в них могут содержаться повторяющиеся элементы (одинаковые записи). И если в реальных таблицах это практически никогда не встречается (ведь надо же как-то различать описания разных сущностей!), то в отношении, которое является результатом работы оператора SELECT такие повторения могут возникать достаточно часто. Если в формируемой с помощью оператора SELECT отношении Вам надо избавиться от повторений, то перед списком полей следует поставить ключевое слово DISTINCT или UNIQUE (это синонимы). В этом случае, если в выборке, удовлетворяющей условию WHERE, имеется несколько записей с одинаковыми значениями, то оператор SELECT исключит повторения. Например, если Вам требуется распечатать только номенклатуру поставляемых товаров, без учета того, что один и тот же вид продукта может пставляться разными поставщиками, Вам следует выполнить запрос:
SELECT UNIQUE name FROM items
Если в запросе выбирается два или более поля, то две записи считаются равными, если равны все их составляющие поля.
5.5.3. Вычисления внутри оператора select
Оператор SELECT можно использовать не просто для выборки каких-то значений из одной или нескольких таблиц, но и для осуществления каких-то действий над выбираемыми значениями. Это могут быть арифмеические или строковые операции над полями, сортировка и т.д.
Выражения над полями
Оператор SELECT может производить сразу вычисления. Над отдельными полями можно производить символьные иарифметические операции, а также функции. В вражениях можно использовать как значения полей, так и константы.
К символьным операциям относится конкатенация двух строк и выделение подстроки. Операция конкатенации записывается в виде двух вертикальных черт: '||'. Операция выделения подстроки записывается с помощью квадратных скобок, в которых через запятую указан номер первого и последнего символа в подстроке. Рассмотрим примеры:
SELECT lname[4,9] FROM companies
"Рога и Ко" " Добро по" "Т Сделай "
SELECT lname || " " || fname FROM persons
"Антонов Сергей" "Шапокляк Алексей" "Антонов Антон" "Бендер Остап"
Обратите внимание, что в последнем примере результат - это четыре ряда, каждый из которых состоит из одной строки. Если бы мы выполнили запрос
SELECT lname, fname FROM persons
то получили бы четыре ряда по два строковых значения в каждом.
В последнем примере мы также использовали и текстовую константу - строку из одного пробела, заключенную в кавычки. Можно использовать строковые константы любой длины и состоящие из любых символов. Если внутри константы надо использовать символ "кавычки", то следует написать его подряд дважды. В символьных выражениях Вы можете использовать и не символьные выражения операция преобразования типов (например, числа 1234 в строку "1234") будет произведена автоматически.
К арифметическим операциям относятся операции сложения ('+'), вычитания ('-'), умножения ('*') и деления ('/'). Пример:
SELECT price*1.2 FROM items
SELECT tax*quantity/1.2 FROM orders
В выражениях внутри оператора SELECT имеется возможность вызывать функции. Некоторые доступные функции приведены в табличке.
Функция определения длины: LENGTH(<имя поля>) - вычисляет длину строки, которая LENGTH(<текстовая строка>) содержится в указанном поле записи или указанной текстовой констант;
Временные функции: DATE (<выражение не типа DATE>) - преобразует выражение типа CHAR, INTEGER или DATETIMEв значение типа DATE; DAY(<выражение типа DATE или DATETIME>) - по заданному в качестве аргумента значению вычисляет номер дня в месяце; MDY(<месяц>, <день>, <год>) - по заданным трем целым значением, определяющим номер месяца, дня, года строится значение типа DATE; MONTH (<выражение типа DATE или DATETIME>) - по заданному в качестве аргумента значению вычисляет номер месяца в годе; WEEKDAY (<выражение типа DATE или DATETIME>) - по заданному в качестве аргумента значению вычисляет номер дня недели, причем восвкресенью соответсвует значение 0, понедельнику - 1 и т.д.; YEAR (<<выражение типа DATE или DATETIME>) - по заданному в качестве аргумента значению вычисляет номер года, состоящий из 4-х цифр;
Функции преобразования HEX (<целое выражение>) - преобразует целое, заданное в качестве аргумента, в строку, представляющую шестнадцатеричную запись данного целого; ROUND (<числовое выражение, точность>) - округляет с указанной точностью числовое выражение, заданное в качестве аргумента; точность определяет степень одной десятой, до которой надо округлять. TRUNC (<числовое выражение, точность>) - обрезает незначащие цифры у заданного в качестве аргумента выражения, причем точность определяет смещение влево от запятой последней значащей цифры;
Математические функции: ACOS(<числовое выражение>) - арккосинус от заданного значения; ASIN(<числовое выражение>) - арксинус от заданного значения; ATAN (<числовое выражение>) - арктангенс от заданного значения; COS(<числовое выражение>) - косинус от заданного числа радиан; SIN(<числовое выражение>) - синус от заданного числа радиан; TAN (<числовое выражение>) - тангенс от заданного числа радиан; ABS (<числовое выражение>) - абсолютное значение; EXP (<степень>) - вычисление заданной экспоненты; LOGN (<выражение>) - вычисление натурального логарифма; LOG10 (<выражение>) - вычисление десятичного логарифма; MOD (<делимое>, <делитель>) - остаток от деления; POW (<значение>, <степень>) - возведение в степень; ROOT (<значение>, <степень>) - вычисление корня заданной степени; SQRT (<числовое выражение>) - квадратный корень;
Функции – псевдополя CURRENT <диапазон> - возвращает точный момент времени (тип DATETIME), когда происхoдит обработка данного запроса; параметр <диапазон> задает (как и при описании типа DATETIME) требуемое точность - от года до тысячных секунды (например, CURRENT DAY TO SECOND); TODAY - возвращает дату (тип DATE) выполнения даного запроса; USER - возвращает имя пользователя (как он зарегестрировался в операционной системе), который выполняет данный запрос.
Следует напомнить про специальное значение NULL - "не определено". Если это значение встретится в выражении, то и все выражение будет иметь значение NULL. Даже умножив нуль на NULL, Вы все равно получите NULL. Конкатенация любой строки с неопределенной строкой (то есть строкой, имеющей значение NULL) тоже в результате даст NULL.
В выражениях можно использовать и скобки. С их помощью Вы имеете возможность управлять порядком вычисления внутри выражения.
Агрегатные функции
Рассмотренные в предыдущем пункте функции производили действия над отдельным полем одной записи из выборки. Агрегатные функции позволяют производить вычисления над совокупностью одних и тех же полей сразу в нескольких записях выборки. Например, если мы хотим определить максимальную цену на товар из нашей базы данных, надо выполнить запрос
SELECT MAX(price) FROM items
В этом запросе будут просмотрены все записи из таблицы items и будет определено максимальное значение среди всех полей price.
Если мы хотим просто узнать, сколько записей получается в результирующей выборке, то надо использовать агрегатную функцию COUNT(*). Например, для того, чтобы получить число предложений поставок джинсов (сколько раз в таблице items имеется записей с названием товара "джинсы"), надо выполнить запрос
SELECT COUNT(*) FROM items WHERE name="джинсы"
А если мы хотим получить пару значений - минимальная и максимальная цены на кеды, то это достигается следующим запросом:
SELECT MIN(price), MAX(price) FROM items WHERE name="кеды"
Некоторые агрегатные функции перечислены в таблице:
AVG(<имя поля>) - среднее по всем значениям данного поля; COUNT(*) - количество записей; MAX(<имя поля>) - максимум из всех значений данного поля; MIN(<имя поля>) - минимум по всем значениям данного поля; SUM(<имя поля>) - сумма всех значений данного поля.
Приведенные выше примеры агрегатных функций работали со всей выборкой сразу - либо со всей таблицей, если условие не было задано, либо с записями, удовлетворяющими условию, если условие присутствовало. Но для агрегатных функций можно использовать и группирование по значениям полей. Для этого после условия (или после раздела FROM, если условие отсутствует) указывается раздел GROUP BY. В этом разделе, после слов GROUP BY, указываются имена полей, по которым надо проводить группировку. Например, нам хочется получить выборку, состоящую из названия товара и числа фирм, этот товар предлагающий и максимальной цены на данный товар. Для этого выполним запрос
SELECT name, COUNT(*), MAX(price) FROM items GROUP BY name
Полученные результаты могли бы быть, например, такими:
кеды 2 3000.00 джинсы 4 46000.00 рога 1 999999.85
В списке выбираемых полей при использовании группирования могут указываться кроме агрегатных функций только те поля, по которым производится группировка. Да это и понятно - ведь одному значению поля из GROUP BY может соответсвовать несколько записей и непонятно, какое значение несгруппированного поля использовать в результирующей выборке.
Можно наложить дополнительное условие на группирование данных с помощью ключевого слова HAVING, указываемого после раздела GROUP BY. В разделе HAVING указываются условие на группу, то есть группы, не удовлетворяющие условию, будут отсутствовать в результирующей выборке. Например, мы хотим выполнить предыдущий запрос, но нам не нужна информация о товарах, поставляемых только одним поставщиком. Для этого построим следующий запрос:
SELECT name, COUNT(*), MAX(price) FROM items GROUP BY name HAVING COUNT(*) > 1
и получим следующие результаты:
кеды 2 3000.00 джинсы 4 46000.00
