Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Gosy_nepolnostyu_7v1.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
3.7 Mб
Скачать

(Http://professorweb.Ru/my/csharp/charp_theory/level12/12_1.Php)

Раздел 2 базы данных

РАЗДЕЛ 2 БАЗЫ ДАННЫХ

1. Файловые формы хранения данных. Преимущества и недостатки

2. [DONE] Сетевые формы хранения данных. Преимущества и недостатки

3. Языки разметки как структуры хранения. Преимущества и недостатки

4. [DONE] Основные понятия реляционных БД и используемая терминология

5. Модель данных – определение, реализация в разных формах хранения.

6. [DONE] Многоуровневая архитектура БД. СУБД, ее назначение.

7. [DONE] Реляционные ключи – назначение, типы, примеры применения

8. [DONE] Оператор SELECT – формат, последовательность обработки

9. Теоретико-множественное описание и характеристические функции отношений. Аксиомы Армстронга

10. [DONE] Содержание процесса нормализации БД

11. [DONE] Содержательная трактовка первой нормальной формы БД

12. [DONE] Содержательная трактовка второй нормальной формы БД

13. Унарные операции реляционной алгебры

14. Бинарные операции реляционной алгебры

15. [DONE] Классификация и содержательный смысл различных операций соединения

16. [DONE]Особенности применения конструкций WHERE, ORDER BY, GROUP BY, HAVING и агрегирующих функций в языке SQL

17. [DONE] Подзапрос в языке SQL: типы, особенности применения

18. [DONE] Процедурные расширения языка SQL – курсоры, подпрограммы, триггеры.

19. [DONE] Механизм представлений в языке SQL

20. [DONE] Средства поддержки целостности данных в языке SQL

Рекомендую так же почитать про все нормальные формы.

1. Файловые формы хранения данных. Преимущества и недостатки

2. [DONE] Сетевые формы хранения данных. Преимущества и недостатки

Базы данных в концепции хранилища описываются с использованием метода «моделирование размерностей».

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

Каждая таблица размерностей имеет не составной(простой) первичный ключ, который точно соответствует одному из компонентов составного ключа в таблице фактов

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

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

В хранилищах данных практически никогда не происходит к единичным записям, базовая операция для них это агрегирование.

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

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

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

Схема снежинка — вариант схемы звезда, в которой каждая размерность может иметь своих собственные размерности.

Приимущество хранилищ данных:

1. Эффективность — единообразие структуры обеспечивает более эффективный доступ к данным, независимо от средств доступа.

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

3. Расширяемость — типичные изменения:

1. Добавление новых фактов, это можно делать при условии, что они имеют такую же степень детализации, как и таблица фактов.

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

3. Добавление новых атрибутов.

4. Разбиение существующих размерностей на записи с меньшим уровнем детализации, н начиная с определенного момента времени.

3. Языки разметки как структуры хранения. Преимущества и недостатки

4. [DONE] Основные понятия реляционных БД и используемая терминология

Данные — информация, имеющая стоимость.

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

Реляционная БД — это набор взаимосвязанных таблиц, содержащих всю необходимую для решения задачи информацию.

Однако таблицы реляционной БД — это не любые таблицы. На них накладываются определенные ограничения. Одним из главных ограничений является запрет на присутствие в таблице двух одинаковых строк, а точнее - строк, имеющих одинаковые первичные ключи.

Таблица 2.1. Отношение Студент.

ФИО Дата_рождения Курс Специальность

Иванов И.И. 01.09.83 3 история

Петров П.П. 09.12.84 2 физика

Сидоров С.С. 07.10.85 1 история

Соловьев С.С. 07.10.85 1 биология

Связь устанавливается между двумя общими полями (столбцами) двух таблиц. Существуют связи с отношением «один-к-одному», «один-ко-многим» и «многие-ко-многим».

A relational database is a digital database whose organization is based on the relational model of data, as proposed by E.F. Codd in 1970.[1] This model organizes data into one or more tables (or "relations") of rows and columns, with a unique key for each row. Generally, each entity type described in a database has its own table, the rows representing instances of that type of entity and the columns representing values attributed to that instance. Because each row in a table has its own unique key, rows in a table can be linked to rows in other tables by storing the unique key of the row to which it should be linked (where such unique key is known as a "foreign key"). Codd showed that data relationships of arbitrary complexity can be represented using this simple set of concepts.

Prior to the advent of this model, databases were usually hierarchical, and each tended to be organized with a unique mix of indexes, chains, and pointers. The simplicity of the relational model led to it soon becoming the predominant type of database.

The various software systems used to maintain relational databases are known as Relational Database Management Systems (RDBMS).

Virtually all relational database systems use SQL (Structured Query Language) as the language for querying and maintaining the database.

Основными понятиями реляционных баз данных являются:

тип данных — полностью эквивалентно понятию типа данных в языках программирования.

домен — допустимое потенциальное множество значений данного типа (ограничения). Следует отметить также семантическую нагрузку понятия домена: данные считаются сравнимыми только в том случае, когда они относятся к одному домену. Домен можно рассматривать как подмножество значений некоторого типа данных имеющих определенный смысл. Домен характеризуется следующими свойствами:

Домен имеет уникальное имя (в пределах базы данных)

Домен определен на некотором простом типе данных или на другом домене

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

Домен несет определенную смысловую нагрузку

атрибут — иногда говорят "столбец таблицы", имея в виду "атрибут отношения". Этой терминологии придерживаются в большинстве коммерческих реляционных СУБД.

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

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

отношение — это множество кортежей, соответствующих одной схеме отношения

5. Модель данных – определение, реализация в разных формах хранения.

Определение.

Модель данных есть формальная теория представления и обработки данных в системе управления базами данных (СУБД), которая включает, по меньшей мере, три аспекта:

1) аспект структуры: методы описания типов и логических структур данных в базе данных;

2) аспект манипуляции: методы манипулирования данными;

3) аспект целостности: методы описания и поддержки целостности базы данных.

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

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

Реализация в разных формах хранения.

6. [DONE] Многоуровневая архитектура БД. СУБД, ее назначение.

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

Концептуальный уровень архитектуры ANSI/SPARC служит для поддержки единого взгляда на базу данных, общего для всех её приложений и независимого от них и от среды хранения [6]. Концептуальный уровень представляет собой формализованную информационно-логическую модель ПО. Описание этого представления называется концептуальной схемой или схемой БД.

Схема базы данных – это описание базы данных в терминах конкретной модели данных.

Внутренний уровень архитектуры поддерживает представление данных в среде хранения и пути доступа к ним . На этом архитектурном уровне БД представлена в полностью "материализованном" виде, тогда как на других уровнях идёт работа на уровне отдельных экземпляров или множества экземпляров данных. Описание БД на внутреннем уровне называется внутренней схемой или схемой хранения.

Внешний уровень архитектуры БД предназначен для групп пользователей. Описание представления данных для группы пользователей называется внешней схемой. Наличие внешнего уровня позволяет поддерживать разное представление одних и тех же данных для различных групп пользователей или задач

Подсхема базы данных – это описание структуры данных прикладного программиста.

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

В архитектурной модели ANSI/SPARC предполагается наличие в СУБД механизмов, обеспечивающих междууровневое отображение данных "внешний – концептуальный" и "концептуальный – внутренний". Функциональные возможности этих механизмов определяют степень независимости данных на всех уровнях. На переходе "внешний – концептуальный" обеспечивается логическая независимость данных, на переходе "концептуальный – внутренний" – физическая независимость. Под логической независимостью подразумевается возможность вносить изменения в концептуальный уровень, не меняя представление БД для пользователей, или изменять представление данных для пользователей без изменения концептуальной схемы. Физическая независимость данных подразумевает возможность вносить изменения в схему хранения, не меняя концептуальную схему БД.

----------------------------------------------------------------------------------------------------------------

В основу работы Базы Данных(БД) в системе заложен принцип многоуровневой архитектуры, который заключается в реализации двух основных принципов:

минимизация функциональности клиентских компонентов, оставляющая за клиентом только функции пользовательского интерфейса; максимальное упрощение и унификация клиентского программного обеспечения;

освобождение сервера БД от несвойственных ему функций.

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

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

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

повышение производительности системы за счет переноса части функциональности на аппаратно выделенные сервера приложений;

повышение структурированности программных систем за счет реализации компонентов в виде независимых модулей (объектов), допускающих повторное использование; обеспечение возможности комплектации готовой системы из таких модулей;

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

хранилище данных (ХД) -- набор зарегистрированных баз данных, структура которых задана в системе регистрации данных;

базовые информационные структуры (БИС), объединение которых составляет содержание коллекций;

провайдер данных (ПД) -- приложение, обеспечивающее обработку унифицированных именованных запросов к коллекция и формирование ``внутреннего представления документа'' (ВПД);

обработчик ВПД -- формирует унифицированные именованные запросы к коллекции и отбор информации в ВПД;

формирование ``презентационного представления документа'' (ППД) в соответствии с выбранным стилем -- приложение, которое осуществляет визуализацию документа в удобном для пользователя виде, а также пользовательский интерфейс, с которого вводятся параметры запроса.

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

публикации данных, поддержка и их аутентичности и качества;

поиска и представления информации;

анализа распределенных данных.

поддержку интероперабельности в глобальной программно-аппаратной инфраструктуре;

поддержку диспетчеризации, включая идентификацию доступных ресурсов, статистика использования и загрузки ресурсов и пр.;

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

поддержку использования данных в удаленных архивах (включая протоколы, которые необходимо использовать для работы с гетерогенными источниками данных, и библиотеки программных комплексов) и др.

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

Должна адекватно отображать предметную область.

Должна удовлять требованиям пользователям, но не нарушать формальные правила.

СУБД — комплекс программных и языковых средств работы с БД.

[Другое определение] Совокупность языковых и программных средств, предназначенных для создания, ведения и совместного использования базы данных многими пользователями. Обычно СУБД различают по используемой модели данных. Так, например, СУБД, основанные на использовании реляционной модели данных, называют реляционными СУБД.

Основные функции СУБД

Непосредственное управление данными во внешней памяти — включает обеспечение необходимых структур внешней памяти как для хранения данных, непосредственно входящих в БД, так и для служебных целей

Управление буферами оперативной памяти — СУБД обычно работают с БД значительного размера; по крайней мере этот размер обычно существенно больше доступного объема оперативной памяти. Понятно, что если при обращении к любому элементу данных будет производиться обмен с внешней памятью, то вся система будет работать со скоростью устройства внешней памяти. Практически единственным способом реального увеличения этой скорости является буферизация данных в оперативной памяти. При этом, даже если операционная система производит общесистемную буферизацию (как в случае ОС UNIX), этого недостаточно для целей СУБД, которая располагает гораздо большей информацией о полезности буферизации той или иной части БД. Поэтому в развитых СУБД поддерживается собственный набор буферов оперативной памяти с собственной дисциплиной замены буферов.

Управление транзакциями — Транзакция - это последовательность операций над БД, рассматриваемых СУБД как единое целое. Либо транзакция успешно выполняется, и СУБД фиксирует (COMMIT) изменения БД, произведенные этой транзакцией, во внешней памяти, либо ни одно из этих изменений никак не отражается на состоянии БД. Понятие транзакции необходимо для поддержания логической целостности БД.

