Язык SQL, история, базовые операторы.

Немного истории

Как уже говорилось, в 1970-х годах Эдгар Кодд предложил использовать реляционную модель. Помимо самой модели, он так же предложил язык для работы с данными в рамках этой модели, названный DSL/Alpha. Впоследствии, на основе DSL/Alpha появился язык SQUARE, а на его основе, в свою очередь, язык SEQUEL, который (ввиду некоторой путаницы в торговых марках) был переименован позже в SQL.

Первый стандарт ANSI1 языка SQL появился в 1986 году. Последующие версии выходили в 1989, 1992, 1999 и 2003 годах.

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

Последнее замечание. SQL исторически не является акронимом, хотя его нередко расшифровывают как Structured Query Language. Читается либо по буквам, либо как “sequel” (сиквел).

Декларативный язык SQL

Многие из вас знакомы с императивными языками программирования. SQL не является императивным языком, и сейчас его принято относить к декларативным. Другие декларативные языки – это, например, различные языки разметки, скажем, HTML или XML.

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

На SQL достаточно сложно писать “полные” программы – обычно требуется встраивать SQL-вызовы в какой-то императивный (или функциональный) язык.

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

  • создание в базе данных новой таблицы;
  • добавление в таблицу новых записей;
  • изменение записей;
  • удаление записей;
  • выборка записей из одной или нескольких таблиц (в соответствии с заданным условием);
  • изменение структур таблиц.

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

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

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

  • запросы на создание или изменение в базе данных новых или существующих объектов (при этом в запросе описывается тип и структура создаваемого или изменяемого объекта);
  • запросы на получение данных;
  • запросы на добавление новых данных (записей);
  • запросы на удаление данных;
  • обращения к СУБД.

В основном, все выражения SQL имеют следующий синтаксис:

ОПЕРАТОР аргументы ИНСТРУКЦИЯ аргументы;

Основным объектом хранения реляционной базы данных является таблица, поэтому все SQL-запросы — это операции над таблицами. В соответствии с этим, запросы делятся на:

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

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

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

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

  • вставка новой строки;
  • изменение значений полей строки или набора строк;
  • удаление строки или набора строк.

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

  • просмотреть полученный набор;
  • изменить все записи набора;
  • удалить все записи набора.

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

Язык SQL представляет собой совокупность

  • операторов,
  • инструкций,
  • и вычисляемых функций.

Преимущества и недостатки

Преимущества

Независимость от конкретной СУБД
Несмотря на наличие диалектов и различий в синтаксисе, в большинстве своём тексты SQL-запросов могут быть достаточно легко перенесены из одной СУБД в другую. Существуют системы, разработчики которых изначально ориентировались на применение по меньшей мере нескольких СУБД (например: система электронного документооборота Documentum может работать как с Oracle Database, так и с Microsoft SQL Server и DB2). Естественно, что при применении некоторых специфичных для реализации возможностей такой переносимости добиться уже очень трудно.
Наличие стандартов
Наличие стандартов и набора тестов для выявления совместимости и соответствия конкретной реализации SQL общепринятому стандарту только способствует «стабилизации» языка. Правда, стоит обратить внимание, что сам по себе стандарт местами чересчур формализован и раздут в размерах (например, базовая часть стандарта SQL:2003 состоит из более 1300 страниц текста).
Декларативность
С помощью SQL программист описывает только то, какие данные нужно извлечь или модифицировать. То, каким образом это сделать, решает СУБД непосредственно при обработке SQL-запроса. Однако не стоит думать, что это полностью универсальный принцип — программист описывает набор данных для выборки или модификации, однако ему при этом полезно представлять, как СУБД будет разбирать текст его запроса. Чем сложнее сконструирован запрос, тем больше он допускает вариантов написания, различных по скорости выполнения, но одинаковых по итоговому набору данных.

Недостатки

Несоответствие реляционной модели данных

Создатели реляционной модели данных Эдгар Кодд, Кристофер Дейт и их сторонники указывают на то, что SQL не является истинно реляционным языком. В частности, они указывают на следующие дефекты SQL с точки зрения реляционной теории:

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

В опубликованном Кристофером Дейтом и Хью Дарвеном Третьем манифесте они излагают принципы СУБД следующего поколения и предлагают язык Tutorial D, который является подлинно реляционным.

Сложность
Хотя SQL и задумывался как средство работы конечного пользователя, в конце концов он стал настолько сложным, что превратился в инструмент программиста.
Отступления от стандартов
Несмотря на наличие международного стандарта ANSI многие разработчики СУБД вносят изменения в язык SQL, применяемый в разрабатываемой СУБД, тем самым отступая от стандарта. Таким образом появляются специфичные для каждой конкретной СУБД диалекты языка SQL.

Основные операторы SQL

В SQL существует четыре больших группы операторов.