Журнализация — ведение логов оперций, производимых над данными. Журанлизация обеспечивает одно из основных требований к СУБД — надежность хранения данных во внешней памяти. Под надежностью хранения понимается то, что СУБД должна быть в состоянии восстановить последнее состояние БД после любого аппаратного или программного сбоя (аварийное выключение питания, аварийное завершение работы СУБД или аварийное завершение пользовательской программы). Понятно, что в любом случае для восстановления БД нужно располагать некоторой дополнительной информацией, которую и обеспечивает журнал. Журнал – это особая часть БД, недоступная пользователям и поддерживаемая с особой тщательностью (иногда поддерживаются две копии журнала, располагаемые на разных физических дисках), в которую поступают записи обо всех изменениях основной части БД. Изменения БД журнализуются следующим образом: запись в журнале соответствует некоторой операции изменения БД (например, операции удаления строки из таблицы реляционной БД). С помощью журнала можно решить все проблемы восстановления БД после любого сбоя.

Поддержка языков БД. СУБД включает язык определения данных, с помощью которого можно определить структуру базы, тип данных в ней, указать ограничения целостности (это язык, с помощью которого задаются различные имена, свойства объектов). Кроме того, СУБД позволяет вставлять, удалять, обновлять и извлекать информацию из базы данных посредством языка управления данными – языка запросов, который позволяет выполнять различные действия с данными, осуществлять их поиск и выборку. Он содержит набор различных операторов (заносить данные, удалять, модифицировать, выбирать и т.д.).

Процесс извлечения данных и их обработка скрыты от пользователя. Cтандартным языком наиболее распространенных в настоящее время СУБД является язык SQL (Structured Query Language). Он имеет сразу два компонента: язык определения данных и язык управления данными. Кроме того, одним из языков управления данными является язык QBE – язык запросов по образцу.

Обычно современная СУБД содержит следующие компоненты:

ядро, которое отвечает за управление данными во внешней и оперативной памяти и журнализацию,

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

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

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

Уровни СУБД

Внутренний уровень — то, как хранятся данные с точки зрения СУБД. Хранятся в виде хэш-таблиц и эти таблицы в виде сбалансированных дерьвьев (AVL tree - наиболее быстрое чтение, RBT - лучшая поддержка вставок/удаления).

Концептуальный уровень — уровень в терминах БД, который видит админ., но не видит конечный юзер (таблицы, связи). Юзеру не надо давать доступ ко всему.

Внешний уровень — уровень представления данных для конечного юзера (вью, таблицы).

Клиенты:

Толстый клиент — сам занимается обработкой визуализацией данных.

Тонкий клиент — только визуализация данных (обработка на стороне сервера).

2-х уровневая модель — клиент, СУБД

3-х уровневая медель — клиент, веб-сервер, СУБД.

7. [DONE] Реляционные ключи – назначение, типы, примеры применения

https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B2%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BB%D1%8E%D1%87

https://sites.google.com/site/gosyvmkss12/bazy-dannyh/17-ponatie-kluca-v-bazah-dannyh-pervicnye-i-vnesnie-kluci

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

Ключи можно разделить по признаку общности как:

· Простой[1] – сформирован из значений единственного поля, которые однозначно определяют каждую запись

· Составной – сформирован из значений нескольких полей, применяется

По способу возникновения:

· Естественный – основан на уже существующем поле. Например поле фамилия.

+Меньший обьем данных

- Изменяемый

- Не гарантируется уникальность

· Суррогатный – основан на добавленном искусственным путем отдельном поле для однозначной идентификации.

+ Неизменность

+ Гарантированная уникальность

+ Эффективность – намного эффективнее проводить выборку по 8-байтовым числам, чем по громоздким записям.

- Дополнительное поле => увеличение общего объема

· Интеллектуальный ключ – основан на естественном ключе путем добавления дополнительного поля. Например:

Ключ

Фамилия

Имя

Отчество

ТИА

Тихонов

Игорь

Алексеевич

Примеряется крайне редко и лишь для при необходимости добавления сокращенных кодов(напр. ТИА-0701)

По ограничению целостности данных:

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

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

Ключи.

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

Потенциальный ключ — в реляционной модели данных — подмножество атрибутов отношения, удовлетворяющее требованиям уникальности и минимальности (несократимости).

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

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

Поскольку все кортежи в отношении по определению уникальны, в нём всегда существует хотя бы один потенциальный ключ (например, включающий все атрибуты отношения).

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

Теоретически, все потенциальные ключи равно пригодны в качестве первичного ключа, на практике в качестве первичного обычно выбирается тот из потенциальных ключей, который имеет меньший размер (физического хранения) и/или включает меньшее количество атрибутов.

Первичный ключ – это одно или несколько полей (столбцов), комбинация значений которых однозначно определяет каждую запись в таблице. Первичный ключ не допускает значений Null и всегда должен иметь уникальный индекс. Первичный ключ используется для связывания таблицы с внешними ключами в других таблицах.

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

Потенциальный ключ — в реляционной модели данных — подмножество атрибутов отношения, удовлетворяющее требованиям уникальности и минимальности (несократимости).

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

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

Поскольку все кортежи в отношении по определению уникальны, в нём всегда существует хотя бы один потенциальный ключ (например, включающий все атрибуты отношения).

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

Теоретически, все потенциальные ключи равно пригодны в качестве первичного ключа, на практике в качестве первичного обычно выбирается тот из потенциальных ключей, который имеет меньший размер (физического хранения) и/или включает меньшее количество атрибутов.

8. [DONE] Оператор SELECT – формат, последовательность обработки

SELECT (англ., означает «выбрать») — оператор DML языка SQL, возвращающий набор данных (выборку) из базы данных, удовлетворяющих заданному условию.

В большинстве случаев, выборка осуществляется из одной или нескольких таблиц. В последнем случае говорят об операции слияния — JOIN. В тех СУБД, где реализованы представления (англ. view) и хранимые процедуры (англ. stored procedure), также возможно получение соответствующих наборов данных.

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

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

Особую роль играет обработка NULL-значений, когда при слиянии, например, двух таблиц — главной (англ. master) и подчинённой (англ. detail) — имеются или отсутствуют соответствия между записями таблиц, участвующих в слиянии. Для решения этой задачи используются механизмы внутреннего (англ. inner) и внешнего (англ. outer) слияния.

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

SELECT

[DISTINCT | DISTINCTROW | ALL]

select_expression,...

[FROM table_references]

[WHERE where_definition]

[GROUP BY {unsigned_integer | col_name | formula}

[HAVING where_definition]

[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]

Формат запроса с использованием данного оператора:

SELECT список полей FROM список таблиц WHERE условия…

WHERE — используется для определения, какие строки должны быть выбраны или включены в GROUP BY.

· GROUP BY — используется для объединения строк с общими значениями в элементы меньшего набора строк.

· HAVING — используется для определения, какие строки после GROUP BY должны быть выбраны.

· ORDER BY — используется для определения, какие столбцы используются для сортировки результирующего набора данных.

9. Теоретико-множественное описание и характеристические функции отношений. Аксиомы Армстронга

10. [DONE] Содержание процесса нормализации БД

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

Процесс преобразования отношений базы данных к виду, отвечающему нормальным формам, называется нормализацией. Нормализация предназначена для приведения структуры БД к виду, обеспечивающему минимальную логическую избыточность, и не имеет целью уменьшение или увеличение производительности работы или же уменьшение или увеличение физического объёма базы данных.[1] Конечной целью нормализации является уменьшение потенциальной противоречивости хранимой в базе данных информации. Как отмечает К. Дейт,[2] общее назначение процесса нормализации заключается в следующем:

исключение некоторых типов избыточности;

устранение некоторых аномалий обновления;

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

упрощение процедуры применения необходимых ограничений целостности.

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

При том, что идеи нормализации весьма полезны для проектирования баз данных, они отнюдь не являются универсальным или исчерпывающим средством повышения качества проекта БД. Это связано с тем, что существует слишком большое разнообразие возможных ошибок и недостатков в структуре БД, которые нормализацией не устраняются. Несмотря на эти рассуждения, теория нормализации является очень ценным достижением реляционной теории и практики, поскольку она даёт научно строгие и обоснованные критерии качества проекта БД и формальные методы для усовершенствования этого качества. Этим теория нормализации резко выделяется на фоне чисто эмпирических подходов к проектированию,[3] которые предлагаются в других моделях данных. Более того, можно утверждать, что во всей сфере информационных технологий практически отсутствуют методы оценки и улучшения проектных решений, сопоставимые с теорией нормализации реляционных баз данных по уровню формальной строгости.

Нормализация отношений (таблиц) — одна из основополагающих частей теории реляционных баз данных. Нормализация имеет своей целью избавиться от избыточности в отношениях и модифицировать их структуру таким образом, чтобы процесс работы с ними не был обременён различными посторонними сложностями. При игнорировании такого подхода эффективность проектирования стремительно снижается, что вкупе с прочими подобными вольностями может привести к критическим последствиям.

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

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

Используемые термины

Атрибут — свойство некоторой сущности. Часто называется полем таблицы.

Домен атрибута — множество допустимых значений, которые может принимать атрибут.

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

Отношение — конечное множество кортежей (таблица).

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

Проекция — отношение, полученное из заданного путём удаления и (или) перестановки некоторых атрибутов.

Функциональная зависимость между атрибутами (множествами атрибутов) X и Y означает, что для любого допустимого набора кортежей в данном отношении: если два кортежа совпадают по значению X, то они совпадают по значению Y. Например, если значение атрибута «Название компании» — Canonical Ltd, то значением атрибута «Штаб-квартира» в таком кортеже всегда будет Millbank Tower, London, United Kingdom. Обозначение: {X} -> {Y}.

11. [DONE] Содержательная трактовка первой нормальной формы БД

First normal form (1NF) is a property of a relation in a relational database. A relation is in first normal form if the domain of each attribute contains only atomic values, and the value of each attribute contains only a single value from that domain.[1]

Edgar Codd, in a 1971 conference paper, defined a relation in first normal form to be one such that none of the domains of that relation should have elements which are themselves sets.[2]

First normal form is an essential property of a relation in a relational database. Database normalization is the process of representing a database in terms of relations in standard normal forms, where first normal is a minimal requirement.

The following scenario illustrates how a database design might violate first normal form.[3][4]

Domains and values[edit]

Suppose a designer wishes to record the names and telephone numbers of customers. He defines a customer table which looks like this:

Customer ID

First Name

Surname

Telephone Number

123

Robert

Ingram

555-861-2025

456

Jane

Wright

555-403-1659

789

Maria

Fernandez

555-808-9633

The designer then becomes aware of a requirement to record multiple telephone numbers for some customers. He reasons that the simplest way of doing this is to allow the "Telephone Number" field in any given record to contain more than one value:

Customer ID

First Name

Surname

Telephone Number

123

Robert

Ingram

555-861-2025

456

Jane

Wright

555-403-1659

555-776-4100

789

Maria

Fernandez

555-808-9633

Assuming, however, that the Telephone Number column is defined on some telephone number-like domain, such as the domain of 12-character strings, the representation above is not in first normal form.

A design that complies with 1NF[edit]

In the first normal form, the previous table can be represented in the following way.

Customer ID

First Name

Surname

Telephone Number

123

Robert

Ingram

555-861-2025

456

Jane

Wright

555-403-1659

456

Jane

Wright

555-776-4100

789

Maria

Fernandez

555-808-9633

However, this database design does not meet the more stringent requirements of second normal form.[5]

A design that also complies with higher normal forms[edit]

Another design for the same data makes use of two tables: a Customer Name table and a Customer Telephone Number table.

Customer ID

First Name

Surname

123

Robert

Ingram

456

Jane

Wright

789

Maria

Fernandez

Customer ID

Telephone Number

123

555-861-2025

456

555-403-1659

456

555-776-4100

789

555-808-9633

1NF tables as representations of relations

This design is in first normal form. Indeed, repeating groups of telephone numbers do not occur in this design. Instead, each Customer-to-Telephone Number link appears on its own record. With Customer ID as key, a one-to-many relationship exists between the two tables. A record in the "parent" table, Customer Name, can have many telephone number records in the "child" table, Customer Telephone Number, but each telephone number belongs to one, and only one customer. It is worth noting that this design meets the additional requirements for second and third normal form.

According to Date's definition, a table is in first normal form if and only if it is "isomorphic to some relation", which means, specifically, that it satisfies the following five conditions:[12]

There's no top-to-bottom ordering to the rows.

There's no left-to-right ordering to the columns.

There are no duplicate rows.

Every row-and-column intersection contains exactly one value from the applicable domain (and nothing else).

All columns are regular [i.e. rows have no hidden components such as row IDs, object IDs, or hidden timestamps].

Violation of any of these conditions would mean that the table is not strictly relational, and therefore that it is not in first normal form.

Examples of tables (or views) that would not meet this definition of first normal form are:

A table that lacks a unique key. Such a table would be able to accommodate duplicate rows, in violation of condition 3.

A view whose definition mandates that results be returned in a particular order, so that the row-ordering is an intrinsic and meaningful aspect of the view.[13] This violates condition 1. The tuples in true relations are not ordered with respect to each other.

A table with at least one nullablhttps://en.wikipedia.org/wiki/Relational_modele attribute. A nullable attribute would be in violation of condition 4, which requires every field to contain exactly one value from its column's domain. It should be noted, however, that this aspect of condition 4 is controversial. It marks an important departure from Codd's later vision of the relational model,[14] which made explicit provision for nulls.[15]

12. [DONE] Содержательная трактовка второй нормальной формы БД

Переменная отношения находится во второй нормальной форме тогда и только тогда, когда она находится в первой нормальной форме и каждый неключевой атрибут неприводимо зависит от её потенциального ключа.[1]

Неприводимость означает, что в составе потенциального ключа отсутствует меньшее подмножество атрибутов, от которого можно также вывести данную функциональную зависимость.[1] Для неприводимой функциональной зависимости часто используется эквивалентное понятие «полная функциональная зависимость».[1]

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

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

Пример приведения отношения ко второй нормальной форме

Пусть в следующем отношении первичный ключ образует пара атрибутов {Сотрудник, Должность}:

Сотрудник

Должность

Зарплата

Наличие компьютера

Гришин

Кладовщик

20000

Нет

Васильев

Программист

40000

Есть

Иванов

Кладовщик

25000

Нет

Зарплату сотруднику каждый начальник устанавливает сам (хотя её границы зависят от должности). Наличие же компьютера у сотрудника зависит только от должности, то есть зависимость от первичного ключа неполная.

В результате приведения к 2NF исходное отношение следует декомпозировать на два отношения:

Сотрудник

Должность

Зарплата

Гришин

Кладовщик

20000

Васильев

Программист

40000

Иванов

Кладовщик

25000

Должность

Наличие компьютера

Кладовщик

Нет

Программист

Есть

13. Унарные операции реляционной алгебры

14. Бинарные операции реляционной алгебры

15. [DONE] Классификация и содержательный смысл различных операций соединения

JOIN — оператор языка SQL, который является реализацией операции соединения реляционной алгебры. Входит в раздел FROM операторов SELECT, UPDATE или DELETE.

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

в схему таблицы-результата входят столбцы обеих исходных таблиц (таблиц-операндов), то есть схема результата является «сцеплением» схем операндов;

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

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

При необходимости соединения не двух, а нескольких таблиц, операция соединения применяется несколько раз (последовательно).

Описание оператора

SELECT

field_name [,... n]

FROM

Table1

{INNER | {LEFT | RIGHT | FULL} OUTER | CROSS } JOIN

Table2

{ON <condition> | USING (field_name [,... n])}

В большинстве СУБД при указании слов LEFT, RIGHT, FULL слово OUTER можно опустить. Слово INNER также в большинстве СУБД можно опустить.

В общем случае СУБД при выполнении соединения проверяет условие (предикат) condition. Если названия столбцов по которым происходит соединение таблиц совпадают, то вместо ON можно использовать USING. Для CROSS JOIN условие не указывается.

Для перекрёстного соединения (декартова произведения) CROSS JOIN в некоторых реализациях SQL используется оператор «запятая» (,):

SELECT field_name [,... n] FROM Table1, Table2

Виды оператора JOIN

Для дальнейших пояснений будут использоваться следующие таблицы:

id

name

1

Москва

2

Санкт-Петербург

3

Казань

name

Cityid

Андрей

1

Леонид

2

Сергей

1

Григорий

4

INNER JOIN

Оператор внутреннего соединения INNER JOIN соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Каждая строка одной таблицы сопоставляется с каждой строкой второй таблицы, после чего для полученной «соединённой» строки проверяется условие соединения (вычисляется предикат соединения). Если условие истинно, в таблицу-результат добавляется соответствующая «соединённая» строка.

Описанный алгоритм действий является строго логическим, то есть он лишь объясняет результат, который должен получиться при выполнении операции, но не предписывает, чтобы конкретная СУБД выполняла соединение именно указанным образом. Существует множество способов реализации операции соединения, например, соединение вложенными циклами (англ. inner loops join), соединение хэшированием (англ. hash join), соединение слиянием (англ. merge join). Единственное требование состоит в том, чтобы любая реализация логически давала такой же результат, как при применении описанного алгоритма.

SELECT * FROM Person INNER JOIN City ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Леонид

2

2

Санкт-Петербург

Сергей

1

1

Москва

OUTER JOIN

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

LEFT OUTER JOIN

Оператор левого внешнего соединения LEFT OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p.

В результат включается внутреннее соединение (INNER JOIN) левой и правой таблиц по предикату p.

Затем в результат добавляются те записи левой таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие правой таблице, заполняются значениями NULL.

SELECT * FROM Person LEFT OUTER JOIN City ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Леонид

2

2

Санкт-Петербург

Сергей

1

1

Москва

Григорий

4

NULL

NULL

RIGHT OUTER JOIN

Оператор правого внешнего соединения RIGHT OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора важен, поскольку оператор не является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение левой и правой таблиц по предикату (условию) p.

В результат включается внутреннее соединение (INNER JOIN) левой и правой таблиц по предикату p.

Затем в результат добавляются те записи правой таблицы, которые не вошли во внутреннее соединение на шаге 1. Для таких записей поля, соответствующие левой таблице, заполняются значениями NULL.

SELECT * FROM Person RIGHT OUTER JOIN City ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Сергей

1

1

Москва

Леонид

2

2

Санкт-Петербург

NULL

NULL

3

Казань

FULL OUTER JOIN

Оператор полного внешнего соединения FULL OUTER JOIN соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку операттоор является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Пусть выполняется соединение первой и второй таблиц по предикату (условию) p. Слова «первой» и «второй» здесь не обозначают порядок в записи (который неважен), а используются лишь для различения таблиц.

В результат включается внутреннее соединение (INNER JOIN) первой и второй таблиц по предикату p.

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

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

SELECT * FROM Person FULL OUTER JOIN City ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Сергей

1

1

Москва

Леонид

2

2

Санкт-Петербург

NULL

NULL

3

Казань

Григорий

4

NULL

NULL

CROSS JOIN

Оператор перекрёстного соединения, или декартова произведения CROSS JOIN соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является симметричным.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

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

SELECT * FROM Person CROSS JOIN City

или

SELECT * FROM Person, City

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Андрей

1

2

Санкт-Петербург

Андрей

1

3

Казань

Леонид

2

1

Москва

Леонид

2

2

Санкт-Петербург

Леонид

2

3

Казань

Сергей

1

1

Москва

Сергей

1

2

Санкт-Петербург

Сергей

1

3

Казань

Григорий

4

1

Москва

Григорий

4

2

Санкт-Петербург

Григорий

4

3

Казань

Если в предложении WHERE добавить условие соединения (предикат p), то есть ограничения на сочетания кортежей, то результат эквивалентен операции INNER JOIN с таким же условием:

SELECT *

FROM

Person,

City

WHERE

Person.CityId = City.Id

Таким образом, t1 CROSS JOIN t2 WHERE p и t1 INNER JOIN t2 ON p синтаксически являются альтернативными формами записи одной и той же логической операции внутреннего соединения по предикату p. Синтаксис CROSS JOIN + WHERE для операции соединения называют устаревшим, его не рекомендует стандарт SQL ANSI[1][2].

16. [DONE]Особенности применения конструкций WHERE, ORDER BY, GROUP BY, HAVING и агрегирующих функций в языке SQL

WHERE — оператор в SQL, указывающий, что оператор языка управления данными (DML) должен действовать только на записи, удовлетворяющие определенным критериям. Критерии должны быть описаны в форме предикатов. Раздел WHERE — не обязательный раздел в SQL (DML) предложениях. Он используется в качестве условия в SQL-запросе для ограничения записей обрабатываемых в выражениях SQL (DML) или возвращаемых запросом.

WHERE is an SQL reserved word.

The WHERE clause is used in conjunction with SQL DML statements, and takes the following general form:

SQL-DML-Statement

FROM TABLE_NAME

WHERE predicate

all rows for which the predicate in the WHERE clause is True are affected (or returned) by the SQL DML statement or query. Rows for which the predicate evaluates to False or Unknown (NULL) are unaffected by the DML statement or query.

The following query returns only those rows from table mytable where the value in column mycol is greater than 100.

SELECT *

FROM mytable

WHERE mycol > 100

The following DELETE statement removes only those rows from table mytable where the column mycol is either NULL or has a value that is equal to 100.

DELETE

FROM mytable

WHERE mycol IS NULL OR mycol = 100

ORDER BY — необязательный (опциональный) параметр операторов SELECT и UNION, который означает что операторы SELECT, UNION возвращают набор строк, отсортированных по значениям одного или более столбцов. Его можно применять как к числовым столбцам, так и к строковым. В последнем случае, сортировка будет происходить по алфавиту.

Использование предложения ORDER BY является единственным способом отсортировать результирующий набор строк. Без этого предложения СУБД может вернуть строки в любом порядке. Если упорядочение необходимо, ORDER BY должен присутствовать в SELECT, UNION.

Сортировка может производиться как по возрастанию, так и по убыванию значений.

Параметр ASC (по умолчанию) устанавливает порядок сортирования во возрастанию, от меньших значений к большим.

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

SELECT * FROM Employees

ORDER BY LastName, FirstName

GROUP BY - необязательный (опциональный) параметр операторa SELECT, для группировки строк по результатам агрегатных функций (MAX, SUM, AVG, …).

Необходимо, чтобы в SELECT были заданы только требуемые в выходном потоке столбцы, перечисленные в GROUP BY и/или агрегированные значения. Распространённая ошибка — указание в SELECT столбца, пропущенного в GROUP BY.

SELECT Partner, SUM(SaleAmount) FROM Sales

WHERE SaleDate > '01-Jan-2000'

GROUP BY Partner

HAVING — необязательный (опциональный) параметр оператора SELECT для указания условия на результат агрегатных функций (MAX, SUM, AVG, …).

HAVING <условия> аналогичен WHERE <условия> за исключением того, что строки отбираются не по значениям столбцов, а строятся из значений столбцов, указанных в GROUP BY, и значений агрегатных функций, вычисленных для каждой группы, образованной GROUP BY.

Необходимо, чтобы в SELECT были заданы только требуемые в выходном потоке столбцы, перечисленные в GROUP BY и/или агрегированные значения. Распространённая ошибка — указание в SELECT столбца, пропущенного в GROUP BY.

Если параметр GROUP BY в SELECT не задан, HAVING применяется к «группе» всех строк таблицы, полностью дублируя WHERE (допускается не во всех реализациях стандарта SQL).

Примеры[править | править вики-текст]

Возвращает список идентификаторов отделов, продажи которых превысили 1000 долларов за 1 января 2000 года, вместе с суммами продаж за этот день:

SELECT DeptID, SUM(SaleAmount) FROM Sales

WHERE SaleDate = '01-Jan-2000'

GROUP BY DeptID

HAVING SUM(SaleAmount) > 1000

Следующий запрос вернет список отделов, в которых работает более одного сотрудника:

SELECT DepartmentName, COUNT(*)

FROM employee, department

WHERE employee.DepartmentID = department.DepartmentID

GROUP BY DepartmentName

HAVING COUNT(*) > 1;

AVG() - Returns the average value.

COUNT() - Returns the number of rows.

FIRST() - Returns the first value.

LAST() - Returns the last value.

MAX() - Returns the largest value.

MIN() - Returns the smallest value.

SUM() - Returns the sum.

17. [DONE] Подзапрос в языке SQL: типы, особенности применения

В лекции обсуждаются вопросы построения и применения подзапросов при извлечении и изменении данных.

Подзапросы

Язык SQL разрешает использовать в других операторах языка DML подзапросы, которые являются внутренними запросами, определяемыми оператором SELECT.

Подзапрос - очень мощное средство языка SQL. Он позволяет строить сложные иерархии запросов, многократно выполняемые в процессе построения результирующего набора или выполнения одного из операторов изменения данных (DELETE, INSERT, UPDATE).

Условно подзапросы иногда подразделяют на три типа, каждый из которых является сужением предыдущего:

табличный подзапрос, возвращающий набор строк и столбцов;

подзапрос строки, возвращающий только одну строку, но, возможно, несколько столбцов (такие подзапросы часто используются во встроенном SQL);

скалярный подзапрос, возвращающий значение одного столбца в одной строке.

Подзапрос позволяет решать следующие задачи:

определять набор строк, добавляемый в таблицу на одно выполнение оператора INSERT;

определять данные, включаемые в представление, создаваемое оператором CREATE VIEW ;

определять значения, модифицируемые оператором UPDATE;

указывать одно или несколько значений во фразах WHERE и HAVING оператора SELECT;

определять во фразе FROM таблицу как результат выполнения подзапроса;

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

Hекоторые СУБД (например, СУБД Oracle) позволяют на основе подзапроса создавать новые таблицы с помощью оператора CREATE TABLE.

Простым примером использования подзапроса может служить следующий оператор:

SELECT * from tbl1

WHERE f2=(SELECT f2 FROM tbl2

WHERE f1=1);

В данном операторе подзапрос всегда должен возвращать единственное значение, которое будет проверяться в предикате. Если подзапрос вернет более одного значения, то СУБД выдаст сообщение об ошибке выполнения SQL-оператора.

В случае если подзапрос не выберет ни одной строки, то предикат будет равен UNKNOWN, что большинством СУБД интерпретируется как FALSE.

Стандарт определяет запись предиката в форме "значение оператор подзапрос". Однако некоторые СУБД также позволяют записывать предикат в форме, указывающей подзапрос слева от оператора сравнения.

Например:

SELECT * from tbl1 WHERE

(SELECT f2 FROM tbl2 WHERE f1=1) = f2;

Очень часто с подзапросами используются агрегирующие функции, предоставляющие возможность сформулировать условие типа "больше, чем среднее по группе".

Например:

SELECT f1,f2,f3 FROM tbl1

WHERE f2> (SELECT AVG(f2) FROM tbl1);

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

Например:

SELECT * from tbl1 WHERE

f2 IN (SELECT f2 FROM tbl2 WHERE f1=1);

В этом случае предикат принимает значение TRUE, если хотя бы одно из значений, возвращаемых подзапросом, удовлетворяет условию.

Однако применение оператора IN имеет и некоторые смысловые недостатки: в запросе четко не определяется, сколько строк должны быть результатом выполнения запроса. При построении отношений для реальной модели данных это может приводить к некоторой неоднозначности и зависимости от самих данных. В противном случае, если модель данных предполагает в качестве постоянного результата подзапроса наличие только одной строки и, соответственно, использует оператор сравнения =, а структура данных позволяет ввод значений, когда в результате подзапроса будет более одной строки, то при использовании такого SQL-оператора в какой-то момент времени может проявиться ошибка.

Если в запросе участвуют более двух таблиц, то для большей наглядности имена полей иногда квалифицируют именами таблиц, указывая их через точку. Стандарт позволяет не квалифицировать имя поля именем таблицы в том случае, если не возникает неоднозначности (поле сначала ищется в таблице, указанной фразой FROM текущего запроса, затем внешнего запроса и т.д.).

Очень часто вместо записи оператора SELECT с использованием подзапроса можно применять соединения. Однако на практике большинство СУБД подзапросы выполняют более эффективно. Тем не менее, при проектировании комплекса программ с критичными требованиями по быстродействию, разработчик должен проанализировать план выполнения SQL-оператора для конкретной СУБД.

Наиболее продвинутые СУБД, такие как Oracle, предоставляют ряд SQL-операторов, позволяющих оценить производительность выполнения конкретного оператора языка SQL, а также определить уровень оптимизации, применяемый для данного оператора.

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

Например:

SELECT avg_f1, COUNT (f2) from tbl1

GROUP BY avg_f1

HAVING avg_f1 >(SELECT f1 FROM tbl1

WHERE f3='a1');

Коррелированные подзапросы

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

Например:

SELECT * from tbl1 t1

WHERE f2 IN (SELECT f2 FROM tbl2 t2

WHERE t1.f3=t2.f3);

В данном случае для каждой строки таблицы tbl1 будет проверяться условие, что значение поля f2 совпадает со значением строки таблицы tbl2, где значение поля f3 равно значению поля f3 внешней таблицы (tbl1). Это простейший пример коррелированного подзапроса.

Очень часто требуется, чтобы подзапрос использовал те же данные, что и внешняя таблица. В этом случае обязательно применение алиасов.

Например:

SELECT * from tbl1 t_out

WHERE f2< (SELECT AVG(f2) FROM tbl1 t_in

WHERE t_out.f1= t_in.f1);

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

Например:

SELECT f1, COUNT(*), SUM(f2) from tbl1 t1

GROUP BY f1

HAVING SUM(f2)> (SELECT MIN(f2)*4

FROM tbl1 t1_in

WHERE t1.f1=t1_in.f1);

Построение предиката для подзапроса, возвращающего несколько строк

Если в предикате надо сравнить значение с некоторым множеством, то, как было показано выше, можно использовать оператор IN.

Для того чтобы проверить, существуют ли строки, удовлетворяющие конкретному условию подзапроса, применяется оператор EXISTS.

Например:

SELECT f1,f2,f3 from tbl1

WHERE EXISTS (SELECT * FROM tbl1

WHERE f4='10/11/2003');

Этот запрос будет формировать не пустой результирующий набор только в том случае, если в какое-либо значение столбца f4 таблицы была занесена дата, например: '10/11/2003'.

Преимущество применения оператора EXISTS с результатами подзапроса состоит в том, что подзапрос может возвращать как множество строк, так и множество столбцов.

При коррелированном подзапросе оператор EXISTS будет вычисляться каждый раз для каждой строки внешнего запроса.

В стандарте SQL-92 не предусмотрено использование в подзапросах, к которым применяется оператор EXISTS агрегирующих функций. Однако некоторые СУБД позволяют такой вид подзапросов.

Для использования результата подзапроса в предикате также применяются операторы ANY и ALL, которые были подробно рассмотрены в предыдущих лекциях.

Приведем пример использования оператора ANY:

SELECT f1,f2,f3 from tbl1

WHERE f3 = ANY (SELECT f3 FROM tbl2);

Данный оператор определяет, что в результирующий набор будут включены все строки, значение столбца f3 которых присутствует в таблице tbl2.

Применение подзапросов в операторах изменения данных

К операторам языка DML, кроме оператора SELECT, относятся операторы, позволяющие изменять данные в таблицах. Это оператор INSERT, выполняющий добавление одной или нескольких строк в таблицу, оператор DELETE, удаляющий из таблицы одну или несколько строк, и оператор UPDATE, изменяющий значения столбцов таблицы.

Оператор INSERT

Оператор INSERT в стандарте SQL-92 имеет следующее формальное описание:

INSERT INTO table_name

[ (field .,:) ]

{ VALUES (value .,:) }

| subquery

| {DEFAULT VALUES};

Оператор INSERT может добавлять в таблицу как одну, так и несколько строк. Список полей (field .,:) указывает имена полей и порядок занесения в них значений из списка значений, определяемого фразой VALUES, или как результат выполнения подзапроса.

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

Если список полей (field .,:) опущен, то порядок занесения значений будет соответствовать порядку столбцов, указанному в операторе CREATE TABLE при создании данной таблицы.

Если для столбцов, на которые установлено ограничение NOT NULL, не указано добавляемых данных, то СУБД инициирует ошибку выполнения SQL-оператора.

Следующий оператор INSERT демонстрирует копирование строк таблицы tbl2, выполняемое на основе подзапроса:

INSERT INTO tbl1(f1,f2,f3)

(SELECT f1,f2,f3 FROM tbl2);

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

Оператор DELETE

Оператор DELETE в стандарте SQL-92 имеет следующее формальное описание:

DELETE FROM table_name

[ { WHERE condition }

| { WHERE CURRENT OF cursor_name } ];

Оператор DELETE используется для удаления из таблицы строк, указанных условием во фразе WHERE (поисковое удаление, searched deletion) или WHERE CURRENT OF (позиционное удаление, positioned deletion).

Позиционное удаление, определяемое фразой WHERE CURRENT OF, удаляя строки из курсора, соответственно удаляет их и из той таблицы базы данных, на базе которой был построен этот курсор.

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

Никогда нельзя забывать, что если фраза WHERE будет отсутствовать или предикат во фразе WHERE будет всегда принимать значение TRUE, то оператор DELETE удалит из таблицы все строки.

Оператор UPDATE

Оператор UPDATE в стандарте SQL-92 имеет следующее формальное описание:

UPDATE table_name

SET { field =

{ expr | NULL | DEFAULT }} .,

[ { WHERE condition }

| { WHERE CURRENT OF cursor_name } ];

Оператор UPDATE применяется для внесения изменений в данные таблиц.

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

При вычислении значений столбцов можно применять условное выражение CASE и выражение CAST для приведения типов.

Например:

SELECT f1, CAST (f2 AS CHAR),

CAST (f3 AS CHAR) from tbl1;

UPDATE tbl2 SET f2 = (SELECT CAST (f2 AS CHAR)

from tbl1 WHERE f1=1);

UPDATE tbl2 SET f5 = (SELECT CAST (f5 AS DATE)

from tbl1 WHERE f1=1),

f6= CAST ('10/12/2003' AS DATE);

Условное выражение CASE

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

Условное выражение CASE имеет следующее формальное описание:

{ CASE

{ expr WHEN expr THEN { expr | NULL }}

| { WHEN expr THEN { expr | NULL }}

[ ELSE { expr | NULL } ]

END}

| { NULLIF {expr1,expr2) }

| {COALESCE (expr .,:) }

Условное выражение CASE может быть записано, соответственно, в четырех формах:

CASE с выражениями. Например:

SELECT f1, CASE f3

WHEN 'abc' THEN '1_abc' END FROM tbl1;

CASE с предикатами. Например:

SELECT f1, CASE

WHEN f3= 'abc' THEN '1_abc'

ELSE f3 END FROM tbl1;

NULLIF - если выражения, указанные в скобках, не совпадают, то выбирается первое из этих значений, в противном случае устанавливается значение NULL. Например:

UPDATE tbl2 SET f3 = (SELECT NULLIF (f3,'aaa')

FROM tbl1 WHERE f1=1);

COALESCE - выбирается первое значение в списке, не равное NULL. Например:

INSERT INTO tbl1(f1,f2)

VALUES (1+ COALESCE(SELECT MAX(f1)

FROM tbl1, 0 ), 100);

Для успешного выполнения оператора UPDATE требуется ряд условий, включающий следующие:

наличие соответствующих привилегий;

для представления требуется определение его как изменяемого;

при изменении представлений применяются ограничения WITH CHECK OPTION или WITH CASCADED CHECK OPTION, установленные при создании этого представления;

в транзакциях "только чтение" изменение доступно только для временных таблиц;

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

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

в курсоре с фразой ORDER BY нельзя выполнять изменение столбцов, указанных в этой фразе.

18. [DONE] Процедурные расширения языка SQL – курсоры, подпрограммы, триггеры.

Cursor

In computer science, a database cursor is a control structure that enables traversal over the records in a database. Cursors facilitate subsequent processing in conjunction with the traversal, such as retrieval, addition and removal of database records. The database cursor characteristic of traversal makes cursors akin to the programming language concept of iterator.

Cursors are used by database programmers to process individual rows returned by database system queries. Cursors enable manipulation of whole result sets at once. In this scenario, a cursor enables the rows in a result set to be processed sequentially.

In SQL procedures, a cursor makes it possible to define a result set (a set of data rows) and perform complex logic on a row by row basis. By using the same mechanics, an SQL procedure can also define a result set and return it directly to the caller of the SQL procedure or to a client application.

A cursor can be viewed as a pointer to one row in a set of rows. The cursor can only reference one row at a time, but can move to other rows of the result set as needed.

Операции выборки SQL работают с наборами строк, которые называются результирующие множества. Все возвращаемые строки являются строками, соответствующими примененному SQL-оператору, их может быть ноль или больше. При использовании простых операторов SELECT невозможно получить первую строку, последнюю строку или предыдущие 10 строк. Это объясняется особенностями функционирования реляционной СУБД.

Иногда бывает необходимо просмотреть строки в прямом или обратном направлении один или несколько раз. Именно для этого используются курсоры. Курсор представляет собой запрос к базе данных, хранящийся на сервере СУБД, — это не оператор SELECT, но результирующее множество, выборка, полученная в результате действия оператора SELECT. После того как курсор сохранен, приложения могут "прокручивать" (просматривать) данные в прямом или обратном направлении, как только возникает такая потребность.

Работу с курсором можно разделить на несколько четко выраженных стадий.

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

Связывание с переменной (слипается с предыдущим)— Воспользуйтесь инструкцией DECLARE CURSOR, чтобы связать курсор языка Transact-SQL с инструкцией SELECT. Инструкция DECLARE CURSOR определяет также характеристики курсора, например имя курсора и тип курсора (read-only или forward-only).

Открытие — Воспользуйтесь инструкцией OPEN для выполнения инструкции SELECT и заполнения курсора.

Использование — Воспользуйтесь инструкцией FETCH INTO для выборки отдельных строк и перемещения данных для каждого столбца в указанную переменную. После этого другие инструкции языка Transact-SQL могут ссылаться на эти переменные для доступа к выбранным значениям данных. Курсоры языка Transact-SQL не поддерживают выборку группы строк.

Закрытие + высвобождение — После завершения работы с курсором примените инструкцию CLOSE. Закрытие курсора освобождает некоторые ресурсы, например результирующий набор курсора и его блокировки на текущей строке, однако структура курсора будет доступна для обработки, если снова выполнить инструкцию OPEN. Поскольку курсор все еще существует на этом этапе, повторно использовать его имя не удастся. Инструкция DEALLOCATE полностью освобождает все ресурсы, выделенные курсору, в том числе имя курсора. После освобождения курсора его необходимо перестроить заново с помощью инструкции DECLARE.

Курсоры создаются с помощью оператора DECLARE, синтаксис которого различен для разных СУБД. Оператор DECLARE дает курсору имя и принимает оператор SELECT, дополненный при необходимости предложением WHERE и другими. Чтобы показать, как это работает, мы создадим курсор, который будет делать выборку всех клиентов, не имеющих адресов электронной почты, в виде части приложения, позволяющего служащему вводить недостающие адреса.

DECLARE CustCursor CURSOR

FOR

SELECT * FROM Customers

WHERE cust_email IS NULL;

В обеих версиях для определения имени курсора используется оператор DECLARE — в данном случае это будет имя CustCursor. Оператор SELECT определяет курсор, содержащий имена всех клиентов, которые не имеют адреса электронной почты (соответствующее значение равно NULL).

Теперь, после того как курсор определен, его можно открыть.

Курсоры открываются с помощью оператора OPEN CURSOR.

При обработке оператора OPEN CURSOR выполняется запрос, и выборка данных сохраняется для последующих просмотра и прокрутки.

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

После использования курсоров их нужно закрывать. Кроме того, в некоторых СУБД (таких как SQL Server) требуется, чтобы ресурсы, занятые курсором, были освобождены явным образом

CLOSE CustCursor

Для закрытия курсора используется оператор CLOSE; после того как курсор закрыт, его нельзя использовать, не открыв перед этим вновь. Однако его не нужно объявлять заново при повторном использовании, достаточно оператора OPEN.

Храни́мая процеду́ра — объект базы данных, представляющий собой набор SQL-инструкций, который компилируется один раз и хранится на сервере. Хранимые процедуры очень похожи на обыкновенные процедуры языков высокого уровня, у них могут быть входные и выходные параметры и локальные переменные, в них могут производиться числовые вычисления и операции над символьными данными, результаты которых могут присваиваться переменным и параметрам. В хранимых процедурах могут выполняться стандартные операции с базами данных (как DDL, так и DML). Кроме того, в хранимых процедурах возможны циклы и ветвления, то есть в них могут использоваться инструкции управления процессом исполнения.

Хранимые процедуры похожи на определяемые пользователем функции (UDF). Основное различие заключается в том, что пользовательские функции можно использовать как и любое другое выражение в SQL запросе, в то время как хранимые процедуры должны быть вызваны с помощью функции CALL:

CALL процедура(…)

или

EXECUTE процедура(…)

Хранимые процедуры могут возвращать множества результатов, то есть результаты запроса SELECT. Такие множества результатов могут обрабатываться, используя курсоры, другими сохраненными процедурами, возвращая указатель результирующего множества, либо же приложениями. Хранимые процедуры могут также содержать объявленные переменные для обработки данных и курсоров, которые позволяют организовать цикл по нескольким строкам в таблице. Стандарт SQL предоставляет для работы выражения IF, LOOP, REPEAT, CASE и многие другие. Хранимые процедуры могут принимать переменные, возвращать результаты или изменять переменные и возвращать их, в зависимости от того, где переменная объявлена.

Реализация хранимых процедур варьируется от одной СУБД к другой. Большинство крупных поставщиков баз данных поддерживают их в той или иной форме. В зависимости от СУБД, хранимые процедуры могут быть реализованы на различных языках программирования, таких, как SQL, Java, C или C++. Хранимые процедуры написанные не на SQL могут самостоятельно выполнять SQL-запросы, а могут и не выполнять. Все более широкое использование хранимых процедур привело к появлению процедурных элементов в языке SQL стандарта SQL:1999 и SQL: 2003 в части SQL/PSM. Это сделало SQL императивным языком программирования. Большинство СУБД предлагают собственные проприетарные и расширения производителя, сверх SQL/PSM.

Назначение и преимущества хранимых процедур

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

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

Кроме собственно выполнения запроса, хранимые процедуры позволяют также производить вычисления и манипуляцию данными — изменение, удаление, выполнять DDL-операторы (не во всех СУБД!) и вызывать другие хранимые процедуры, выполнять сложную транзакционную логику. Один-единственный оператор позволяет вызвать сложный сценарий, который содержится в хранимой процедуре, что позволяет избежать пересылки через сеть сотен команд и, в особенности, необходимости передачи больших объёмов данных с клиента на сервер.

В большинстве СУБД при первом запуске хранимой процедуры она компилируется (выполняется синтаксический анализ и генерируется план доступа к данным). В дальнейшем её обработка осуществляется быстрее. В СУБД Oracle выполняется интерпретация хранимого процедурного кода, сохраняемого в словаре данных. Начиная с версии Oracle 10g поддерживается так называемая естественная компиляция (native compilation) хранимого процедурного кода в Си и затем в машинный кодцелевой машины, после чего при вызове хранимой процедуры происходит прямое выполнение её скомпилированного объектного кода.

Возможности программирования[править | править вики-текст]

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

Для упрощения тестирования, независимости бизнес-логики приложений от СУБД существует подход, в котором СУБД выступает лишь в роли хранилища, с минимальным количеством хранимых процедур или полном отказе от них. При этом используется отображение программных сущностей бизнес-логики на хранилище. См. ORM (англ. Object-relational mapping, рус. Объектно-реляционное отображение)

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

Использование хранимых процедур позволяет ограничить или вообще исключить непосредственный доступ пользователей к таблицам базы данных, оставив пользователям только разрешения на выполнение хранимых процедур, обеспечивающих косвенный и строго регламентированный доступ к данным. Кроме того, некоторые СУБД поддерживают шифрование текста (wrapping) хранимой процедуры.

Эти функции безопасности позволяют изолировать от пользователя структуру базы данных, что обеспечивает целостность и надежность базы.

Снижается вероятность таких действий как «внедрение SQL-кода», поскольку хорошо написанные хранимые процедуры дополнительно проверяют входные параметры перед тем, как передать запрос СУБД.

Stored Procedures in PostgreSQL

Usually stored procedures do not return any value, or return one or more result sets.

No Value Returned

If a stored procedure does not return any value, you can specify void as the return type:

-- Procedure to insert a new city

CREATE OR REPLACE FUNCTION add_city(city VARCHAR(70), state CHAR(2))

RETURNS void AS $$

BEGIN

INSERT INTO cities VALUES (city, state);

END;

$$ LANGUAGE plpgsql;

You can use SELECT statement to invoke the add_city procedure:

-- Add a new city

SELECT add_city('St.Louis', 'MO');

You can also use PERFORM add_city() statement to invoke add_city from another procedure or function.

Return a Single Result Set - Return a Cursor

To return a result set from a PostgreSQL procedure, you have to specify refcursor return type, open and return a cursor:

CREATE OR REPLACE FUNCTION show_cities() RETURNS refcursor AS $$

DECLARE

ref refcursor;

BEGIN

OPEN ref FOR SELECT city, state FROM cities;

RETURN ref;

END;

$$ LANGUAGE plpgsql;

Important Note: The cursor remains open until the end of transaction, and since PostgreSQL works in auto-commit mode by default, the cursor is closed immediately after the procedure call, so it is not available to the caller. To work with cursors you have to start a transaction (turn auto-commit off).

A database trigger is procedural code that is automatically executed in response to certain events on a particular table or view in a database. The trigger is mostly used for maintaining the integrity of the information on the database. For example, when a new record (representing a new worker) is added to the employees table, new records should also be created in the tables of the taxes, vacations and salaries.

Триггер — это особая разновидность хранимой процедуры, выполняемая автоматически при возникновении события на сервере базы данных. Триггеры языка обработки данных выполняются по событиям, вызванным попыткой пользователя изменить данные с помощью языка обработки данных. Событиями DML являются процедуры INSERT, UPDATE или DELETE, применяемые к таблице или представлению.

FOR | AFTER

Тип AFTER указывает, что триггер DML срабатывает только после успешного выполнения всех операций в инструкции SQL, запускаемой триггером. Все каскадные действия и проверки ограничений, на которые имеется ссылка, должны быть успешно завершены, прежде чем триггер сработает.

Если единственным заданным ключевым словом является FOR, аргумент AFTER используется по умолчанию.

INSTEAD OF

Указывает, что триггер DML срабатывает вместо инструкции SQL, используемой триггером, переопределяя таким образом действия выполняемой инструкции триггера.

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

команда INSERT – в таблице inserted содержатся все строки, которые пользователь пытается вставить в таблицу; в таблице deleted не будет ни одной строки; после завершения триггера все строки из таблицы inserted переместятся в исходную таблицу;

команда DELETE – в таблице deleted будут содержаться все строки, которые пользователь попытается удалить; триггер может проверить каждую строку и определить, разрешено ли ее удаление; в таблице inserted не окажется ни одной строки;

команда UPDATE – при ее выполнении в таблице deleted находятся старые значения строк, которые будут удалены при успешном завершении триггера. Новые значения строк содержатся в таблице inserted. Эти строки добавятся в исходную таблицу после успешного выполнения триггера.

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

Если Триггер обнаружил, что из 100 вставляемых, изменяемых или удаляемых строк только одна не удовлетворяет тем или иным условиям, то никакая строка не будет вставлена, изменена или удалена. Такое поведение обусловлено требованиями транзакции – должны быть выполнены либо все модификации, либо ни одной. Триггер выполняется как неявно определенная транзакция, поэтому внутри триггера допускается применение команд управления транзакциями. В частности, при обнаружении нарушения ограничений целостности для прерывания выполнения триггера и отмены всех изменений, которые пытался выполнить пользователь, необходимо использовать команду ROLLBACK TRANSACTION.

Нельзя:

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

2. Триггер не может использовать инструкции, которые явно или неявно начинают или заканчивают транзакцию, типа START TRANSACTION, COMMIT или ROLLBACK.

3. Вы не можете связывать триггер с VIEW или таблицей TEMPORARY.

4. Ключевые слова OLD и NEW дают возможность обратиться к столбцам в строках, на которые воздействует триггер. OLD и NEW не чувствительны к регистру. В триггере INSERT может использоваться только NEW.col_name : не имеется никакой старой строки. В триггере DELETE не ожидается никакой новой строки, так что может использоваться исключительно OLD.col_name. В триггере UPDATE Вы можете использовать OLD.col_name, чтобы обратиться к столбцам строки прежде, чем они изменятся, и NEW.col_name , чтобы обратиться к ним уже после внесения изменений.

5. Тригер не может возвращать результат, т.е. например выводить SELECT.

6. Нельзя привязать к одной таблице два триггера с одинаковым временем и типом события.

Типы триггеров:

Триггеры DML — Триггеры DML часто используются для применения бизнес-правил и обеспечения целостности данных. В SQL Server декларативное ограничение ссылочной целостности обеспечивается инструкциями ALTER TABLE и CREATE TABLE. Однако декларативное ограничение ссылочной целостности не обеспечивает ссылочную целостность между базами данных. Ограничение ссылочной целостности подразумевает выполнение правил связи между первичными и внешними ключами таблиц. Для обеспечения ограничений ссылочной целостности используйте в инструкциях ALTER TABLE и CREATE TABLE ограничения PRIMARY KEY и FOREIGN KEY. Если ограничения распространяются на таблицу триггера, они проверяются после срабатывания триггера INSTEAD OF и до выполнения триггера AFTER. В случае нарушения ограничения выполняется откат действий триггера INSTEAD OF, и триггер AFTER не срабатывает.

Триггеры DDL — как и стандартные триггеры, выполняют хранимые процедуры в ответ на какое-либо событие. В отличие от стандартных триггеров, они не срабатывают в ответ на выполнение инструкций UPDATE, INSERT или DELETE по отношению к таблице или представлению. Вместо этого триггеры срабатывают в первую очередь в ответ на инструкции языка определения данных (DDL). Это инструкции CREATE, ALTER, DROP, GRANT, DENY, REVOKE и UPDATE STATISTICS. Системные хранимые процедуры, выполняющие операции, подобные операциям DDL, также могут запускать триггеры DDL.

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

Trigger on an INSERT, UPDATE, or DELETE statement to a table or view (DML Trigger)

CREATE TRIGGER [ schema_name . ]trigger_name

ON { table | view }

[ WITH <dml_trigger_option> [ ,...n ] ]

{ FOR | AFTER | INSTEAD OF }

{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }

[ NOT FOR REPLICATION ]

AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > }

<dml_trigger_option> ::=

[ ENCRYPTION ]

[ EXECUTE AS Clause ]

<method_specifier> ::=

assembly_name.class_name.method_name

Trigger on a CREATE, ALTER, DROP, GRANT, DENY, REVOKE, or UPDATE STATISTICS statement (DDL Trigger)

CREATE TRIGGER trigger_name

ON { ALL SERVER | DATABASE }

[ WITH <ddl_trigger_option> [ ,...n ] ]

{ FOR | AFTER } { event_type | event_group } [ ,...n ]

AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier > [ ; ] }

<ddl_trigger_option> ::=

[ ENCRYPTION ]

[ EXECUTE AS Clause ]

Trigger on a LOGON event (Logon Trigger)

CREATE TRIGGER trigger_name

ON ALL SERVER

[ WITH <logon_trigger_option> [ ,...n ] ]

{ FOR| AFTER } LOGON

AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier > [ ; ] }

<logon_trigger_option> ::=

[ ENCRYPTION ]

[ EXECUTE AS Clause ]

Пример (dml):

CREATE TRIGGER reminder2

ON Sales.Customer

AFTER INSERT, UPDATE, DELETE

AS

EXEC msdb.dbo.sp_send_dbmail

@profile_name = 'AdventureWorks2012 Administrator',