Операторы управления схемой данных

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

  • CREATE создает объект БД (саму базу, таблицу, представление, пользователя и т. д.),
  • ALTER изменяет объект,
  • DROP удаляет объект;
Операторы управления данными

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

  • SELECT считывает данные, удовлетворяющие заданным условиям,
  • INSERT добавляет новые данные,
  • UPDATE изменяет существующие данные,
  • DELETE удаляет данные;
Операторы управления СУБД

это операторы, позволяющие настраивать СУБД, управлять разрешениями, создавать пользователей, и т.п.

  • GRANT предоставляет пользователю (группе) разрешения на определенные операции с объектом,
  • REVOKE отзывает ранее выданные разрешения,
  • DENY задает запрет, имеющий приоритет над разрешением;
Операторы управления транзакциями

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

  • COMMIT применяет транзакцию,
  • ROLLBACK откатывает все изменения, сделанные в контексте текущей транзакции,
  • SAVEPOINT делит транзакцию на более мелкие участки.

Рассмотрим некоторые из них более подробно.

Операторы управления схемой данных

Операторы создания элементов схемы в общем называются CREATE.

Операторы создания

Создание базы данных

CREATE DATABASE db_name;

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

CREATE TABLE table_name
  (
    column_name_1 type1(size) constraint_1,
    column_name_2 type2(size) constraint_2,
    ...
    CONSTRAINT constraint_name_n constraint_n arguments,
    ...
    INDEX index_name_1 (columns...),
    ...
  );

Здесь constraint_* может иметь следующие значения (или их комбинации):

  • NOT NULL – не может быть “пустым”
  • UNIQUE – значение уникально
  • PRIMARY KEY – комбинация первых двух
  • FOREIGN KEY – указание внешнего ключа
  • CHECK – значение должно удовлетворять условию
  • DEFAULT – значение по умолчанию

Присутствуют некоторые разночтения в разных реализациях.

Если первичный ключ состоит из нескольких столбцов, необходимо выносить его после объявления столбцов в виде

CONSTRAINT pk_table PRIMARY KEY (col1, col2, ...)

где pk_table – уникальное название ограничения.

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

Внешний ключ в любом случае объявляется после объявления колонок.

Синтаксис:

CONSTRAINT fk_table FOREIGN KEY (col1, ...) REFERENCES tbl_name (ref_col1, ...) ON UPDATE upd_action ON DELETE del_action;

где fk_table – уникальное название ограничения, col1, ... – названия колонок данной таблицы, входящих во внешний ключ, tbl_name – таблица, для которой указанный внешний ключ является первичным, ref_col1, ... – названия соответствующих колонок в tbl_name. upd_action и del_action определяют, как БД реагирует на изменение и удаление записей из tbl_name, и могут принимать одно из значений:

  • SET NULL – ссылающиеся колонки col1, ... устанавливается в NULL
  • RESTRICT – если есть записи, ссылающиеся на обновляемое/удаляемое значение, обновление/удаление завершается ошибкой
  • CASCADE – обновляет/удаляет все ссылающиеся записи
  • NO ACTION – ничего не делать

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

Создание индекса

CREATE INDEX index_name ON table_name (column_name);
CREATE UNIQUE INDEX index_name ON table_name (column_name);

Индексы ускоряют выборку по индексированным колонкам, но замедляют добавление и удаление записей.

Операторы удаления

Операторы удаления элементов схемы в общем называются DROP.

Удаление базы данных

DROP DATABASE db_name;

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

DROP TABLE table_name;

Удаление индекса

DROP INDEX index_name ON table_name;

Операторы изменения

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

ALTER TABLE table_name COMMAND arguments;

Здесь COMMAND может быть одним из:

  • ADD COLUMN
  • ADD INDEX
  • ADD CONSTRAINT
  • ALTER COLUMN – позволяет указать или убрать значение по умолчанию
  • CHANGE COLUMN – позволяет переименовать, и изменить определение
  • MODIFY COLUMN – позволяет изменить определение
  • DROP COLUMN
  • DROP INDEX
  • DROP PRIMARY KEY
  • DROP FOREIGN KEY
  • RENAME
  • и т.д.

Операторы управления данными

Операторы выборки

Общее название SELECT

Выборка всех данных

SELECT * FROM table_name;

Выборка колонок

SELECT column_1, column_2 FROM table_name;

Выборка по условию

SELECT ... FROM table_name WHERE condition;

Выборка только уникальных записей

SELECT DISTINCT ... FROM table_name ...;

Операторы вставки

Общее название INSERT.

Вставка в таблицу

INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2,...);

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

Операторы удаления

DELETE FROM table_name WHERE condition;

Операторы изменения

UPDATE table_name SET column_1=value_1, column_2=value_2, ... WHERE condition;

  1. American National Standards Institute↩︎