@recipients = 'danw@Adventure-Works.com',

@body = 'Don''t forget to print a report for the sales force.',

@subject = 'Reminder';

19. [DONE] Механизм представлений в языке SQL

In database theory, a view is the result set of a stored query on the data, which the database users can query just as they would in a persistent database collection object. This pre-established query command is kept in the database dictionary. Unlike ordinary base tables in a relational database, a view does not form part of the physical schema: as a result set, it is a virtual table computed or collated dynamically from data in the database when access to that view is requested. Changes applied to the data in a relevantunderlying table are reflected in the data shown in subsequent invocations of the view. In some NoSQL databases, views are the only way to query data.

Views can provide advantages over tables:

Views can represent a subset of the data contained in a table. Consequently, a view can limit the degree of exposure of the underlying tables to the outer world: a given user may have permission to query the view, while denied access to the rest of the base table.

Views can join and simplify multiple tables into a single virtual table.

Views can act as aggregated tables, where the database engine aggregates data (sum, average, etc.) and presents the calculated results as part of the data.

Views can hide the complexity of data. For example, a view could appear as Sales2000 or Sales2001, transparently partitioning the actual underlying table.

Views take very little space to store; the database contains only the definition of a view, not a copy of all the data that it presents.

Depending on the SQL engine used, views can provide extra security.

Just as a function (in programming) can provide abstraction, so can a database view. In another parallel with functions, database users can manipulate nested views, thus one view can aggregate data from other views. Without the use of views, the normalization of databases above second normal form would become much more difficult. Views can make it easier to create lossless join decomposition.

Just as rows in a base table lack any defined ordering, rows available through a view do not appear with any default sorting. A view is a relational table, and the relational model defines a table as a set of rows. Since sets are not ordered — by definition — neither are the rows of a view. Therefore, an ORDER BY clause in the view definition is meaningless; the SQL standard (SQL:2003) does not allow an ORDER BY clause in the subquery of a CREATE VIEW command, just as it is refused in a CREATE TABLE statement. However, sorted data can be obtained from a view, in the same way as any other table — as part of a query statement on that view. Nevertheless, some DBMS (such as Oracle Database) do not abide by this SQL standard restriction.

Read-only vs. updatable views[edit]

Database practitioners can define views as read-only or updatable. If the database system can determine the reverse mapping from the view schema to the schema of the underlying base tables, then the view is updatable. INSERT, UPDATE, and DELETEoperations can be performed on updatable views. Read-only views do not support such operations because the DBMS cannot map the changes to the underlying base tables. A view update is done by key preservation.

Some systems support the definition of INSTEAD OF triggers on views. This technique allows the definition of other logic for execution in place of an insert, update, or delete operation on the views. Thus database systems can implement data modifications based on read-only views. However, an INSTEAD OF trigger does not change the read-only or updatable property of the view itself.

Advanced view features[edit]

Various database management systems have extended the views from read-only subsets of data.

Oracle Database introduced the concept of materialized views: pre-executed, non-virtual views commonly used in data warehousing. They give a static snapshot of the data and may include data from remote sources. The accuracy of a materialized view depends on the frequency of trigger mechanisms behind its updates. IBM DB2 provides so-called "materialized query tables" (MQTs) for the same purpose. Microsoft SQL Server introduced in its 2000 version indexed views which only store a separate index from the table, but not the entire data. PostgreSQL implemented materialized views in its 9.3 release.

Equivalence[edit]

A view is equivalent to its source query. When queries are run against views, the query is modified. For example, if there exists a view named accounts_view with the content as follows:

accounts_view:

-------------

SELECT name, money_received, money_sent, (money_received - money_sent) AS balance,address,

...

FROM table_customers c JOIN accounts_table a ON a.customer_id = c.customer_id

then the application could run a simple query such as:

Simple query

------------

SELECT name, balance FROM accounts_view

The RDBMS then takes the simple query, replaces the equivalent view, then sends the following to the query optimizer:

Preprocessed query:

------------------

SELECT name, balance

FROM (SELECT name,

money_received,

money_sent,

(money_received - money_sent) AS balance,

address,

...

FROM table_customers c JOIN accounts_table a

ON a.customer_id = c.customer_id )

The optimizer then removes unnecessary fields and complexity (for example: it is not necessary to read the address, since the parent invocation does not make use of it) and then sends the query to the SQL engine for processing.

20. [DONE] Средства поддержки целостности данных в языке SQL

Таблицы с ограничениями в стандарте языка

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

обязательные данные;

ограничения для доменов полей;

целостность сущностей;

ссылочная целостность;

требования конкретного предприятия.

Большая часть перечисленных ограничений задается в операторах CREATE TABLE и ALTER TABLE.

Создание таблицы

В стандарте SQL дано несколько вариантов определения оператора создания таблицы, однако его базовый формат имеет следующий вид:

<определение_таблицы> ::=

CREATE TABLE имя_таблицы

{(имя_столбца тип_данных [ NOT NULL ][ UNIQUE]

[DEFAULT <значение>]

[ CHECK (<условие_выбора>)][,...n]}

[CONSTRAINT имя_ограничения]

[PRIMARY KEY (имя_столбца [,...n])

{[UNIQUE (имя_столбца [,...n])}

[FOREIGN KEY (имя_столбца_внешнего_ключа

[,...n])

REFERENCES имя_род_таблицы

[(имя_столбца_род_таблицы [,...n])],

[MATCH {PARTIAL | FULL}

[ON UPDATE {CASCADE| SET NULL |SET DEFAULT

|NO ACTION}]

[ON DELETE {CASCADE| SET NULL |SET DEFAULT

|NO ACTION}]

{[CHECK(<условие_выбора>)][,...n]})

Ограничения

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

Обязательные данные

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

Требования конкретного предприятия

Обновления данных в таблицах могут быть ограничены существующими в организации требованиями (бизнес-правилами). Стандарт SQL позволяет реализовать бизнес-правила предприятий с помощью предложения CHECK и ключевого слова UNIQUE.

Ограничения для доменов полей

Каждый столбец имеет собственный домен - некоторый набор допустимых значений. Стандарт SQL предусматривает два различных механизма определения доменов. Первый состоит в использовании предложения CHECK, позволяющего задать требуемые ограничения для столбца или таблицы в целом, а второй предполагает применение оператора CREATE DOMAIN.

Целостность сущностей

Первичный ключ таблицы должен иметь уникальное непустое значение в каждой строке. Стандарт SQL позволяет задавать подобные требования поддержки целостности данных с помощью фразы PRIMARY KEY. В пределах таблицы она может указываться только один раз. Однако существует возможность гарантировать уникальность значений и для любых альтернативных ключей таблицы, что обеспечивает ключевое слово UNIQUE. Кроме того, при определении альтернативных ключей рекомендуется использовать и спецификаторы NOT NULL.

Ссылочная целостность

Внешние ключи представляют собой столбцы или наборы столбцов, предназначенные для связывания каждой из строк дочерней таблицы, содержащей этот внешний ключ, со строкой родительской таблицы, содержащей соответствующее значение потенциального ключа. Стандарт SQL предусматривает механизм определения внешних ключей с помощью предложения FOREIGN KEY, а фраза REFERENCES определяет имя родительской таблицы, т.е. таблицы, где находится соответствующий потенциальный ключ. При использовании этого предложения система отклонит выполнение любых операторов INSERT или UPDATE, с помощью которых будет предпринята попытка создать в дочерней таблице значение внешнего ключа, не соответствующее одному из уже существующих значений потенциального ключа родительской таблицы. Когда действия системы выполняются при поступлении операторов UPDATE и DELETE, содержащих попытку обновить или удалить значение потенциального ключа в родительской таблице, которому соответствует одна или более строк дочерней таблицы, то они зависят от правил поддержки ссылочной целостности, указанных во фразах ON UPDATE и ON DELETE предложения FOREIGN KEY. Если пользователь предпринимает попытку удалить из родительской таблицы строку, на которую ссылается одна или более строк дочерней таблицы, язык SQL предоставляет следующие возможности:

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

SET NULL - выполняется удаление строки из родительской таблицы, а во внешние ключи всех ссылающихся на нее строк дочерней таблицы записывается значение NULL;

SET DEFAULT - выполняется удаление строки из родительской таблицы, а во внешние ключи всех ссылающихся на нее строк дочерней таблицы заносится значение, принимаемое по умолчанию;

NO ACTION - операция удаления строки из родительской таблицы отменяется. Именно это значение используется по умолчанию в тех случаях, когда в описании внешнего ключа фраза ON DELETE опущена.

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

Определитель MATCH позволяет уточнить способ обработки значения NULL во внешнем ключе.

При определении таблицы предложение FOREIGN KEY может указываться произвольное количество раз.

В операторе CREATE TABLE используется необязательная фраза DEFAULT, которая предназначена для задания принимаемого по умолчанию значения, когда в операторе INSERT значение в данном столбце будет отсутствовать.

Фраза CONSTRAINT позволяет задать имя ограничению, что позволит впоследствии отменить то или иное ограничение с помощью оператора ALTER TABLE.

Изменение и удаление таблицы

Для внесения изменений в уже созданные таблицы стандартом SQL предусмотрен оператор ALTER TABLE, предназначенный для выполнения следующих действий:

добавление в таблицу нового столбца;

удаление столбца из таблицы;

добавление в определение таблицы нового ограничения;

удаление из определения таблицы существующего ограничения;

задание для столбца значения по умолчанию;

отмена для столбца значения по умолчанию.

Оператор изменения таблицы имеет следующий обобщенный формат:

<изменение_таблицы> ::=

ALTER TABLE имя_таблицы

[ADD [COLUMN]имя_столбца тип_данных

[ NOT NULL ][UNIQUE]

[DEFAULT <значение>][ CHECK (<условие_выбора>)]]

[DROP [COLUMN] имя_столбца [RESTRICT | CASCADE ]]

[ADD [CONSTRAINT [имя_ограничения]]

[{PRIMARY KEY (имя_столбца [,...n])

|[UNIQUE (имя_столбца [,...n])}

|[FOREIGN KEY (имя_столбца_внешнего_ключа [,...n])

REFERENCES имя_род_таблицы

[(имя_столбца_род_таблицы [,...n])],

[ MATCH {PARTIAL | FULL}

[ON UPDATE {CASCADE| SET NULL |

SET DEFAULT | NO ACTION}]

[ON DELETE {CASCADE| SET NULL |

SET DEFAULT | NO ACTION}]

|[CHECK(<условие_выбора>)][,...n]}]

[DROP CONSTRAINT имя_ограничения

[RESTRICT | CASCADE]]

[ALTER [COLUMN] SET DEFAULT <значение>]

[ALTER [COLUMN] DROP DEFAULT]

Здесь параметры имеют то же самое назначение, что и в определении оператора CREATE TABLE.

Оператор ALTER TABLE реализован не во всех диалектах языка SQL. В некоторых диалектах он поддерживается, однако не позволяет удалять из таблицы уже существующие столбцы.

Для удаления таблицы используется команда DROP TABLE.

Таблицы в среде MS SQL Server

Создание таблицы

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

Столбцы какого типа и размера будут составлять каждую из таблиц, какие требуется выбрать имена для столбцов таблиц?

Какие столбцы могут содержать значение NULL?

Будут ли использованы ограничения целостности, значения по умолчанию и правила для столбцов?

Необходимо ли индексирование столбцов, какие типы индексов будут применены для конкретных столбцов?

Какие столбцы будут входить в первичные и внешние ключи.

Для создания таблиц в среде MS SQL Server используется команда:

<определение_таблицы> ::=

CREATE TABLE [ имя_базы_данных.[владелец].

| владелец. ]имя_таблицы

(<элемент_таблицы>[,...n])

где

<элемент_таблицы> ::=

{<определение_столбца>}

| <имя_столбца> AS <выражение>

|>ограничение_таблицы<

Обычно владельцем таблицы (dbo) является тот, кто ее создал.

<Выражение> задает значение для вычисляемого столбца. Вычисляемые столбцы - это виртуальные столбцы, т. е. физически в таблице они не хранятся и вычисляются с использованием значений столбцов той же таблицы. В выражении для вычисляемого столбца могут присутствовать имена обычных столбцов, константы и функции, связанные одним или несколькими операторами. Подзапросы в таком выражении участвовать не могут.Вычисляемые столбцы могут быть включены в раздел SELECT при указании списка столбцов, которые должны быть возвращены в результате выполнения запроса. Вычисляемые столбцы не могут входить во внешний ключ, для них не используются значения по умолчанию. Кроме того, вычисляемые столбцы не могут участвовать в операциях INSERT и DELETE.

<определение_столбца> ::=

{ имя_столбца <тип_данных>}

[ [ DEFAULT <выражение> ]

| [ IDENTITY (начало, шаг) [NOT FOR REPLICATION]]]]

[ROWGUIDCOL][<ограничение_столбца>][...n]]

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

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

<ограничение_столбца>::=

[ CONSTRAINT имя_ограничения ]

{ [ NULL | NOT NULL ]

| [ {PRIMARY KEY | UNIQUE }

[ CLUSTERED | NONCLUSTERED ]

[ WITH FILLFACTOR=фактор_заполнения ]

[ ON {имя_группы_файлов | DEFAULT } ] ] ]

| [ [ FOREIGN KEY ]

REFERENCES имя_род_таблицы

[(имя_столбца_род_таблицы) ]

[ ON DELETE { CASCADE | NO ACTION } ]

[ ON UPDATE { CASCADE | NO ACTION } ]

[ NOT FOR REPLICATION ]]

| CHECK [ NOT FOR REPLICATION](<лог_выражение>) }

<ограничение_таблицы>::=

[CONSTRAINT имя_ограничения ]

{ [ {PRIMARY KEY | UNIQUE }

[ CLUSTERED | NONCLUSTERED ]

{(имя_столбца [ASC | DESC][,...n])}

[WITH FILLFACTOR=фактор_заполнения ]

[ON {имя_группы_файлов | DEFAULT } ]]

|FOREIGN KEY[(имя_столбца [,...n])]

REFERENCES имя_род_таблицы

[(имя_столбца_род_таблицы [,...n])]

[ ON DELETE { CASCADE | NO ACTION } ]

[ ON UPDATE { CASCADE | NO ACTION } ]

| NOT FOR REPLICATION ]

| CHECK [ NOT FOR REPLICATION ] (лог_выражение) }

Рассмотрим отдельные параметры представленных конструкций, связанные с ограничениями целостности данных. Ограничения целостности имеют приоритет над триггерами, правилами и значениями по умолчанию. Кограничениям целостности относятся ограничение первичного ключа PRIMARY KEY, ограничение внешнего ключа FOREIGN KEY, ограничение уникальности UNIQUE, ограничение значения NULL, ограничение на проверкуCHECK.

Ограничение первичного ключа (PRIMARY KEY)

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

При создании первичного ключа SQL Server автоматически создает уникальный индекс для столбцов, входящих в первичный ключ. Он ускоряет доступ к данным этих столбцов при использовании первичного ключа в запросах.

Таблица может иметь только одно ограничение PRIMARY KEY, причем ни один из включенных в первичный ключ столбцов не может принимать значение NULL. При попытке использовать в качестве первичного ключа столбец (или группу столбцов), для которого ограничения первичного ключа не выполняются, первичный ключ создан не будет, а система выдаст сообщение об ошибке.

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

Ограничение внешнего ключа (FOREIGN KEY)

Ограничение внешнего ключа - это основной механизм для поддержания ссылочной целостности между таблицами реляционной базы данных. Столбец дочерней таблицы, определенный в качестве внешнего ключа в параметре FOREIGN KEY, применяется для ссылки на столбец родительской таблицы, являющийся в ней первичным ключом. Имя родительской таблицы и столбцы ее первичного ключа указываются в предложенииREFERENCES. Данные в столбцах, определенных в качестве внешнего ключа, могут принимать только такие же значения, какие находятся в связанных с ним столбцах первичного ключа родительской таблицы. Совпадение имен столбцов для связи дочерней и родительской таблиц необязательно. Первичный ключ может быть определен для столбца с одним именем, в то время как столбец, на который наложено ограничение FOREIGN KEY, может иметь совершенно другое имя. Единственным требованием остается соответствие столбцов по типу и размеру данных.

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

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

Столбцы внешнего ключа могут содержать значение NULL, однако проверка на ограничение FOREIGN KEY игнорируется. Внешний ключ может быть проиндексирован, тогда сервер будет быстрее отыскивать нужные данные.Внешний ключ определяется как при создании, так и при изменении таблиц.

Ограничение ссылочной целостности задает требование, согласно которому для каждой записи в дочерней таблице должна иметься запись в родительской таблице. При этом изменение значения столбца связи в записи родительской таблицы при наличии дочерней записи блокируется, равно как и удаление родительской записи (запрет каскадного изменения и удаления), что гарантируется параметрами ON DELETE NO ACTION и ON UPDATE NO ACTION, принятыми по умолчанию. Для разрешения каскадного воздействия следует использовать параметры ON DELETE CASCADE и ON UPDATE CASCADE.

Ограничение уникального ключа (UNIQUE)

Это ограничение задает требование уникальности значения поля (столбца) или группы полей (столбцов), входящих в уникальный ключ, по отношению к другим записям. Ограничение UNIQUE для столбца таблицы похоже напервичный ключ: для каждой строки данных в нем должны содержаться уникальные значения. Установив для некоторого столбца ограничение первичного ключа, можно одновременно установить для другого столбца ограничение UNIQUE. Отличие в ограничении первичного и уникального ключа заключается в том, что первичный ключ служит как для упорядочения данных в таблице, так и для соединения связанных между собой таблиц. Кроме того, при использовании ограничения UNIQUE допускается существование значения NULL, но лишь единственный раз.

Ограничение на значение (NOT NULL)

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

Ограничение проверочное (CHECK) и правила

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

Ограничения целостности CHECK задают диапазон возможных значений для столбца или столбцов. В основе ограничений целостности CHECK лежит использование логических выражений.

Допускается применение нескольких ограничений CHECK к одному и тому же столбцу. В этом случае они будут применимы в той последовательности, в которой происходило их создание. Возможно применение одного и того же ограничения к разным столбцам и использование в логических выражениях значений других столбцов. Указание параметра NOT FOR REPLICATION предписывает не выполнять проверочных действий, если они выполняются подсистемой репликации.

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

Правило может быть создано командой:

CREATE RULE имя_правила AS выражение

Чтобы связать правило с тем или иным столбцом какой-либо таблицы, необходимо использовать системную хранимую процедуру:

sp_bindrule [@rulename=] 'rule'

[@objname=] 'object_name'

[,[@futureonly=['futureonly_flag']

Чтобы отменить правила, следует выполнить следующую процедуру:

sp_unbindrule [@objname=] 'object_name'

[,[@futureonly=['futureonly_flag']

Удаление правила производится командой

DROP RULE {имя_правила} [,...n].

Ограничение по умолчанию (DEFAULT)

Столбцу может быть присвоено значение по умолчанию. Оно будет актуальным в том случае, если пользователь не введет в столбец никакого иного значения.

Отдельно необходимо отметить пользу от использования значений по умолчанию при добавлении нового столбца в таблицу. Если для добавляемого столбца не разрешено хранение значений NULL и не определено значение по умолчанию, то операция добавления столбца закончится неудачей.

При определении в таблице столбца с параметром ROWGUIDCOL сервер автоматически определяет для него значение по умолчанию в виде функции NEWID(). Таким образом, для каждой новой строки будет автоматически генерироваться глобальный уникальный идентификатор.

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

CREATE DEFAULT имя_умолчания AS константа

Умолчание связывается с тем или иным столбцом какой-либо таблицы с помощью процедуры:

sp_bindefault [@defname=] 'default',

[@objname=] 'object_name'

[,[@futureonly=] 'futureonly_flag'],

где

'object_name'

может быть представлен как

'имя_таблицы.имя_столбца'

Удаление ограничения по умолчанию выполняется командой

DROP DEFAULT {имя_умолчания} [,...n]

если предварительно это ограничение было удалено из всех таблиц процедурой

sp_unbindefault [@objname=] 'object_name'

[,[@futureonly=] 'futureonly_flag']

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

Ключевые слова CLUSTERED и NONCLUSTERED позволяют создать для столбца кластерный или некластерный индекс. Для ограничения PRIMARY KEY по умолчанию создается кластерный индекс, а для ограничения UNIQUE -некластерный. В каждой таблице может быть создан лишь один кластерный индекс, отличительной особенностью которого является то, что в соответствии с ним изменяется физический порядок строк в таблице. ASC и DESCопределяют метод упорядочения данных в индексе.

С помощью параметра WITH FILLFACTOR=фактор_заполнения задается степень заполнения индексных страниц при создании индекса. Значение фактора заполнения указывается в процентах и может изменяться в промежутке от 0 до 100.

Параметр ON имя_группы_файлов обозначает группу, в которой предполагается хранить таблицу.

Изменение таблицы

Изменения в таблицу можно внести командой:

<изменение_таблицы> ::=

ALTER TABLE имя_таблицы

{[ALTER COLUMN имя_столбца

{ тип_данных [(точность[,масштаб])]

[ NULL | NOT NULL ]

| {ADD | DROP } ROWGUIDCOL }]

| ADD { [<определение_столбца>]

| имя_столбца AS выражение } [,...n]

| [WITH CHECK | WITH NOCHECK ]

ADD { <ограничение-таблицы> } [,...n]

| DROP

{ [CONSTRAINT ] имя_ограничения

| COLUMN имя_столбца}[,...n]

| {CHECK | NOCHECK } CONSTRAINT

{ALL | имя_ограничения[,...n]}

| {ENABLE | DISABLE } TRIGGER

{ALL | имя_триггера [,...n]}}

В дополнение к уже названным параметрам определим параметр {ENABLE | DISABLE } TRIGGER ALL_, предписывающий задействовать или отключить конкретный триггер или все триггера, связанные с таблицей.

Удаление таблицы

Удаление таблицы выполняется командой:

DROP TABLE имя_таблицы

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

CREATE TABLE Товар

(КодТовара INT IDENTITY(1,1) PRIMARY KEY,

Название VARCHAR(50) NOT NULL UNIQUE,

Цена MONEY NOT NULL,

Тип VARCHAR(50) NOT NULL,

Сорт VARCHAR(50) NOT NULL

CHECK(сорт in('первый','второй','третий')),

Город VARCHAR(50) NOT NULL,

Остаток INT

CHECK(остаток>=0))

Пример 9.1. Создание родительской таблицы Товар с ограничениями.

CREATE TABLE Клиент

(КодКлиента INT IDENTITY(1,1) PRIMARY KEY,

Фирма VARCHAR(50) NOT NULL,

Фамилия VARCHAR(50) NOT NULL,

Город VARCHAR(50) NOT NULL,

Телефон CHAR(10) NOT NULL

CHECK(Телефон LIKE

'[1-9][0-9]-[0-9][0-9]-[0-9][0-9]'))

Пример 9.2. Создание родительской таблицы Клиент с ограничениями.

CREATE TABLE Сделка

(КодСделки INT IDENTITY(1,1) PRIMARY KEY,

КодТовара INT NOT NULL,

КодКлиента INT NOT NULL,

Количество INT NOT NULL DEFAULT 0,

Дата DATETIME NOT NULL DEFAULT

GETDATE(),

CONSTRAINT fk_Товар

FOREIGN KEY(КодТовара) REFERENCES Товар,

CONSTRAINT fk_Клиент

FOREIGN KEY(КодКлиента) REFERENCES Клиент)

Пример 9.3. Создание дочерней таблицы Сделка с ограничениями.

CREATE TABLE Склад

(КодТовара INT PRIMARY KEY,

Остаток INT)

Пример 9.4. Создание таблицы Склад.

ALTER TABLE Сделка DROP CONSTRAINT fk_Товар

Пример 9.5. Удаление ограничения внешнего ключа.

ALTER TABLE Сделка ADD CONSTRAINT fk_Товар

FOREIGN KEY (КодТовара) REFERENCES товар

ON UPDATE NO ACTION ON DELETE NO ACTION

Пример 9.6. Добавление ограничения внешнего ключа, реализующего декларативную ссылочную целостность.

ALTER TABLE Сделка ADD CONSTRAINT fk_Товар

FOREIGN KEY (КодТовара) REFERENCES Товар

ON UPDATE CASCADE ON DELETE CASCADE

Пример 9.7. Добавления ограничения внешнего ключа, реализующего каскадные обновления и изменения.

ALTER TABLE Товар ADD Налог AS Цена*0.05

ALTER TABLE Товар DROP COLUMN Налог

Пример 9.8. Пример создания и удаления вычисляемого поля.

Пусть создана таблица без ограничений:

CREATE TABLE Товар

(КодТовара INT,

Название VARCHAR(20),

Тип VARCHAR(20),

Дата DATETIME,

Цена MONEY,

Остаток INT)

Рассмотрим примеры внесения в таблицу всевозможных ограничений.

Пример 9.9. Поле КодТовара необходимо сделать первичным ключом. Выполнение следующей команды будет отвергнуто, поскольку поле КодТовара допускает внесение значений NULL.

ALTER TABLE Товар ADD CONSTRAINT pk1

PRIMARY KEY(КодТовара)

Пример 9.9. Поле КодТовара необходимо сделать первичным ключом.

Сначала нужно изменить объявление столбца КодТовара, запретив внесение значений NULL:

ALTER TABLE Товар

ALTER COLUMN КодТовара INT NOT NULL

И только потом создать ограничение первичного ключа:

ALTER TABLE Товар ADD CONSTRAINT pk1

PRIMARY KEY(КодТовара)

Пример 9.10. Удалить столбец целого типа и добавить столбец-счетчик.

ALTER TABLE Товар DROP COLUMN КодТовара

ALTER TABLE Товар ADD

КодТовара INT IDENTITY(1,1)

Пример 9.10. Удаление столбца целого типа и добавление столбца-счетчика.

Пример 9.11. Добавить ограничение первичного ключа.

ALTER TABLE Товар ADD CONSTRAINT pk1

PRIMARY KEY(КодТовара)

Пример 9.11. Добавление ограничений первичного ключа.

Пример 9.12. Изменить столбец, добавив ограничение NOT NULL.

ALTER TABLE Товар ALTER COLUMN

Название VARCHAR(40) NOT NULL

Пример 9.12. Добавление ограничения NOT NULL.

Пример 9.13. Добавить ограничение уникальности значения.

ALTER TABLE Товар ADD CONSTRAINT

u1 UNIQUE(Название)

Пример 9.13. Добавление ограничения уникальности значения.

Пример 9.14. Создать умолчание и добавить умолчание столбцу.

CREATE DEFAULT df1 AS 0

sp_bindefault 'df1', 'Товар.Остаток'

CREATE DEFAULT df2 AS GETDATE()

sp_bindefault 'df2', 'Товар.Дата'

Пример 9.14. Создание и добавление умолчания столбцу.

Пример 9.15. Создать правило и добавить правило столбцу.

CREATE RULE r1 AS @m IN

('мебель','бытовая химия','косметика')

sp_bindrule 'r1','Товар.Тип'

Пример 9.15. Создание и добавление правила столбцу.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]