SQL Основы

SQL Дополнительно

Оптимизация SQL-запросов

Постреляционные базы данных

SQL Injection

Яндекс.Метрика

SQL Основы

SQL - это язык для работы с базами данных; Он включает создание, удаление, выбор строк, изменение строк и т. Д. SQL является стандартным языком ANSI (Американский национальный институт стандартов), но существует много разных версий языка SQL.

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

SQL является стандартным языком для системы реляционной базы данных. Все системы управления реляционными базами данных (RDMS), такие как MySQL, MS Access, Oracle, Sybase, Informix, Postgres и SQL Server, используют SQL в качестве стандартного языка баз данных.

Кроме того, они используют разные диалекты, такие как -

MS SQL Server с использованием T-SQL,
Oracle использует PL / SQL,
Версия MS Access SQL называется JET SQL (собственный формат) и т. Д.
Почему SQL?
SQL широко популярен, поскольку он предлагает следующие преимущества:

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

Позволяет пользователям описывать данные.

Позволяет пользователям определять данные в базе данных и манипулировать этими данными.

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

Позволяет пользователям создавать и удалять базы данных и таблицы.

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

Позволяет пользователям устанавливать разрешения для таблиц, процедур и представлений.

Краткая история SQL
1970 - д-р Эдгар Ф. «Тед» Кодд IBM известен как отец реляционных баз данных. Он описал реляционную модель для баз данных.

1974 г. Появился язык структурированного запроса.

1978 - IBM работала над разработкой идей Codd и выпустила продукт под названием System / R.

1986 - IBM разработала первый прототип реляционной базы данных и стандартизирована ANSI. Первая реляционная база данных была выпущена Relational Software, которая позже стала известна как Oracle.

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

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

Этими компонентами являются:

Диспетчер запросов
Двигатели оптимизации
Классический движок запросов
SQL Query Engine и т. Д.
Классический механизм запросов обрабатывает все запросы, отличные от SQL, но механизм запросов SQL не обрабатывает логические файлы.

Ниже приведена простая диаграмма, показывающая архитектуру SQL -

Архитектура SQL
Команды SQL
Стандартными командами SQL для взаимодействия с реляционными базами данных являются CREATE, SELECT, INSERT, UPDATE, DELETE и DROP. Эти команды можно классифицировать по следующим группам в зависимости от их природы -


DDL - язык определения данных
Sr.No. Команда и описание
1 CREATE Создает новую таблицу, представление таблицы или другой объект в базе данных.
2 ALTER Изменяет существующий объект базы данных, например таблицу.
3 DROP Удаляет всю таблицу, представление таблицы или других объектов в базе данных.

DML - язык манипулирования данными
Sr.No. Команда и описание
1 SELECT Извлекает определенные записи из одной или нескольких таблиц.
2 INSERT Создает запись.
3 UPDATE Изменяет записи.
4 DELETE Удаляет записи.

DCL - Язык управления данными
Sr.No. Команда и описание
1 GRANT Предоставляет пользователю привилегию.
2 REVOKE Возвращает привилегии, предоставленные пользователю.
Что такое RDBMS? RDBMS означает систему управления реляционными базами данных. RDBMS является основой для SQL и для всех современных систем баз данных, таких как MS SQL Server, IBM DB2, Oracle, MySQL и Microsoft Access. Система управления реляционными базами данных (СУБД) представляет собой систему управления базами данных (СУБД), которая основана на реляционной модели, введенной Е. Ф. Коддом. Что такое таблица? Данные в СУБД хранятся в объектах базы данных, которые называются таблицами. Эта таблица в основном представляет собой набор связанных записей данных и состоит из множества столбцов и строк. Помните, что таблица является наиболее распространенной и простой формой хранения данных в реляционной базе данных. Следующая программа представляет собой пример таблицы CUSTOMERS - +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Андрей | 32 | Москва | 1000.00 | | 2 | Николай | 25 | Новосибирск | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | | 4 | Анджелеса | 25 | Урал | 3500.00 | | 5 | Анатолий | 27 | Казахстан | 8500.00 | | 6 | Люда | 22 | MP | 4500.00 | | 7 | Нина | 24 | Алжир | 30000.00 | +----+----------+-----+-----------+----------+ Что такое поле? Каждая таблица разбивается на более мелкие объекты, называемые полями. Поля в таблице CUSTOMERS состоят из ID, NAME, AGE, ADDRESS и SALARY. Поле представляет собой столбец в таблице, который предназначен для поддержки конкретной информации о каждой записи в таблице. Что такое запись или строка? Запись также вызывается как строка данных - каждая отдельная запись, которая существует в таблице. Например, в приведенной выше таблице КЛИЕНТОВ имеется 7 записей. Ниже приведена одна строка данных или записей в таблице CUSTOMERS +----+----------+-----+-----------+----------+ | 1 | Андрей | 32 | Москва | 2000.00 | +----+----------+-----+-----------+----------+ Запись представляет собой горизонтальную сущность в таблице. Что такое столбец? Столбец представляет собой вертикальный объект в таблице, который содержит всю информацию, связанную с определенным полем в таблице. Например, столбец в таблице CUSTOMERS является NAME , который представляет описание местоположения и будет выглядеть следующим образом +-----------+ | NAME | +-----------+ | Андрей | | Николай | | kaushik | | Анджелеса | | Анатолий | | Люда | | Нина | +----+------+ Что такое значение NULL? Значение NULL в таблице - это значение в поле, которое кажется пустым, что означает, что поле со значением NULL является полем без значения. Очень важно понять, что значение NULL отличается от нулевого значения или поля, содержащего пробелы. Поле со значением NULL является тем, которое осталось пустым во время создания записи. Ограничения SQL Ограничения - это правила, применяемые к столбцам данных таблицы. Они используются для ограничения типа данных, которые могут входить в таблицу. Это обеспечивает точность и надежность данных в базе данных. Ограничения могут быть либо уровнем столбца, либо уровнем таблицы. Ограничения уровня столбца применяются только к одному столбцу, тогда как ограничения уровня таблицы применяются ко всей таблице. Ниже приведены некоторые из наиболее часто используемых ограничений, доступных в SQL - NOT NULL Constraint - гарантирует, что столбец не может иметь значение NULL. DEFAULT Constraint - задает значение по умолчанию для столбца, если ни один не указан. UNIQUE Constraint - Обеспечивает, чтобы все значения в столбце были разными. PRIMARY Key - уникальная идентификация каждой строки / записи в таблице базы данных. FOREIGN Key - уникально идентифицирует строку / запись в любой другой таблице базы данных. CHECK Constraint - ограничение CHECK гарантирует, что все значения в столбце удовлетворяют определенным условиям. INDEX - используется для быстрого и быстрого создания данных из базы данных. Целостность данных Для каждой СУБД существуют следующие категории целостности данных: Целостность сущности - в таблице нет повторяющихся строк. Integrity домена - принудительно вводит допустимые записи для данного столбца, ограничивая тип, формат или диапазон значений. Ссылочная целостность - строки не могут быть удалены, которые используются другими записями. User-Defined Integrity - обеспечивает определенные бизнес-правила, которые не попадают в сущность, домен или ссылочную целостность. Нормализация базы данных Нормализация базы данных - это процесс эффективной организации данных в базе данных. Есть две причины этого процесса нормализации - Устранение избыточных данных, например, хранение одних и тех же данных в нескольких таблицах. Обеспечение взаимозависимости данных имеет смысл. Обе эти причины являются достойными целями, поскольку они уменьшают объем пространства, потребляемого базой данных, и гарантируют, что данные будут логически сохранены. Нормализация состоит из ряда рекомендаций, которые помогут вам создать хорошую структуру базы данных. Руководящие принципы нормализации делятся на нормальные формы; Подумайте о форме как формате или способе формирования структуры базы данных. Цель нормальных форм - организовать структуру базы данных, чтобы она соответствовала правилам первой нормальной формы, затем второй нормальной форме и, наконец, третьей нормальной форме. Это ваш выбор, чтобы принять его дальше и перейти к четвертой нормальной форме, пятой нормальной форме и т. Д., Но в общем случае третьей нормальной формы более чем достаточно. Первая нормальная форма (1NF) Первая нормальная форма (1NF) устанавливает основные правила для организованной базы данных - Определите требуемые элементы данных, поскольку они становятся столбцами в таблице. Поместите соответствующие элементы данных в таблицу. Убедитесь, что нет повторяющихся групп данных. Убедитесь, что имеется первичный ключ. Первое правило 1NF Вы должны определить элементы данных. Это означает просмотр данных, которые нужно сохранить, организацию данных в столбцы, определение типов данных, которые содержит каждый столбец, а затем, наконец, размещение соответствующих столбцов в их собственной таблице. Например, вы помещаете все столбцы, относящиеся к местоположениям собраний в таблице Location, а также те, которые относятся к членам в таблице MemberDetails и так далее. Второе правило 1NF Следующим шагом является обеспечение отсутствия повторяющихся групп данных. Рассмотрим следующую таблицу: CREATE TABLE CUSTOMERS( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25), ORDERS VARCHAR(155) ); Итак, если мы заполняем эту таблицу для одного клиента, имеющего несколько заказов, то это будет что-то, как показано ниже -
ID NAME AGE ADDRESS ORDERS
100 Anatolii 36 Moscow Cannon XL-200
100 Anatolii 36 Moscow Battery XL-200
100 Anatolii 36 Moscow Tripod Large
Но в соответствии с 1NF нам необходимо убедиться, что нет повторяющихся групп данных. Итак, разделим приведенную выше таблицу на две части, а затем присоедините их, используя ключ, как показано в следующей программе - Таблица КЛИЕНТОВ - CREATE TABLE CUSTOMERS( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, ADDRESS CHAR (25), PRIMARY KEY (ID) ); Эта таблица будет иметь следующую запись:
ID NAME AGE ADDRESS
100 Anatolii 36 Moscow
Таблица ЗАКАЗОВ - CREATE TABLE ORDERS( ID INT NOT NULL, CUSTOMER_ID INT NOT NULL, ORDERS VARCHAR(155), PRIMARY KEY (ID) ); Эта таблица будет иметь следующие записи:
ID CUSTOMER_ID ORDERS
10 100 Cannon XL-200
11 100 Battery XL-200
12 100 Tripod Large
Третье правило 1NF Окончательное правило первой нормальной формы, создайте первичный ключ для каждой таблицы, которую мы уже создали. Вторая нормальная форма (2NF) Вторая нормальная форма гласит, что она должна соответствовать всем правилам для 1NF и не должно быть частичных зависимостей любого из столбцов первичного ключа - Рассмотрите связь с заказчиком, и вы хотите сохранить идентификатор клиента, имя клиента, идентификатор заказа и подробную информацию о заказе, а также дату покупки - CREATE TABLE CUSTOMERS( CUST_ID INT NOT NULL, CUST_NAME VARCHAR (20) NOT NULL, ORDER_ID INT NOT NULL, ORDER_DETAIL VARCHAR (20) NOT NULL, SALE_DATE DATETIME, PRIMARY KEY (CUST_ID, ORDER_ID) ); Эта таблица находится в первой нормальной форме; В том, что он подчиняется всем правилам первой нормальной формы. В этой таблице первичный ключ состоит из CUST_ID и ORDER_ID. Комбинированные, они уникальны, если один и тот же клиент вряд ли закажет одно и то же. Однако таблица не во второй нормальной форме, потому что есть частичные зависимости первичных ключей и столбцов. CUST_NAME зависит от CUST_ID и нет реальной связи между именем клиента и приобретенным им. Детали заказа и дата покупки также зависят от ORDER_ID, но они не зависят от CUST_ID, потому что нет никакой связи между CUST_ID и ORDER_DETAIL или их SALE_DATE. Чтобы эта таблица соответствовала второй нормальной форме, вам необходимо разделить столбцы на три таблицы. Во-первых, создайте таблицу для хранения данных клиента, как показано в блоке кода ниже - CREATE TABLE CUSTOMERS( CUST_ID INT NOT NULL, CUST_NAME VARCHAR (20) NOT NULL, PRIMARY KEY (CUST_ID) ); Следующим шагом будет создание таблицы для хранения деталей каждого заказа - CREATE TABLE ORDERS( ORDER_ID INT NOT NULL, ORDER_DETAIL VARCHAR (20) NOT NULL, PRIMARY KEY (ORDER_ID) ); Наконец, создайте третью таблицу, хранящую только CUST_ID и ORDER_ID, чтобы отслеживать все заказы для клиента - CREATE TABLE CUSTMERORDERS( CUST_ID INT NOT NULL, ORDER_ID INT NOT NULL, SALE_DATE DATETIME, PRIMARY KEY (CUST_ID, ORDER_ID) ); Третья нормальная форма (3NF) Таблица находится в третьей нормальной форме, когда выполняются следующие условия: Он находится во второй нормальной форме. Все непервичные поля зависят от первичного ключа. Зависимость этих непервичных полей находится между данными. Например, в следующей таблице - название улицы, город и государство неразрывно связаны с их почтовым индексом. СОЗДАТЬ ТАБЛИЦЫ КЛИЕНТОВ (    CUST_ID INT NOT NULL,    CUST_NAME VARCHAR (20) NOT NULL,    DOB DATE,    УЛИЦА VARCHAR (200),    CITY VARCHAR (100),    ГОСУДАРСТВЕННЫЙ ВАРШАР (100),    ZIP VARCHAR (12),    EMAIL_ID VARCHAR (256),    ПЕРВИЧНЫЙ КЛЮЧ (CUST_ID) ); Зависимость между почтовым индексом и адресом называется транзитивной зависимостью. Чтобы соответствовать третьей нормальной форме, все, что вам нужно сделать, это переместить поля Street, City и State в их собственную таблицу, которую вы можете назвать таблицей Zip Code. - CREATE TABLE ADDRESS (    ZIP VARCHAR (12),    УЛИЦА VARCHAR (200),    CITY VARCHAR (100),    ГОСУДАРСТВЕННЫЙ ВАРШАР (100),    ПЕРВИЧНЫЙ КЛЮЧ (ZIP) ); Следующий шаг - изменить таблицу CUSTOMERS, как показано ниже: СОЗДАТЬ ТАБЛИЦЫ КЛИЕНТОВ (    CUST_ID INT NOT NULL,    CUST_NAME VARCHAR (20) NOT NULL,    DOB DATE,    ZIP VARCHAR (12),    EMAIL_ID VARCHAR (256),    ПЕРВИЧНЫЙ КЛЮЧ (CUST_ID) ); Преимущества удаления транзитивных зависимостей в основном в два раза. Во-первых, объем дублирования данных уменьшается, и поэтому ваша база данных становится меньше. Второе преимущество - целостность данных. При изменении дублированных данных существует большой риск обновления только некоторых данных, особенно если он распространен во многих разных местах базы данных. Например, если данные адреса и zip-кода были сохранены в трех или четырех разных таблицах, любые изменения в почтовых кодах должны были бы рябить к каждой записи в этих трех или четырех таблицах. SQL сопровождается уникальным набором правил и рекомендаций под названием Syntax. В этом учебном пособии вы быстро начнете с SQL, указав весь базовый синтаксис SQL. Все инструкции SQL начинаются с любых ключевых слов, таких как SELECT, INSERT, UPDATE, DELETE, ALTER, DROP, CREATE, USE, SHOW, и все инструкции заканчиваются точкой с запятой (;). Наиболее важным моментом, который следует отметить здесь, является то, что SQL нечувствителен к регистру, что означает SELECT и select имеют одинаковый смысл в операторах SQL. В то время как MySQL делает разницу в именах таблиц. Итак, если вы работаете с MySQL, вам нужно указать имена таблиц, как они есть в базе данных. Различные синтаксисы в SQL Все примеры, приведенные в этом руководстве, были протестированы на сервере MySQL. SELECT declaration SELECT column1, column2....columnN FROM table_name; DISTINCT item SELECT DISTINCT column1, column2....columnN FROM table_name; WHERE item SELECT column1, column2....columnN FROM table_name WHERE CONDITION; AND/OR item SELECT column1, column2....columnN FROM table_name WHERE CONDITION-1 {AND|OR} CONDITION-2; IN item SELECT column1, column2....columnN FROM table_name WHERE column_name IN (val-1, val-2,...val-N); BETWEEN item SELECT column1, column2....columnN FROM table_name WHERE column_name BETWEEN val-1 AND val-2; LIKE item SELECT column1, column2....columnN FROM table_name WHERE column_name LIKE { PATTERN }; ORDER BY item SELECT column1, column2....columnN FROM table_name WHERE CONDITION ORDER BY column_name {ASC|DESC}; GROUP BY item SELECT SUM(column_name) FROM table_name WHERE CONDITION GROUP BY column_name; COUNT item SELECT COUNT(column_name) FROM table_name WHERE CONDITION; HAVING item SELECT SUM(column_name) FROM table_name WHERE CONDITION GROUP BY column_name HAVING (arithematic function condition); CREATE TABLE declaration CREATE TABLE table_name( column1 datatype, column2 datatype, column3 datatype, ..... columnN datatype, PRIMARY KEY( one or more columns ) ); DROP TABLE declaration DROP TABLE table_name; CREATE INDEX declaration CREATE UNIQUE INDEX index_name ON table_name ( column1, column2,...columnN); DROP INDEX declaration ALTER TABLE table_name DROP INDEX index_name; DESC declaration DESC table_name; TRUNCATE TABLE declaration TRUNCATE TABLE table_name; ALTER TABLE declaration ALTER TABLE table_name {ADD|DROP|MODIFY} column_name {data_ype}; ALTER TABLE declaration (Rename) ALTER TABLE table_name RENAME TO new_table_name; INSERT INTO declaration INSERT INTO table_name( column1, column2....columnN) VALUES ( value1, value2....valueN); UPDATE declaration UPDATE table_name SET column1 = value1, column2 = value2....columnN=valueN [ WHERE CONDITION ]; DELETE declaration DELETE FROM table_name WHERE {CONDITION}; CREATE DATABASE declaration CREATE DATABASE database_name; DROP DATABASE declaration DROP DATABASE database_name; USE declaration USE database_name; COMMIT declaration COMMIT; ROLLBACK declaration ROLLBACK; Тип данных SQL - это атрибут, определяющий тип данных любого объекта. Каждый столбец, переменная и выражение имеет связанный тип данных в SQL. Эти типы данных можно использовать при создании таблиц. Вы можете выбрать тип данных для столбца таблицы на основе вашего требования. SQL Server предлагает шесть категорий типов данных для вашего использования, которые перечислены ниже - Точные числовые типы данных
DATA TYPE FROM TO
bigint -9,223,372,036,854,775,808 9,223,372,036,854,775,807
int -2,147,483,648 2,147,483,647
smallint -32,768 32,767
tinyint 0 255
bit 0 1
decimal -10^38 +1 10^38 -1
numeric -10^38 +1 10^38 -1
money -922,337,203,685,477.5808 +922,337,203,685,477.5807
smallmoney -214,748.3648 +214,748.3647
Приблизительные числовые типы данных
DATA TYPE FROM TO
datetime Jan 1, 1753 Dec 31, 9999
smalldatetime Jan 1, 1900 Jun 6, 2079
date Stores a date like June 30, 1991
time Stores a time of day like 12:30 P.M.
Типы данных даты и времени
DATA TYPE FROM TO
datetime Jan 1, 1753 Dec 31, 9999
smalldatetime Jan 1, 1900 Jun 6, 2079
date Stores a date like June 30, 1991
time Stores a time of day like 12:30 P.M.
Примечание. Здесь datetime имеет точность 3,33 миллисекунды, когда smalldatetime имеет точность в 1 минуту. Типы строк символов
Sr.No. DATA TYPE & Description
1 char Максимальная длина 8000 символов. (Фиксированная длина символов, отличных от Юникода)
2 varchar Максимум 8000 символов. (Данные, не относящиеся к Unicode для переменной длины).
3 varchar(max) Максимальная длина 231 символа, данные не-Unicode с переменной длиной (только для SQL Server 2005).
4 text Неравномерные данные переменной длины с максимальной длиной 2 147 483 647 символов.
Строки данных символов Unicode
Sr.No. DATA TYPE & Description
1 nchar Максимальная длина 4000 символов (Unicode с фиксированной длиной)
2 nvarchar Максимальная длина 4000 символов (Unicode с переменной длиной)
3 nvarchar(max) Максимальная длина 231 символа (только для SQL Server 2005). (Unicode с переменной длиной)
4 ntext Максимальная длина 1 073 741 823 символов. (Unicode с переменной длиной)
Типы двоичных данных
Sr.No. DATA TYPE & Description
1 binary Максимальная длина 8000 байт (двоичные данные фиксированной длины)
2 varbinary Максимальная длина 8000 байт (двоичные данные переменной длины)
3 varbinary(max) Максимальная длина 231 байт (только для SQL Server 2005). (Переменная длина двоичных данных)
4 image Максимальная длина 2 147 483 647 байт. (Двоичные данные переменной длины)
Различные типы данных
Sr.No. DATA TYPE & Description
1 sql_variant Сохраняет значения различных типов данных, поддерживаемых SQL Server, за исключением текста, ntext и timestamp.
2 timestamp Сохраняет уникальный номер базы данных, который обновляется каждый раз, когда строка обновляется
3 uniqueidentifier Хранит глобально уникальный идентификатор (GUID)
4 xml Сохраняет XML-данные. Вы можете хранить экземпляры xml в столбце или переменной (только для SQL Server 2005).
5 cursor Ссылка на объект курсора
6 table Сохраняет набор результатов для последующей обработки
Что такое оператор в SQL? Оператором является зарезервированное слово или символ, используемый в основном в предложении WHERE оператора SQL для выполнения операций (операций), таких как сравнения и арифметические операции. Эти операторы используются для указания условий в операторе SQL и служат конъюнкциями для нескольких условий в инструкции. Арифметические операторы Операторы сравнения Логические операторы Операторы, используемые для отрицания условий Арифметические операторы SQL Предположим, что «переменная a» имеет значение 10, а «переменная b» - 20, затем
Operator Description Example
+ (Addition) Добавляет значения по обе стороны оператора. a + b = 30
- (Subtraction) Вычитает правый операнд из левого операнда a - b = -10
* (Multiplication) Умножает значения по обе стороны оператора. a * b = 200
/ (Division) Делит левый операнд правой рукой b / a = 2
% (Modulus) Раздевает левый операнд правой рукой и возвращает остаток b % a = 0
Операторы сравнения SQL Предположим, что «переменная a» имеет значение 10, а «переменная b» - 20, затем
Operator Description Example
= Проверяет, равны ли значения двух операндов или нет, если да, то условие становится истинным (a = b) is not true.
!= Проверяет, равны ли значения двух операндов или нет, если значения не равны, тогда условие становится истинным. (a != b) is true.
<> Проверяет, равны ли значения двух операндов или нет, если значения не равны, тогда условие становится истинным. (a <> b) is true.
> Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (a > b) is not true.
< Проверяет, является ли значение левого операнда меньше значения правильного операнда, если да, тогда условие становится истинным. (a < b) is true.
>= Проверяет, превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (a >= b) is not true.
<= Проверяет, является ли значение левого операнда меньше или равно значению правого операнда, если да, тогда условие становится истинным. (a <= b) is true.
!< Проверяет, не превышает ли значение левого операнда значение правого операнда, если да, то условие становится истинным. (a !< b) is false.
!> Проверяет, не превышает ли значение левого операнда значение правого операнда, если да, тогда условие становится истинным. (a !> b) is true.
Логические операторы SQL Вот список всех логических операторов, доступных в SQL.
Sr.No. Operator & Description
1 ALL Оператор ALL используется для сравнения значения со всеми значениями в другом наборе значений.
2 AND Оператор AND допускает существование множества условий в предложении WHERE оператора SQL.
3 ANY Оператор ANY используется для сравнения значения с любым применимым значением в списке в соответствии с условием.
4 BETWEEN Оператор BETWEEN используется для поиска значений, находящихся в пределах набора значений, с учетом минимального значения и максимального значения.
5 EXISTS Оператор EXISTS используется для поиска наличия строки в указанной таблице, которая соответствует определенному критерию.
6 IN Оператор IN используется для сравнения значения со списком заданных литеральных значений.
7 LIKE Оператор LIKE используется для сравнения значения с аналогичными значениями с помощью подстановочных операторов.
8 NOT Оператор NOT меняет смысл логического оператора, с которым он используется. Например: НЕ СУЩЕСТВУЕТ, НЕ МЕЖДУ, НЕ ВХОДОМ и т. Д. Это оператор отрицания.
9 OR Оператор OR используется для объединения нескольких условий в предложение WHERE предложения SQL.
10 IS NULL Оператор NULL используется для сравнения значения со значением NULL.
11 UNIQUE Оператор UNIQUE выполняет поиск каждой строки указанной таблицы для уникальности (без дубликатов).
Выражение представляет собой комбинацию одного или нескольких значений, операторов и функций SQL, которые оценивают значение. Эти SQL EXPRESSIONs похожи на формулы, и они написаны на языке запросов. Вы также можете использовать их для запроса базы данных для определенного набора данных. Синтаксис Рассмотрим основной синтаксис оператора SELECT следующим образом: SELECT column1, column2, columnN FROM table_name WHERE [СОСТОЯНИЕ | ЭКСПРЕССИЯ]; Существуют различные типы выражений SQL, которые упоминаются ниже - логический числовой Дата Давайте теперь обсудим каждую из них подробно. Булевы выражения Буферные выражения SQL извлекают данные на основе соответствия одному значению. Ниже приведен синтаксис - SELECT column1, column2, columnN FROM table_name WHERE условиик; Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: SQL> SELECT * FROM CUSTOMERS; + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + 7 строк в наборе (0,00 сек) Следующая таблица представляет собой простой пример, показывающий использование различных булевых выражений SQL - SQL> SELECT * FROM CUSTOMERS WHERE SALARY = 10000; + ---- + ------- + ----- + --------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ------- + ----- + --------- + ---------- + | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ------- + ----- + --------- + ---------- + 1 строка в наборе (0,00 сек) Числовое выражение Эти выражения используются для выполнения любой математической операции в любом запросе. Ниже приведен синтаксис - ВЫБЕРИТЕ численное выражение как OPERATION_NAME [FROM table_name WHERE УСЛОВИЕ]; Здесь численное выражение используется для математического выражения или любой формулы. Ниже приведен простой пример, показывающий использование SQL Numeric Expressions - SQL> SELECT (15 + 6) AS ADDITION + ---------- + |ADDITION | + ---------- + | 21 | + ---------- + 1 строка в наборе (0,00 сек) Существует несколько встроенных функций, таких как avg (), sum (), count () и т. Д., Чтобы выполнять так называемые вычисления совокупных данных с таблицей или столбцом конкретной таблицы. SQL> SELECT COUNT (*) AS "ЗАПИСИ" FROM CUSTOMERS; + --------- + | ЗАПИСИ | + --------- + | 7 | + --------- + 1 строка в наборе (0,00 сек) Выражения даты Выражения даты возвращают текущие системные значения даты и времени - SQL> SELECT CURRENT_TIMESTAMP; + --------------------- + | Current_Timestamp | + --------------------- + | 2009-11-12 06:40:23 | + --------------------- + 1 строка в наборе (0,00 сек) Другое выражение даты показано ниже: SQL> SELECT GETDATE () ;; + ------------------------- + | GETDATE | + ------------------------- + | 2009-10-22 12: 07: 18.140 | + ------------------------- + 1 строка в наборе (0,00 сек) Создание базовой таблицы предполагает присвоение имени таблице и определение ее столбцов и типа данных каждого столбца. Оператор SQL CREATE TABLE используется для создания новой таблицы. Синтаксис Основной синтаксис оператора CREATE TABLE выглядит следующим образом: CREATE TABLE имя_таблицы (    Column1 тип данных,    Column2,    Column3,    .....    ColumnN тип данных,    PRIMARY KEY (ID) ); CREATE TABLE - это ключевое слово, сообщающее системе баз данных, что вы хотите сделать. В этом случае вы хотите создать новую таблицу. Уникальное имя или идентификатор таблицы следует за оператором CREATE TABLE. Затем в скобках появляется список, определяющий каждый столбец в таблице и тип данных. Синтаксис становится более понятным в следующем примере. Копию существующей таблицы можно создать, используя комбинацию оператора CREATE TABLE и оператора SELECT. Вы можете проверить полную информацию в таблице Создать с помощью другой таблицы. пример Следующий пример кода является примером, который создает таблицу CUSTOMERS с идентификатором в качестве первичного ключа, а NOT NULL - это ограничения, показывающие, что эти поля не могут быть NULL при создании записей в этой таблице - SQL> CREATE TABLE CUSTOMERS (    ID INT NOT NULL,    NAME VARCHAR (20) NOT NULL,    AGE INT NOT NULL,    ADDRESS CHAR (25),    SALARY DECIMAL (18, 2),    PRIMARY KEY (ID) ); Вы можете проверить, была ли ваша таблица успешно создана, просмотрев сообщение, отображаемое SQL-сервером, иначе вы можете использовать команду DESC следующим образом: SQL> DESC CUSTOMERS; + --------- + --------------- + ------ + ----- + --------- + ------- + | Поле | Тип | Null | Ключ | По умолчанию | Экстра | + --------- + --------------- + ------ + ----- + --------- + ------- + | ID | Int (11) | НЕТ | PRI | | | | ИМЯ | Varchar (20) | НЕТ | | | | | ВОЗРАСТ | Int (11) | НЕТ | | | | | АДРЕС | Char (25) | ДА | | NULL | | | SALARY | Десятичная (18,2) | ДА | | NULL | | + --------- + --------------- + ------ + ----- + --------- + ------- + 5 строк в наборе (0,00 сек) Теперь у вас есть таблица CUSTOMERS, доступная в вашей базе данных, которую вы можете использовать для хранения необходимой информации, связанной с клиентами. Существуют два основных синтаксиса оператора INSERT INTO, которые показаны ниже. INSERT INTO TABLE_NAME (столбец1, столбец2, столбец3, ... columnN) VALUES (значение1, значение2, значение3, ... значениеN); Здесь column1, column2, column3, ... columnN - это имена столбцов в таблице, в которые вы хотите вставить данные. Возможно, вам не нужно указывать имя столбца в SQL-запросе, если вы добавляете значения для всех столбцов таблицы. Но убедитесь, что порядок значений находится в том же порядке, что и столбцы в таблице. Синтаксис SQL INSERT INTO будет следующим: INSERT INTO TABLE_NAME VALUES (value1, value2, value3, ... valueN); пример Следующие операторы будут создавать шесть записей в таблице CUSTOMERS. INSERT INTO CUSTOMERS (ID, ИМЯ, ВОЗРАСТ, АДРЕС, ОТОБРАЖЕНИЕ) VALUES (1, «Рамеш», 32, «Ахмедабад», 2000.00); INSERT INTO CUSTOMERS (ID, ИМЯ, ВОЗРАСТ, АДРЕС, ОТОБРАЖЕНИЕ) VALUES (2, 'Khilan', 25, 'Delhi', 1500.00); INSERT INTO CUSTOMERS (ID, ИМЯ, ВОЗРАСТ, АДРЕС, ОТОБРАЖЕНИЕ) VALUES (3, 'kaushik', 23, 'Kota', 2000.00); INSERT INTO CUSTOMERS (ID, ИМЯ, ВОЗРАСТ, АДРЕС, ОТОБРАЖЕНИЕ) VALUES (4, 'Chaitali', 25, 'Mumbai', 6500,00); INSERT INTO CUSTOMERS (ID, ИМЯ, ВОЗРАСТ, АДРЕС, ОТОБРАЖЕНИЕ) VALUES (5, 'Hardik', 27, 'Bhopal', 8500,00); INSERT INTO CUSTOMERS (ID, ИМЯ, ВОЗРАСТ, АДРЕС, ОТОБРАЖЕНИЕ) VALUES (6, «Комаль», 22, «МП», 4500,00); Вы можете создать запись в таблице CUSTOMERS, используя второй синтаксис, как показано ниже. INSERT INTO CUSTOMERS VALUES (7, 'Muffy', 24, 'Indore', 10000,00); Все приведенные выше инструкции приведут к следующим записям в таблице КЛИЕНТОВ, как показано ниже. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Заполнение одной таблицы с использованием другой таблицы Вы можете заполнить данные в таблице посредством оператора select над другой таблицей; Если в другой таблице есть набор полей, которые должны заполнять первую таблицу. Вот синтаксис - INSERT INTO first_table_name [(column1, column2, ... columnN)]    SELECT column1, column2, ... columnN    FROM second_table_name    [WHERE condition]; Оператор SQL SELECT используется для извлечения данных из таблицы базы данных, которая возвращает эти данные в форме таблицы результатов. Эти таблицы результатов называются результирующими наборами. Синтаксис Основной синтаксис оператора SELECT выглядит следующим образом: SELECT column1, column2, columnN FROM table_name; Здесь column1, column2 ... являются полями таблицы, значения которых вы хотите получить. Если вы хотите получить все поля, доступные в этом поле, вы можете использовать следующий синтаксис. SELECT * FROM table_name; пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Ниже приведен пример кода, который будет отображать поля ID, Name и Salary для клиентов, доступных в таблице CUSTOMERS. SQL> SELECT ID, NAME, SALARY FROM CUSTOMERS; Это приведет к следующему результату - + ---- + ---------- + ---------- + | ID | ИМЯ | SALARY | + ---- + ---------- + ---------- + | 1 | Рамеш | 2000.00 | | 2 | Хилан | 1500,00 | | 3 | Каушик | 2000.00 | | 4 | Chaitali | 6500,00 | | 5 | Хардик | 8500,00 | | 6 | Комаль | 4500,00 | | 7 | Muffy | 10000,00 | + ---- + ---------- + ---------- + Если вы хотите получить все поля таблицы CUSTOMERS, вы должны использовать следующий запрос. SQL> SELECT * FROM CUSTOMERS; Это даст результат, как показано ниже. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Предложение SQL WHERE используется для указания условия при извлечении данных из одной таблицы или путем соединения с несколькими таблицами. Если заданное условие выполнено, то только оно возвращает определенное значение из таблицы. Вы должны использовать предложение WHERE для фильтрации записей и получения только необходимых записей. Предложение WHERE используется не только в инструкции SELECT, но также используется в операциях UPDATE, DELETE и т. Д., Которые мы рассмотрим в последующих главах. Синтаксис Основной синтаксис оператора SELECT с предложением WHERE показан ниже. SELECT column1, column2, columnN FROM table_name ГДЕ [условие] Вы можете указать условие, используя сравнительные или логические операторы типа Хардик , >, =, LIKE, NOT и т. Д. Следующие примеры позволили бы понять эту концепцию. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Следующий пример является примером, который будет отображать поля ID, Name и Salary из таблицы CUSTOMERS, где зарплата больше 2000 - SQL < SELECT ID, NAME, SALARY FROM CUSTOMERS WHERE NAME = 'Хардик'; Это приведет к следующему результату - + ---- + ---------- + ---------- + | ID | ИМЯ | SALARY | + ---- + ---------- + ---------- + | 4 | Chaitali | 6500,00 | | 5 | Хардик | 8500,00 | | 6 | Комаль | 4500,00 | | 7 | Muffy | 10000,00 | + ---- + ---------- + ---------- + Следующий пример - пример, который будет извлекать поля ID, Name и Salary из таблицы CUSTOMERS для клиента с именем Hardik. Здесь важно отметить, что все строки должны быть указаны внутри одинарных кавычек (''). Принимая во внимание, что числовые значения следует указывать без каких-либо котировок, как в приведенном выше примере. SQL SELECT ID, NAME, SALARY ОТ КЛИЕНТОВ ГДЕ ИМЯ = 'Хардик'; Это приведет к следующему результату - + ---- + ---------- + ---------- + | ID | ИМЯ | SALARY | + ---- + ---------- + ---------- + | 5 | Хардик | 8500,00 | + ---- + ---------- + ---------- + Операторы SQL AND & OR используются для объединения нескольких условий для сужения данных в инструкции SQL. Эти два оператора называются конъюнктивными операторами. Эти операторы предоставляют средства для выполнения нескольких сравнений с разными операторами в одном и том же заявлении SQL. Оператор И Оператор AND допускает существование множества условий в предложении WHERE оператора SQL. Синтаксис Основной синтаксис оператора AND с предложением WHERE заключается в следующем: SELECT column1, column2, columnN FROM table_name ГДЕ [условие1] И [условие2] ... AND [условиеN]; Вы можете комбинировать N число условий с помощью оператора AND. Для действия, которое должно выполнить оператор SQL, будь то транзакция или запрос, все условия, разделенные И, должны быть ИСТИНА. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Ниже приведен пример, который будет отображать поля ID, Name и Salary из таблицы CUSTOMERS, где зарплата превышает 2000, а возраст составляет менее 25 лет - SQL> SELECT ID, NAME, SALARY FROM CUSTOMERS WHERE SALARY> 2000 И возраст <25; Это приведет к следующему результату - + ---- + ------- + ---------- + | ID | ИМЯ | SALARY | + ---- + ------- + ---------- + | 6 | Комаль | 4500,00 | | 7 | Muffy | 10000,00 | + ---- + ------- + ---------- + Оператор ИЛИ Оператор OR используется для объединения нескольких условий в предложение WHERE предложения SQL. Синтаксис Основной синтаксис оператора OR с предложением WHERE заключается в следующем: SELECT column1, column2, columnN FROM table_name WHERE [состояние1] OR [состояние2] ... OR [состояниеN] Вы можете комбинировать N количество условий с помощью оператора OR. Для действия, выполняемого оператором SQL, будь то транзакция или запрос, единственное любое ОДИН из условий, разделенных OR, должно быть ИСТИНА. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Следующий код кода имеет запрос, который будет извлекать поля ID, Name и Salary из таблицы CUSTOMERS, где зарплата превышает 2000, а возраст составляет менее 25 лет. SQL> SELECT ID, NAME, SALARY FROM CUSTOMERS WHERE SALARY> 2000 OR age <25; Это приведет к следующему результату - + ---- + ---------- + ---------- + | ID | ИМЯ | SALARY | + ---- + ---------- + ---------- + | 3 | Каушик | 2000.00 | | 4 | Chaitali | 6500,00 | | 5 | Хардик | 8500,00 | | 6 | Комаль | 4500,00 | | 7 | Muffy | 10000,00 | + ---- + ---------- + ---------- + SQL UPDATE Query используется для изменения существующих записей в таблице. Вы можете использовать предложение WHERE с запросом UPDATE для обновления выбранных строк, иначе все строки будут затронуты. Синтаксис Основной синтаксис запроса UPDATE с предложением WHERE выглядит следующим образом: UPDATE имя_таблицы SET column1 = значение1, column2 = значение2 ...., columnN = значениеN WHERE [условие]; Вы можете объединить N число условий с помощью операторов AND или OR. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Следующий запрос обновит АДРЕС для клиента, идентификационный номер которого равен 6 в таблице. SQL> UPDATE CUSTOMERS SET ADDRESS = 'Pune' WHERE ID = 6; Теперь таблица CUSTOMERS будет иметь следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | Пуне | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Если вы хотите изменить все значения столбца ADDRESS и SALARY в таблице CUSTOMERS, вам не нужно использовать предложение WHERE, поскольку запрос UPDATE будет достаточным, как показано в следующем блоке кода. SQL> UPDATE CUSTOMERS SET ADDRESS = 'Pune', SALARY = 1000,00; Теперь таблица CUSTOMERS будет иметь следующие записи: + ---- + ---------- + ----- + --------- + --------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + --------- + --------- + | 1 | Рамеш | 32 | Пуне | 1000,00 | | 2 | Хилан | 25 | Пуне | 1000,00 | | 3 | Каушик | 23 | Пуне | 1000,00 | | 4 | Chaitali | 25 | Пуне | 1000,00 | | 5 | Хардик | 27 | Пуне | 1000,00 | | 6 | Комаль | 22 | Пуне | 1000,00 | | 7 | Muffy | 24 | Пуне | 1000,00 | + ---- + ---------- + ----- + --------- + --------- + SQL DELETE Query используется для удаления существующих записей из таблицы. Вы можете использовать предложение WHERE с запросом DELETE для удаления выбранных строк, иначе все записи будут удалены. Синтаксис Основной синтаксис запроса DELETE с предложением WHERE выглядит следующим образом: DELETE FROM table_name WHERE [условие]; Вы можете комбинировать N количество условий с использованием операторов AND или OR. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Следующий код содержит запрос, который удалит клиента, чей идентификатор равен 6. SQL> DELETE FROM CUSTOMERS WHERE ID = 6; Теперь таблица CUSTOMERS будет иметь следующие записи. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Если вы хотите УДАЛИТЬ все записи из таблицы CUSTOMERS, вам не нужно использовать предложение WHERE, и запрос DELETE будет следующим: SQL> УДАЛИТЬ ОТ КЛИЕНТОВ; Теперь таблица CUSTOMERS не будет иметь никакой записи. Предложение SQL LIKE используется для сравнения значения с аналогичными значениями с помощью подстановочных операторов. В сочетании с оператором LIKE используются две маски. Знак процента (%) Подчеркивание (_) Знак процента представляет нуль, один или несколько символов. Подчеркивание представляет собой одно число или символ. Эти символы могут использоваться в комбинациях. Синтаксис Основной синтаксис% и _ следующий: SELECT FROM table_name WHERE column LIKE 'XXXX%' или SELECT FROM table_name WHERE column LIKE '% XXXX%' или SELECT FROM table_name WHERE column LIKE 'XXXX_' или SELECT FROM table_name WHERE column LIKE '_XXXX' или SELECT FROM table_name WHERE column LIKE '_XXXX_' Вы можете комбинировать N количество условий с использованием операторов AND или OR. Здесь XXXX может быть любым числовым или строковым значением. пример В следующей таблице приведены несколько примеров, показывающих, что часть WHERE имеет разные предложения LIKE с операторами «%» и «_» - Предложение SQL TOP используется для извлечения таблицы TOP N или X процентов из таблицы. Примечание. Все базы данных не поддерживают предложение TOP. Например, MySQL поддерживает предложение LIMIT для получения ограниченного количества записей, в то время как Oracle использует команду ROWNUM для извлечения ограниченного количества записей. Синтаксис Основной синтаксис предложения TOP с выражением SELECT будет следующим. SELECT TOP number | percent column_name (s) FROM table_name WHERE [условие] пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Следующий запрос представляет собой пример на SQL-сервере, который будет извлекать верхние 3 записи из таблицы CUSTOMERS. SQL> SELECT TOP 3 * FROM CUSTOMERS; Это приведет к следующему результату - + ---- + --------- + ----- + ----------- + --------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + --------- + ----- + ----------- + --------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | + ---- + --------- + ----- + ----------- + --------- + Если вы используете сервер MySQL, то здесь приведен эквивалентный пример - SQL> SELECT * FROM CUSTOMERS LIMIT 3; Это приведет к следующему результату - + ---- + --------- + ----- + ----------- + --------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + --------- + ----- + ----------- + --------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | + ---- + --------- + ----- + ----------- + --------- + Если вы используете сервер Oracle, следующий примерный блок имеет эквивалентный пример. SQL> SELECT * FROM CUSTOMERS WHERE ROWNUM <= 3; Это приведет к следующему результату - + ---- + --------- + ----- + ----------- + --------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + --------- + ----- + ----------- + --------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | + ---- + --------- + ----- + ----------- + --------- + Предложение SQL ORDER BY используется для сортировки данных в порядке возрастания или убывания на основе одного или нескольких столбцов. Некоторые базы данных сортируют результаты запроса в порядке возрастания по умолчанию. Синтаксис Основной синтаксис предложения ORDER BY выглядит следующим образом: SELECT column-list FROM table_name [WHERE условие] [ORDER BY column1, column2, .. columnN] [ASC | По убыванию]; Вы можете использовать более одного столбца в предложении ORDER BY. Убедитесь, что любой столбец, который вы используете для сортировки этого столбца, должен находиться в списке столбцов. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + В следующем блоке кода есть пример, который сортирует результат в порядке возрастания с помощью NAME и SALARY - SQL> SELECT * FROM CUSTOMERS    ORDER BY NAME, SALARY; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | + ---- + ---------- + ----- + ----------- + ---------- + В следующем блоке кода есть пример, который сортирует результат в порядке убывания по NAME. SQL> SELECT * FROM CUSTOMERS    ORDER BY NAME DESC; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | + ---- + ---------- + ----- + ----------- + ---------- + Предложение SQL ORDER BY используется для сортировки данных в порядке возрастания или убывания на основе одного или нескольких столбцов. Некоторые базы данных сортируют результаты запроса в порядке возрастания по умолчанию. Синтаксис Основной синтаксис предложения ORDER BY выглядит следующим образом: Список столбцов SELECT FROM table_name [WHERE условие] [ORDER BY column1, column2, .. columnN] [ASC | По убыванию]; Вы можете использовать более одного столбца в предложении ORDER BY. Убедитесь, что любой столбец, который вы используете для сортировки этого столбца, должен находиться в списке столбцов. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + В следующем блоке кода есть пример, который сортирует результат в порядке возрастания с помощью NAME и SALARY - SQL> SELECT * FROM CUSTOMERS    ORDER BY NAME, SALARY; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | + ---- + ---------- + ----- + ----------- + ---------- + В следующем блоке кода есть пример, который сортирует результат в порядке убывания по NAME. SQL> SELECT * FROM CUSTOMERS    ORDER BY NAME DESC; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | + ---- + ---------- + ----- + ----------- + ---------- + Ключевое слово SQL DISTINCT используется в сочетании с оператором SELECT для устранения всех повторяющихся записей и получения только уникальных записей. Может возникнуть ситуация, когда в таблице имеется несколько повторяющихся записей. При извлечении таких записей имеет смысл извлекать только те уникальные записи, а не извлекать дубликаты записей. Синтаксис Основной синтаксис ключевого слова DISTINCT для устранения дубликатов записей выглядит следующим образом: SELECT DISTINCT column1, column2, ..... columnN FROM table_name WHERE [условие] пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 3000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 3000.00 | | 4 | Chaitali | 25 | Мумбаи | 7500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 5500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Сначала давайте посмотрим, как следующий запрос SELECT возвращает дубликаты записей зарплаты. SQL> SELECT SALARY FROM CUSTOMERS    ORDER BY SALARY; Это приведет к следующему результату, когда зарплата (2000) будет поступать дважды, что является дубликатностью из исходной таблицы. + ---------- + | SALARY | + ---------- + | 1500,00 | | 3000.00 | | 3000.00 | | 5500,00 | | 7500,00 | | 8500,00 | | 10000,00 | + ---------- + Теперь давайте используем ключевое слово DISTINCT с вышеуказанным запросом SELECT, а затем увидим результат. SQL> SELECT DISTINCT SALARY FROM CUSTOMERS    ORDER BY SALARY; Это приведет к следующему результату, когда у нас нет дубликатов. + ---------- + | SALARY | + ---------- + | 1500,00 | | 3000.00 | | 5500,00 | | 7500,00 | | 8500,00 | | 10000,00 | + ---------- + Предложение SQL ORDER BY используется для сортировки данных в порядке возрастания или убывания на основе одного или нескольких столбцов. Некоторые базы данных сортируют результаты запроса в порядке возрастания по умолчанию. Синтаксис Основной синтаксис предложения ORDER BY, который будет использоваться для сортировки результата в порядке возрастания или убывания, выглядит следующим образом: SELECT column-list FROM table_name [WHERE условие] [ORDER BY column1, column2, .. columnN] [ASC | По убыванию]; Вы можете использовать более одного столбца в предложении ORDER BY. Убедитесь, что любой столбец, который вы используете для сортировки, этот столбец должен находиться в списке столбцов. пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Ниже приведен пример, который сортирует результат в порядке возрастания по NAME и SALARY. SQL> SELECT * FROM CUSTOMERS    ORDER BY NAME, SALARY; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | + ---- + ---------- + ----- + ----------- + ---------- + В следующем блоке кода есть пример, который сортирует результат в порядке убывания с помощью NAME. SQL> SELECT * FROM CUSTOMERS    ORDER BY NAME DESC; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | + ---- + ---------- + ----- + ----------- + ---------- + Чтобы получить строки с их собственным предпочтительным порядком, используемый запрос SELECT будет следующим: SQL> SELECT * FROM CUSTOMERS    ORDER BY (АДРЕС ДЕЯТЕЛЬНОСТИ    WHEN «ДЕЛИ» ТОГДА 1    WHEN BHOPAL THEN 2    WHEN «КОТА» ТОГДА 3    WHEN «АХМАДАБАД» ТОГДА 4    WHEN «МП» ТОГДА 5    ELSE 100 END) ASC, ADDRESS DESC; Это приведет к следующему результату - + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 2 | Хилан | 25 | Дели | 1500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 6 | Комаль | 22 | MP | 4500,00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | + ---- + ---------- + ----- + ----------- + ---------- + Это отсортирует клиентов по адресу ADDRESS в вашем собственном приоритете сначала и в натуральном порядке для остальных адресов. Кроме того, остальные адреса будут отсортированы в обратном алфавитном порядке.

SQL дополнительно

					
	Ограничения - это правила, применяемые в столбцах данных таблицы. Они используются для ограничения типа данных, которые могут входить в таблицу. Это обеспечивает точность и надежность данных в базе данных.
Ограничения могут быть либо на уровне столбцов, либо на уровне таблицы. Ограничения уровня столбца применяются только к одному столбцу, тогда как ограничения уровня таблицы применяются ко всей таблице.
Ниже приведены некоторые из наиболее часто используемых ограничений, доступных в SQL. Эти ограничения уже обсуждались в главе «Концепции SQL - RDBMS», но сейчас стоит их пересмотреть.
NOT NULL Constraint - гарантирует, что столбец не может иметь значение NULL.
DEFAULT Constraint - задает значение по умолчанию для столбца, если ни один не указан.
UNIQUE Constraint - гарантирует, что все значения в столбце отличаются.
PRIMARY Key - уникальная идентификация каждой строки / записи в таблице базы данных.
FOREIGN Key - уникально идентифицирует строку / запись в любой из данных таблицы базы данных.
CHECK Constraint - ограничение CHECK гарантирует, что все значения в столбце удовлетворяют определенным условиям.
INDEX - используется для быстрого и быстрого создания данных из базы данных.
Ограничения могут быть указаны, когда таблица создается с помощью оператора CREATE TABLE или вы можете использовать оператор ALTER TABLE для создания ограничений даже после создания таблицы.
Снижение ограничений
Любое ограничение, которое вы определили, можно отбросить с помощью команды ALTER TABLE с параметром DROP CONSTRAINT.
Например, чтобы удалить ограничение первичного ключа в таблице EMPLOYEES, вы можете использовать следующую команду.
ALTER TABLE EMPLOYEES DROP CONSTRAINT EMPLOYEES_PK;
Некоторые реализации могут предоставлять ярлыки для отмены определенных ограничений. Например, чтобы удалить ограничение первичного ключа для таблицы в Oracle, вы можете использовать следующую команду.
ALTER TABLE EMPLOYEES DROP PRIMARY KEY;
Некоторые реализации позволяют отключать ограничения. Вместо того, чтобы постоянно удалять ограничение из базы данных, вы можете временно отключить ограничение и затем включить его позже.
Ограничения целостности
Ограничения целостности используются для обеспечения точности и согласованности данных в реляционной базе данных. Целостность данных обрабатывается в реляционной базе данных посредством концепции ссылочной целостности.
Существует множество типов ограничений целостности, которые играют роль в ссылочной целостности (RI). Эти ограничения включают в себя первичный ключ, внешний ключ, уникальные ограничения и другие ограничения, о которых упоминалось выше.					
	

	


Предложение SQL Joins используется для объединения записей из двух или более таблиц в базе данных. JOIN - это средство для объединения полей из двух таблиц с использованием значений, общих для каждого.
Рассмотрим следующие две таблицы:
Таблица 1 -  CUSTOMERS Table
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - ORDERS Table
+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам в инструкции SELECT, как показано ниже.

SQL>  SELECT ID, NAME, AGE, AMOUNT
   FROM CUSTOMERS, ORDERS
   WHERE  CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату.

+ ---- + ---------- + ----- + -------- +
| ID | ИМЯ | ВОЗРАСТ | AMOUNT |
+ ---- + ---------- + ----- + -------- +
| 3 | Каушик | 23 | 3000 |
| 3 | Каушик | 23 | 1500 |
| 2 | Хилан | 25 | 1560 |
| 4 | Chaitali | 25 | 2060 |
+ ---- + ---------- + ----- + -------- +
Здесь заметно, что соединение выполняется в предложении WHERE. Для объединения таблиц можно использовать несколько операторов, таких как:,,,,,,,,, Все они могут использоваться для объединения таблиц. Однако наиболее распространенным оператором является символ равный.

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

INNER JOIN создает новую таблицу результатов, комбинируя значения столбцов двух таблиц (table1 и table2) на основе предиката соединения. Запрос сравнивает каждую строку таблицы1 с каждой строкой таблицы2, чтобы найти все пары строк, которые удовлетворяют предикату соединения. Когда предикат соединения выполняется, значения столбцов для каждой согласованной пары строк A и B объединяются в строку результатов.

Синтаксис
Основной синтаксис INNER JOIN заключается в следующем.

SELECT table1.column1, table2.column2 ...
FROM table1
INNER JOIN table2
ON table1.common_field = table2.common_field;
пример
Рассмотрим следующие две таблицы.

Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица ORDERS выглядит следующим образом.

+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам, используя INNER JOIN следующим образом:

SQL>  SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   INNER JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату.

+ ---- + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ---- + ---------- + -------- + --------------------- +
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+ ---- + ---------- + -------- + --------------------- +




LEFT JOIN - возвращает все строки из левой таблицы, даже если в правой таблице нет совпадений.
SQL LEFT JOIN возвращает все строки из левой таблицы, даже если в правой таблице нет совпадений. Это означает, что если предложение ON соответствует 0 (ноль) записей в правой таблице; Объединение все равно вернет строку в результат, но с NULL в каждом столбце из правой таблицы.

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

Синтаксис
Основной синтаксис LEFT JOIN заключается в следующем.

SELECT table1.column1, table2.column2 ...
FROM table1
LEFT JOIN table2
ON table1.common_field = table2.common_field;
Здесь данное условие может быть любым заданным выражением, основанным на вашем требовании.

пример
Рассмотрим следующие две таблицы,

Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица заказов выглядит следующим образом.

+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам, используя LEFT JOIN следующим образом.

SQL>SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату -

+ ---- + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ---- + ---------- + -------- + --------------------- +
| 1 | Рамеш | NULL | NULL |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Хардик | NULL | NULL |
| 6 | Комаль | NULL | NULL |
| 7 | Muffy | NULL | NULL |
+ ---- + ---------- + -------- + --------------------- +




RIGHT JOIN - возвращает все строки из правой таблицы, даже если в левой таблице нет совпадений.
SQL RIGHT JOIN возвращает все строки из правой таблицы, даже если в левой таблице нет совпадений. Это означает, что если предложение ON соответствует 0 (ноль) записей в левой таблице; Объединение все равно вернет строку в результат, но с NULL в каждом столбце из левой таблицы.

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

Синтаксис
Основной синтаксис RIGHT JOIN следующий.

SELECT table1.column1, table2.column2 ...
FROM table1
RIGHT JOIN table2
ON table1.common_field = table2.common_field;
пример
Рассмотрим следующие две таблицы,

Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица ORDERS выглядит следующим образом.

+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам, используя ПРАВОЕ СОЕДИНЕНИЕ следующим образом.

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату -

+ ------ + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ------ + ---------- + -------- + --------------------- +
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+ ------ + ---------- + -------- + --------------------- +




FULL JOIN - возвращает строки, когда есть совпадение в одной из таблиц.
SQL FULL JOIN объединяет результаты как левого, так и правого внешних соединений.
Объединенная таблица будет содержать все записи из обеих таблиц и заполнять NULL для отсутствия совпадений с обеих сторон.
Синтаксис
Основной синтаксис FULL JOIN заключается в следующем:
SELECT table1.column1, table2.column2 ...
FROM table1
FULL JOIN к таблице2
ON table1.common_field = table2.common_field;
Здесь данное условие может быть любым заданным выражением, основанным на вашем требовании.
пример
Рассмотрим следующие две таблицы.
Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица ORDERS выглядит следующим образом.
+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам, используя FULL JOIN следующим образом.

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION ALL
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
+ ------ + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ------ + ---------- + -------- + --------------------- +
| 1 | Рамеш | NULL | NULL |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Хардик | NULL | NULL |
| 6 | Комаль | NULL | NULL |
| 7 | Muffy | NULL | NULL |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+ ------ + ---------- + -------- + --------------------- +
Если ваша база данных не поддерживает FULL JOIN (MySQL не поддерживает FULL JOIN), вы можете использовать предложение UNION ALL, чтобы объединить эти два JOINS, как показано ниже.

SQL>  SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION ALL
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID







SELF JOIN - используется для объединения таблицы в себя, как если бы таблица была двумя таблицами, временно переименовав хотя бы одну таблицу в SQL-заявлении.
SQL SELF JOIN используется для объединения таблицы в себя, как если бы таблица была двумя таблицами; Временно переименовать по крайней мере одну таблицу в SQL-запросе.

Синтаксис
Основной синтаксис SELF JOIN выглядит следующим образом:

SELECT a.column_name, b.column_name ...
FROM table1 a, table1 b
WHERE a.common_field = b.common_field;
Здесь предложение WHERE может быть любым заданным выражением, основанным на вашем требовании.

пример
Рассмотрим следующую таблицу.
Таблица КЛИЕНТОВ выглядит следующим образом.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Теперь позвольте нам присоединиться к этой таблице, используя SELF JOIN следующим образом:
SQL>  SELECT  a.ID, b.NAME, a.SALARY
   FROM CUSTOMERS a, CUSTOMERS b
   WHERE a.SALARY < b.SALARY;
Это приведет к следующему результату -
+ ---- + ---------- + --------- +
| ID | ИМЯ | SALARY |
+ ---- + ---------- + --------- +
| 2 | Рамеш | 1500,00 |
| 2 | Каушик | 1500,00 |
| 1 | Chaitali | 2000.00 |
| 2 | Chaitali | 1500,00 |
| 3 | Chaitali | 2000.00 |
| 6 | Chaitali | 4500,00 |
| 1 | Хардик | 2000.00 |
| 2 | Хардик | 1500,00 |
| 3 | Хардик | 2000.00 |
| 4 | Хардик | 6500,00 |
| 6 | Хардик | 4500,00 |
| 1 | Комаль | 2000.00 |
| 2 | Комаль | 1500,00 |
| 3 | Комаль | 2000.00 |
| 1 | Muffy | 2000.00 |
| 2 | Muffy | 1500,00 |
| 3 | Muffy | 2000.00 |
| 4 | Muffy | 6500,00 |
| 5 | Muffy | 8500,00 |
| 6 | Muffy | 4500,00 |
+ ---- + ---------- + --------- +






CARTESIAN JOIN - возвращает декартово произведение наборов записей из двух или более объединенных таблиц.
CARTESIAN JOIN или CROSS JOIN возвращает декартово произведение наборов записей из двух или более объединенных таблиц. Таким образом, он приравнивается к внутреннему соединению, где условие соединения всегда оценивается как True, или где условие соединения отсутствует в инструкции.

Синтаксис
Основной синтаксис CARTESIAN JOIN или CROSS JOIN заключается в следующем:

SELECT table1.column1, table2.column2 ...
FROM table1, table2 [, table3]
пример
Рассмотрим следующие две таблицы.

Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2: Таблица ORDERS выглядит следующим образом:
+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам, используя INNER JOIN следующим образом:
SQL>  SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS, ORDERS;
Это приведет к следующему результату -
+ ---- + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ---- + ---------- + -------- + --------------------- +
| 1 | Рамеш | 3000 | 2009-10-08 00:00:00 |
| 1 | Рамеш | 1500 | 2009-10-08 00:00:00 |
| 1 | Рамеш | 1560 | 2009-11-20 00:00:00 |
| 1 | Рамеш | 2060 | 2008-05-20 00:00:00 |
| 2 | Хилан | 3000 | 2009-10-08 00:00:00 |
| 2 | Хилан | 1500 | 2009-10-08 00:00:00 |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 2 | Хилан | 2060 | 2008-05-20 00:00:00 |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1560 | 2009-11-20 00:00:00 |
| 3 | Каушик | 2060 | 2008-05-20 00:00:00 |
| 4 | Chaitali | 3000 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Хардик | 3000 | 2009-10-08 00:00:00 |
| 5 | Хардик | 1500 | 2009-10-08 00:00:00 |
| 5 | Хардик | 1560 | 2009-11-20 00:00:00 |
| 5 | Хардик | 2060 | 2008-05-20 00:00:00 |
| 6 | Комаль | 3000 | 2009-10-08 00:00:00 |
| 6 | Комаль | 1500 | 2009-10-08 00:00:00 |
| 6 | Комаль | 1560 | 2009-11-20 00:00:00 |
| 6 | Комаль | 2060 | 2008-05-20 00:00:00 |
| 7 | Muffy | 3000 | 2009-10-08 00:00:00 |
| 7 | Muffy | 1500 | 2009-10-08 00:00:00 |
| 7 | Muffy | 1560 | 2009-11-20 00:00:00 |
| 7 | Muffy | 2060 | 2008-05-20 00:00:00 |
+ ---- + ---------- + -------- + --------------------- +








Оператор SQL UNION / оператор используется для объединения результатов двух или более операторов SELECT без возврата каких-либо повторяющихся строк.
Чтобы использовать это предложение UNION, каждый оператор SELECT должен иметь
Такое же количество выбранных столбцов
Такое же количество выражений столбцов
Тот же тип данных и
Имейте их в одном порядке
Но им не обязательно быть одинаковой длины.
Синтаксис
Основной синтаксис предложения UNION заключается в следующем:
SELECT column1 [, column2]
FROM table1 [, table2]
[WHEREусловие]
UNION
SELECT column1 [, column2]
FROM table1 [, table2]
[WHERE условие]
Здесь данное условие может быть любым заданным выражением, основанным на вашем требовании.
пример
Рассмотрим следующие две таблицы.
Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица ORDERS выглядит следующим образом.
+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам в инструкции SELECT следующим образом:

SQL>  SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату -
+ ------ + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ------ + ---------- + -------- + --------------------- +
| 1 | Рамеш | NULL | NULL |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Хардик | NULL | NULL |
| 6 | Комаль | NULL | NULL |
| 7 | Muffy | NULL | NULL |
+ ------ + ---------- + -------- + --------------------- +
Предложение UNION ALL
Оператор UNION ALL используется для объединения результатов двух операторов SELECT, включая повторяющиеся строки.
Те же правила, которые применяются к статье UNION, будут применяться к оператору UNION ALL.
Синтаксис
Основной синтаксис UNION ALL выглядит следующим образом.
SELECT column1 [, column2]
FROM table1 [, table2]
[WHERE условие]
UNION
SELECT column1 [, column2]
FROM table1 [, table2]
[WHERE условие]
Здесь данное условие может быть любым заданным выражением, основанным на вашем требовании.
пример
Рассмотрим следующие две таблицы,
Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - таблица ORDERS выглядит следующим образом.

+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам в инструкции SELECT следующим образом:

SQL>  SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION ALL
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату -
+ ------ + ---------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ------ + ---------- + -------- + --------------------- +
| 1 | Рамеш | NULL | NULL |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Хардик | NULL | NULL |
| 6 | Комаль | NULL | NULL |
| 7 | Muffy | NULL | NULL |
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 2 | Хилан | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+ ------ + ---------- + -------- + --------------------- +
Существуют два других предложения (т. Е. Операторы), которые похожи на предложение UNION.




SQL INTERSECT Clause - используется для объединения двух операторов SELECT, но возвращает строки только из первого оператора SELECT, которые идентичны строке во втором операторе SELECT.
Оператор SQL INTERSECT / оператор используется для объединения двух операторов SELECT, но возвращает строки только из первого оператора SELECT, которые идентичны строке во втором операторе SELECT. Это означает, что INTERSECT возвращает только обычные строки, возвращаемые двумя операторами SELECT.
Как и в случае с оператором UNION, применяются те же правила при использовании оператора INTERSECT. MySQL не поддерживает оператор INTERSECT.
Синтаксис
Основной синтаксис INTERSECT заключается в следующем.
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
INTERSECT
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
Здесь данное условие может быть любым заданным выражением, основанным на вашем требовании.
пример
Рассмотрим следующие две таблицы.
Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица ORDERS выглядит следующим образом.

+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам в инструкции SELECT следующим образом.
SQL>  SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
INTERSECT
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
Это приведет к следующему результату.
+ ------ + --------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ------ + --------- + -------- + --------------------- +
| 3 | Каушик | 3000 | 2009-10-08 00:00:00 |
| 3 | Каушик | 1500 | 2009-10-08 00:00:00 |
| 2 | Рамеш | 1560 | 2009-11-20 00:00:00 |
| 4 | Каушик | 2060 | 2008-05-20 00:00:00 |
+ ------ + --------- + -------- + --------------------- +






SQL EXCEPT Clause - объединяет два оператора SELECT и возвращает строки из первого оператора SELECT, которые не возвращаются вторым оператором SELECT.
Оператор SQL EXCEPT / operator используется для объединения двух операторов SELECT и возвращает строки из первого оператора SELECT, которые не возвращаются вторым оператором SELECT. Это означает, что EXCEPT возвращает только строки, которые недоступны во втором операторе SELECT.
Как и при использовании оператора UNION, те же правила применяются при использовании оператора EXCEPT. MySQL не поддерживает оператора EXCEPT.
Синтаксис
Основной синтаксис EXCEPT заключается в следующем.
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
EXCEPT
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
Здесь данное условие может быть любым заданным выражением, основанным на вашем требовании.
пример
Рассмотрим следующие две таблицы.
Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - таблица ORDERS выглядит следующим образом.
+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь давайте присоединимся к этим двум таблицам в инструкции SELECT, как показано ниже.
SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
EXCEPT
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Это приведет к следующему результату.
+ ---- + --------- + -------- + --------------------- +
| ID | ИМЯ | AMOUNT | DATE |
+ ---- + --------- + -------- + --------------------- +
| 1 | Рамеш | NULL | NULL |
| 5 | Хардик | NULL | NULL |
| 6 | Комаль | NULL | NULL |
| 7 | Muffy | NULL | NULL |
+ ---- + --------- + -------- + --------------------- +
	
	
	
	
SQL NULL - это термин, используемый для представления недостающего значения. Значение NULL в таблице - это значение в поле, которое выглядит пустым.
Поле со значением NULL является полем без значения. Очень важно понять, что значение NULL отличается от нулевого значения или поля, содержащего пробелы.
Синтаксис
Основной синтаксис NULL при создании таблицы.
SQL>  CREATE TABLE CUSTOMERS(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25) ,
   SALARY   DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);
Здесь NOT NULL означает, что столбец всегда должен принимать явное значение данного типа данных. Есть два столбца, где мы не использовали NOT NULL, что означает, что эти столбцы могут быть NULL.
Поле со значением NULL является тем, которое осталось пустым во время создания записи.
пример
Значение NULL может вызвать проблемы при выборе данных. Однако, поскольку при сравнении неизвестного значения с любым другим значением результат всегда неизвестен и не включен в результаты. Вы должны использовать операторы IS NULL или NOT NULL для проверки значения NULL.
Рассмотрим следующую таблицу КЛИЕНТОВ, имеющую записи, как показано ниже.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | |
| 7 | Muffy | 24 | Индор | |
+ ---- + ---------- + ----- + ----------- + ---------- +
Теперь следует использовать IS NOT NULLoperator.
SQL>  SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM CUSTOMERS
   WHERE SALARY IS NOT NULL;
Это приведет к следующему результату -
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Теперь следует использовать оператор IS NULL.
SQL>  SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM CUSTOMERS
   WHERE SALARY IS NULL;
Это приведет к следующему результату -
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 6 | Комаль | 22 | MP | |
| 7 | Muffy | 24 | Индор | |
+ ---- + ---------- + ----- + ----------- + ---------- +	
	
	
	
	
Вы можете переименовать таблицу или столбец временно, указав другое имя, известное как Alias. Использование псевдонимов таблиц заключается в переименовании таблицы в конкретный оператор SQL. Переименование - это временное изменение, и фактическое имя таблицы не изменяется в базе данных. Алиасы столбцов используются для переименования столбцов таблицы для конкретного запроса SQL.
Синтаксис
Основной синтаксис псевдонима таблицы следующий.
SELECT column1, column2 ....
FROM table_name AS alias_name
WHERE [условие];
Основной синтаксис псевдонима столбца следующий.
SELECT column_name AS alias_name
FROM table_name
WHERE [условие];
пример
Рассмотрим следующие две таблицы.
Таблица 1 - Таблица КЛИЕНТОВ выглядит следующим образом.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Таблица 2 - Таблица ORDERS выглядит следующим образом.
+ ----- + --------------------- + ------------- + ------- - +
| OID | DATE | CUSTOMER_ID | AMOUNT |
+ ----- + --------------------- + ------------- + ------- - +
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+ ----- + --------------------- + ------------- + ------- - +
Теперь следующий блок кода показывает использование псевдонима таблицы.
SQL>  SELECT C.ID, C.NAME, C.AGE, O.AMOUNT 
   FROM CUSTOMERS AS C, ORDERS AS O
   WHERE  C.ID = O.CUSTOMER_ID;
Это приведет к следующему результату.
+ ---- + ---------- + ----- + -------- +
| ID | ИМЯ | ВОЗРАСТ | AMOUNT |
+ ---- + ---------- + ----- + -------- +
| 3 | Каушик | 23 | 3000 |
| 3 | Каушик | 23 | 1500 |
| 2 | Хилан | 25 | 1560 |
| 4 | Chaitali | 25 | 2060 |
+ ---- + ---------- + ----- + -------- +
Ниже приводится использование псевдонима столбца.
SQL>  SELECT  ID AS CUSTOMER_ID, NAME AS CUSTOMER_NAME
   FROM CUSTOMERS
   WHERE SALARY IS NOT NULL;
Это приведет к следующему результату.
+ ------------- + --------------- +
| CUSTOMER_ID | CUSTOMER_NAME |
+ ------------- + --------------- +
| 1 | Рамеш |
| 2 | Хилан |
| 3 | Каушик |
| 4 | Chaitali |
| 5 | Хардик |
| 6 | Комаль |
| 7 | Muffy |
+ ------------- + --------------- +	
	
	
	
	
Индексы представляют собой специальные таблицы поиска, которые может использовать поисковая система базы данных для ускорения поиска данных. Проще говоря, индекс является указателем на данные в таблице. Индекс в базе данных очень похож на индекс в конце книги.
Например, если вы хотите ссылаться на все страницы в книге, в которой обсуждается определенная тема, сначала обратитесь к индексу, в котором перечислены все темы в алфавитном порядке и затем указаны один или несколько конкретных номеров страниц.
Индекс помогает ускорить запросы SELECT и WHERE, но это замедляет ввод данных с помощью операторов UPDATE и INSERT. Индексы могут быть созданы или удалены без влияния на данные.
Создание индекса включает оператор CREATE INDEX, который позволяет вам указывать индекс, указывать таблицу и столбцы или столбцы для индексации, а также указывать, находится ли индекс в порядке возрастания или убывания.
Индексы также могут быть уникальными, такими как ограничение UNIQUE, в том, что индекс предотвращает дублирование записей в столбце или комбинации столбцов, на которых есть индекс.
Команда CREATE INDEX
Основной синтаксис CREATE INDEX заключается в следующем.

CREATE INDEX index_name ON table_name;
Одиночные колонки
Индекс с одним столбцом создается на основе только одного столбца таблицы. Основной синтаксис следующий.

CREATE INDEX index_name
ON table_name (column_name);
Уникальные индексы
Уникальные индексы используются не только для производительности, но и для целостности данных. Уникальный индекс не позволяет вставлять повторяющиеся значения в таблицу. Основной синтаксис следующий.

CREATE UNIQUE INDEX index_name
On table_name (column_name);
Композитные индексы
Составной индекс - это индекс на двух или более столбцах таблицы. Его основной синтаксис выглядит следующим образом.

CREATE INDEX index_name
На table_name (column1, column2);
Чтобы создать индекс с одним столбцом или составной индекс, учитывайте столбцы (столбцы), которые вы можете использовать очень часто в предложении WHERE запроса в качестве условий фильтра.

Если используется только один столбец, должен быть выбран один столбцовый индекс. Если есть два или более столбца, которые часто используются в предложении WHERE в качестве фильтров, лучшим вариантом будет составной индекс.
Неявные индексы
Неявные индексы - это индексы, которые автоматически создаются сервером базы данных при создании объекта. Индексы автоматически создаются для ограничений первичного ключа и уникальных ограничений.
Команда DROP INDEX
Индекс можно отбросить с помощью команды SQL DROP. Следует проявлять осторожность при снижении индекса, поскольку производительность может замедляться или улучшаться.
Основной синтаксис заключается в следующем:

DROP INDEX index_name;
Вы можете проверить главу INDEX Constraint, чтобы увидеть некоторые фактические примеры индексов.

Когда следует избегать индексов?
Хотя индексы предназначены для повышения производительности базы данных, бывают случаи, когда их следует избегать.
Следующие рекомендации указывают на необходимость пересмотра использования индекса.
Индексы не должны использоваться на небольших таблицах.
Таблицы, в которых есть частые, большие обновления партии или операции вставки.
Индексы не должны использоваться в столбцах, содержащих большое количество значений NULL.
Столбцы, которые часто обрабатываются, не должны индексироваться.	
	
	
	
	
	
	
Команда SQL ALTER TABLE используется для добавления, удаления или изменения столбцов в существующей таблице. Вы также должны использовать команду ALTER TABLE для добавления и удаления различных ограничений в существующей таблице.
Синтаксис
Основной синтаксис команды ALTER TABLE для добавления нового столбца в существующую таблицу выглядит следующим образом.

ALTER TABLE имя_таблицы ADD имя_столбца datatype;
Основной синтаксис команды ALTER TABLE для DROP COLUMN в существующей таблице выглядит следующим образом.

ALTER TABLE имя_таблицы DROP COLUMN column_name;
Основной синтаксис команды ALTER TABLE для изменения ТИПА DATA столбца в таблице выглядит следующим образом.

ALTER TABLE имя_таблицы MODIFY COLUMN column_name datatype;
Основной синтаксис команды ALTER TABLE для добавления ограничения NOT NULL в столбец в таблице выглядит следующим образом.

ALTER TABLE имя_таблицы MODIFY column_name datatype NOT NULL;
Основной синтаксис ALTER TABLE для добавления UNIQUE CONSTRAINT к таблице следующий.

ALTER TABLE имя_таблицы
ADD CONSTRAINT MyUniqueConstraint UNIQUE (column1, column2 ...);
Основной синтаксис команды ALTER TABLE для ADD CHECK CONSTRAINT для таблицы выглядит следующим образом.

ALTER TABLE имя_таблицы
ADD CONSTRAINT MyUniqueConstraint CHECK (CONDITION);
Основной синтаксис команды ALTER TABLE для ограничения ADD PRIMARY KEY для таблицы выглядит следующим образом.

ALTER TABLE имя_таблицы
ADD CONSTRAINT MyPrimaryKey ПЕРВИЧНЫЙ КЛЮЧ (column1, column2 ...);
Основной синтаксис команды ALTER TABLE для DROP CONSTRAINT из таблицы следующий.

ALTER TABLE имя_таблицы
DROP CONSTRAINT MyUniqueConstraint;
Если вы используете MySQL, код выглядит следующим образом:

ALTER TABLE имя_таблицы
DROP INDEX MyUniqueConstraint;
Основной синтаксис команды ALTER TABLE для ограничения DROP PRIMARY KEY из таблицы выглядит следующим образом.

ALTER TABLE имя_таблицы
DROP CONSTRAINT MyPrimaryKey;
Если вы используете MySQL, код выглядит следующим образом:

ALTER TABLE имя_таблицы
DROP PRIMARY KEY;
пример
Рассмотрим таблицу CUSTOMERS, имеющую следующие записи:

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Ниже приведен пример добавления нового столбца к существующей таблице -

ALTER TABLE CUSTOMERS ADD SEX char (1);
Теперь таблица CUSTOMERS изменена, и последующие будут выводиться из инструкции SELECT.

+ ---- + --------- + ----- + ----------- + ---------- + ----- - +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | СЕКС |
+ ---- + --------- + ----- + ----------- + ---------- + ----- - +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 | NULL |
| 2 | Рамеш | 25 | Дели | 1500,00 | NULL |
| 3 | Каушик | 23 | Кота | 2000.00 | NULL |
| 4 | Каушик | 25 | Мумбаи | 6500,00 | NULL |
| 5 | Хардик | 27 | Бхопал | 8500,00 | NULL |
| 6 | Комаль | 22 | MP | 4500,00 | NULL |
| 7 | Muffy | 24 | Индор | 10000,00 | NULL |
+ ---- + --------- + ----- + ----------- + ---------- + ----- - +
Ниже приведен пример столбца DROP sex из существующей таблицы.
ALTER TABLE CUSTOMERS DROP SEX;
Теперь таблица CUSTOMERS изменена, и последующий результат будет выводиться из инструкции SELECT.	
+ ---- + --------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + --------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Рамеш | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Каушик | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + --------- + ----- + ----------- + ---------- +	
	
	
	
	
	
Команда SQL TRUNCATE TABLE используется для удаления полных данных из существующей таблицы.
Вы также можете использовать команду DROP TABLE для удаления полной таблицы, но она приведет к удалению полной структуры таблицы из базы данных, и вам нужно будет повторно создать эту таблицу еще раз, если вы хотите сохранить некоторые данные.
Синтаксис
Основной синтаксис команды TRUNCATE TABLE выглядит следующим образом.

TRUNCATE TABLE имя_таблицы;
пример
Рассмотрим таблицу CUSTOMERS, имеющую следующие записи:

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Ниже приведен пример команды Truncate.
SQL> TRUNCATE TABLE CUSTOMERS;
Теперь таблица CUSTOMERS усекается, и вывод из инструкции SELECT будет таким, как показано в блоке кода ниже -

SQL> SELECT * FROM CUSTOMERS;
Пустой набор (0,00 сек)	
	
	
	
	
	
	
	
VIEW - это не что иное, как оператор SQL, который хранится в базе данных с соответствующим именем. На самом деле представление представляет собой состав таблицы в виде предопределенного SQL-запроса.
VIEW может содержать все строки таблицы или выбирать строки из таблицы. Представление может быть создано из одной или многих таблиц, которая зависит от написанного SQL-запроса для создания представления.
VIEW, которые являются типом виртуальных таблиц, позволяют пользователям делать следующее:
Структурируйте данные таким образом, чтобы пользователи или классы пользователей находили естественные или интуитивные.
Ограничьте доступ к данным таким образом, чтобы пользователь мог видеть и (иногда) изменять то, что им нужно, и не более того.
Суммируйте данные из разных таблиц, которые могут использоваться для создания отчетов.
Создание представлений
Представления базы данных создаются с помощью инструкции CREATE VIEW. Представления могут быть созданы из одной таблицы, нескольких таблиц или другого представления.
Чтобы создать представление, пользователь должен иметь соответствующие системные привилегии в соответствии с конкретной реализацией.
Основной синтаксис CREATE VIEW выглядит следующим образом:

CREATE VIEW view_name AS
SELECT column1, column2 .....
FROM table_name
WHERE [условие];
Вы можете включить несколько таблиц в оператор SELECT так же, как вы используете их в обычном запросе SQL SELECT.

пример
Рассмотрим таблицу CUSTOMERS, имеющую следующие записи:

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Ниже приведен пример создания представления из таблицы CUSTOMERS. Это представление будет использоваться для указания имени клиента и возраста из таблицы CUSTOMERS.

SQL>  CREATE VIEW CUSTOMERS_VIEW AS
SELECT имя, возраст
FROM  CUSTOMERS;
Теперь вы можете запросить CUSTOMERS_VIEW так же, как вы запрашиваете фактическую таблицу. Ниже приведен пример того же.

SQL>  SELECT * FROM CUSTOMERS_VIEW;
Это приведет к следующему результату.
+ ---------- + ----- +
| Имя | Возраст |
+ ---------- + ----- +
| Рамеш | 32 |
| Хилан | 25 |
| Каушик | 23 |
| Chaitali | 25 |
| Хардик | 27 |
| Комаль | 22 |
| Muffy | 24 |
+ ---------- + ----- +
Опция WITH CHECK OPTION
Параметр WITH CHECK OPTION является опцией CREATE VIEW. Назначение опции WITH CHECK OPTION - гарантировать, что все UPDATE и INSERT удовлетворяют условиям (условиям) определения.
Если они не удовлетворяют условию (-ам), UPDATE или INSERT возвращает ошибку.
Следующий блок кода имеет пример создания такого же представления CUSTOMERS_VIEW с опцией WITH CHECK OPTION.

CREATE VIEW CUSTOMERS_VIEW AS
SELECT имя, возраст
FROM  CUSTOMERS
WHERE age IS NOT NULL
WITH CHECK OPTION;

Параметр WITH CHECK OPTION в этом случае должен отказать в записи любых значений NULL в столбце AGE представления, поскольку представление определяется данными, которые не имеют значения NULL в столбце AGE.
Обновление View
Представление может быть обновлено при определенных условиях, которые приведены ниже -
Предложение SELECT может не содержать ключевое слово DISTINCT.
Предложение SELECT может не содержать сводных функций.
Предложение SELECT может не содержать заданных функций.
Предложение SELECT может не содержать операторов набора.
Предложение SELECT не может содержать предложение ORDER BY.
Предложение FROM может не содержать несколько таблиц.
Предложение WHERE может не содержать подзапросов.
Запрос может не содержать GROUP BY или HAVING.
Вычисленные столбцы не могут быть обновлены.
Все NOT NULL столбцы из базовой таблицы должны быть включены в представление, чтобы запрос INSERT функционировал.
Таким образом, если представление удовлетворяет всем вышеупомянутым правилам, вы можете обновить это представление. В следующем блоке кода показан пример обновления возраста Ramesh.

SQL>  UPDATE CUSTOMERS_VIEW
   SET AGE = 35
   WHERE name = 'Ramesh';
Это, в конечном счете, обновит базовые таблицы CUSTOMERS, и то же самое отразится на самом представлении. Теперь попробуйте запросить базовую таблицу, и инструкция SELECT приведет к следующему результату.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 35 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Вставка строк в представление(VIEW)
Строки данных могут быть вставлены в представление. Те же правила, которые применяются к команде UPDATE, также применяются к команде INSERT.
Здесь мы не можем вставлять строки в CUSTOMERS_VIEW, потому что мы не включили в это представление все столбцы NOT NULL, иначе вы можете вставлять строки в представление так же, как вы вставляете их в таблицу.
Удаление строк в представлении
Строки данных могут быть удалены из представления. Те же правила, которые применяются к командам UPDATE и INSERT, применяются к команде DELETE.
Ниже приведен пример удаления записи с AGE = 22.

SQL> DELETE FROM CUSTOMERS_VIEW
   WHERE age = 22;
Это в конечном итоге удалит строку из базовой таблицы CUSTOMERS, и это будет отражено в самом представлении. Теперь попробуйте запросить базовую таблицу, и инструкция SELECT приведет к следующему результату.

+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 35 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Удаление просмотров
Очевидно, что если у вас есть представление, вам нужно отбросить представление, если он больше не нужен. Синтаксис очень прост и приведен ниже:
DROP VIEW view_name;
Ниже приведен пример, чтобы удалить CUSTOMERS_VIEW из таблицы CUSTOMERS.
DROP VIEW CUSTOMERS_VIEW;
	
	
	
	
	
	
	
Предложение HAVING позволяет указать условия, которые фильтруют результаты группы в результатах.
Предложение WHERE устанавливает условия для выбранных столбцов, тогда как предложение HAVING устанавливает условия для групп, созданных в предложении GROUP BY.
Синтаксис
Следующий код-блок показывает позицию предложения HAVING в запросе.
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
Предложение HAVING должно следовать предложении GROUP BY в запросе и также должно предшествовать предложению ORDER BY, если оно используется. Следующий блок кода имеет синтаксис инструкции SELECT, включая предложение HAVING -

SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2
пример
Рассмотрим таблицу CUSTOMERS, имеющую следующие записи.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Ниже приведен пример, в котором будет отображаться запись для аналогичного возраста, которая будет больше или равна 2.
SQL>  SELECT ID, NAME, AGE, ADDRESS, SALARY
FROM CUSTOMERS
GROUP BY age
HAVING COUNT(age) >= 2;
Это приведет к следующему результату -
+ ---- + -------- + ----- + --------- + --------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + -------- + ----- + --------- + --------- +
| 2 | Хилан | 25 | Дели | 1500,00 |
+ ---- + -------- + ----- + --------- + --------- +	
	
	
	
	
	
	
	
	
	
Транзакция - это единица работы, выполняемая в отношении базы данных. Транзакции - это единицы или последовательности работы, выполненные в логическом порядке, будь то вручную или автоматически с помощью какой-либо программы базы данных.
Транзакция - это распространение одного или нескольких изменений в базе данных. Например, если вы создаете запись или обновляете запись или удаляете запись из таблицы, вы выполняете транзакцию в этой таблице. Важно контролировать эти транзакции, чтобы обеспечить целостность данных и обрабатывать ошибки базы данных.
Практически, вы соберете множество SQL-запросов в группу, и вы будете выполнять их все вместе как часть транзакции.
Свойства транзакций
Транзакции имеют следующие четыре стандартных свойства, на которые обычно ссылается акроним ACID.
Атомность - гарантирует, что все операции в рабочем блоке будут успешно завершены. В противном случае транзакция прерывается в момент сбоя, а все предыдущие операции возвращаются в прежнее состояние.
Согласованность - гарантирует, что база данных правильно изменяет состояния при успешной транзакции.
Изоляция - позволяет транзакциям работать независимо друг от друга и прозрачно.
Долговечность - гарантирует, что результат или эффект совершенной транзакции сохранится в случае сбоя системы.
Управление транзакциями
Для управления транзакциями используются следующие команды.
COMMIT - сохранение изменений.
ROLLBACK - отменить изменения.
SAVEPOINT - создает точки в группах транзакций, в которых ROLLBACK.
SET TRANSACTION - Помещает имя в транзакцию.
Команды управления транзакциями
Команды управления транзакциями используются только с командами DML, такими как: INSERT, UPDATE и DELETE. Они не могут использоваться при создании таблиц или их удалении, поскольку эти операции автоматически фиксируются в базе данных.
Команда COMMIT
Команда COMMIT - это транзакционная команда, используемая для сохранения изменений, вызванных транзакцией, в базу данных.
Команда COMMIT - это транзакционная команда, используемая для сохранения изменений, вызванных транзакцией, в базу данных. Команда COMMIT сохраняет все транзакции в базе данных с момента последней команды COMMIT или ROLLBACK.
Синтаксис команды COMMIT следующий.

COMMIT;
пример

Рассмотрим таблицу CUSTOMERS, имеющую следующие записи:
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Ниже приведен пример, который удалит эти записи из таблицы с возрастом = 25, а затем COMMIT изменения в базе данных.

SQL> DELETE FROM CUSTOMERS
   WHERE AGE = 25;
SQL> COMMIT;
Таким образом, две строки из таблицы будут удалены, и оператор SELECT произведет следующий результат.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Команда ROLLBACK
Команда ROLLBACK представляет собой транзакционную команду, используемую для отмены транзакций, которые еще не были сохранены в базе данных. Эта команда может использоваться только для отмены транзакций с момента выдачи последней команды COMMIT или ROLLBACK.
Синтаксис команды ROLLBACK следующий:
ROLLBACK;
пример
Рассмотрим таблицу CUSTOMERS, имеющую следующие записи:
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Ниже приведен пример, который удалит те записи из таблицы, у которых возраст = 25, а затем ROLLBACK - изменения в базе данных.
SQL> DELETE FROM CUSTOMERS
   WHERE AGE = 25;
SQL> ROLLBACK;
Таким образом, операция удаления не повлияет на таблицу, и оператор SELECT приведет к следующему результату.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Команда SAVEPOINT
SAVEPOINT - это точка транзакции, когда вы можете перевести транзакцию обратно в определенную точку, не откатывая всю транзакцию.
Синтаксис команды SAVEPOINT приведен ниже.
SAVEPOINT SAVEPOINT_NAME;
Эта команда служит только для создания SAVEPOINT среди всех транзакционных операторов. Команда ROLLBACK используется для отмены группы транзакций.
Синтаксис для возврата к SAVEPOINT приведен ниже.
ROLLBACK TO SAVEPOINT_NAME;
Ниже приведен пример, когда вы планируете удалить три разных записи из таблицы CUSTOMERS. Вы хотите создать SAVEPOINT перед каждым удалением, чтобы вы могли ROLLBACK в любой SAVEPOINT в любое время, чтобы вернуть соответствующие данные в исходное состояние.
пример
Рассмотрим таблицу CUSTOMERS, имеющую следующие записи.
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 1 | Рамеш | 32 | Ахмедабад | 2000.00 |
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Следующий блок кода содержит ряд операций.

SQL> SAVEPOINT SP1;
Создано Savepoint.
SQL> УДАЛИТЬ ОТ КЛИЕНТОВ ГДЕ ID = 1;
1 строка удалена.
SQL> SAVEPOINT SP2;
Создано Savepoint.
SQL> УДАЛИТЬ ОТ КЛИЕНТОВ ГДЕ ID = 2;
1 строка удалена.
SQL> SAVEPOINT SP3;
Создано Savepoint.
SQL> УДАЛИТЬ ОТ КЛИЕНТОВ ГДЕ ID = 3;
1 строка удалена.
Теперь, когда три удаления произошли, предположим, что вы передумали и решили ROLLBACK на SAVEPOINT, который вы определили как SP2. Поскольку SP2 был создан после первого удаления, последние два удаления отменены -
SQL> ROLLBACK TO SP2;
Откат завершен.
Обратите внимание, что только первое удаление произошло после того, как вы вернулись к SP2.
SQL> SELECT * FROM CUSTOMERS;
+ ---- + ---------- + ----- + ----------- + ---------- +
| ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY |
+ ---- + ---------- + ----- + ----------- + ---------- +
| 2 | Хилан | 25 | Дели | 1500,00 |
| 3 | Каушик | 23 | Кота | 2000.00 |
| 4 | Chaitali | 25 | Мумбаи | 6500,00 |
| 5 | Хардик | 27 | Бхопал | 8500,00 |
| 6 | Комаль | 22 | MP | 4500,00 |
| 7 | Muffy | 24 | Индор | 10000,00 |
+ ---- + ---------- + ----- + ----------- + ---------- +
Выбрано 6 строк.
Команда RELEASE SAVEPOINT
Команда RELEASE SAVEPOINT используется для удаления созданного SAVEPOINT.
Синтаксис команды RELEASE SAVEPOINT следующий.
RELEASE SAVEPOINT SAVEPOINT_NAME;
Как только SAVEPOINT будет выпущен, вы больше не сможете использовать команду ROLLBACK для отмены транзакций, выполненных с момента последнего SAVEPOINT.
Команда SET TRANSACTION
Команда SET TRANSACTION может использоваться для инициирования транзакции базы данных. Эта команда используется для указания характеристик для последующей транзакции. Например, вы можете указать транзакцию только для чтения или читать запись.
Синтаксис команды SET TRANSACTION следующий.
SET TRANSACTION [ READ WRITE | READ ONLY ];
	
	
	
	
Мы уже обсуждали оператор SQL LIKE, который используется для сравнения значения с аналогичными значениями с помощью подстановочных операторов.
SQL поддерживает два подстановочных оператора в сочетании с оператором LIKE, которые подробно описаны в следующей таблице.	
Sr.No. Wildcard & Description
1 Знак процента (%) Соответствует одному или нескольким символам. Примечание. MS Access использует символ подстановки звездочки (*) вместо символа подстановочного знака (%).
2 Подчеркивание (_) Соответствует одному символу. Примечание. MS Access использует знак вопроса (?) Вместо подчеркивания (_) для соответствия любому символу.
Знак процента представляет нуль, один или несколько символов. Подчеркивание представляет собой одиночное число или символ. Эти символы могут использоваться в комбинациях. Синтаксис Основной синтаксис оператора «%» и «_» заключается в следующем. SELECT FROM table_name WHERE column LIKE 'XXXX%' или SELECT FROM table_name WHERE column LIKE '% XXXX%' или SELECT FROM table_name WHERE column LIKE 'XXXX_' или SELECT FROM table_name WHERE column LIKE '_XXXX' или SELECT FROM table_name WHERE column LIKE '_XXXX_' Вы можете объединить N число условий с помощью операторов AND или OR. Здесь XXXX может быть любым числовым или строковым значением. пример В следующей таблице приведен ряд примеров, показывающих, что часть WHERE имеет разные предложения LIKE с операторами «%» и «_».
Sr.No. Statement & Description
1 WHERE SALARY LIKE «200%» Находит любые значения, начинающиеся с 200.
2 WHERE SALARY LIKE '% 200%' Находит любые значения, которые имеют 200 в любой позиции.
3 WHERE SALARY LIKE '_00%' Находит любые значения, которые имеют 00 во второй и третьей позициях.
4 WHERE SALARY LIKE '2 _% _%' Находит любые значения, начинающиеся с 2 и длиной не менее 3 символов.
5 WHERE SALARY LIKE '% 2' Находит любые значения, заканчивающиеся на 2.
6 WHERE SALARY LIKE '_2% 3' Находит любые значения, которые имеют 2 во второй позиции и заканчиваются на 3.
7 WHERE SALARY LIKE '2___3' Находит любые значения в пятизначном числе, начинающемся с 2, и заканчивается на 3.
Возьмем реальный пример, рассмотрим таблицу CUSTOMERS, имеющую следующие записи. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Следующий пример кода - это пример, который отображает все записи из таблицы CUSTOMERS, где SALARY начинается с 200. SQL> SELECT * FROM CUSTOMERS WHERE SALARY LIKE '200%'; Это приведет к следующему результату. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 3 | Каушик | 23 | Кота | 2000.00 | + ---- + ---------- + ----- + ----------- + ---------- + В следующей таблице приведен список всех важных функций, связанных с Date and Time, доступных через SQL. Существуют различные другие функции, поддерживаемые вашей RDBMS. Данный список основан на СУБД MySQL.
Sr.No. Function & Description
1 ADDDATE() Добавляет даты
2 ADDTIME() Добавляет время
3 CONVERT_TZ() Преобразование из одного часового пояса в другое
4 CURDATE() Возвращает текущую дату
5 CURRENT_DATE(), CURRENT_DATE Синонимы для CURDATE ()
6 CURRENT_TIME(), CURRENT_TIME Синонимы для CURTIME ()
7 CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP Синонимы для NOW ()
8 CURTIME() Возвращает текущее время
9 DATE_ADD() Добавляет две даты
10 DATE_FORMAT() Форматирует дату, указанную
11 DATE_SUB() Вычитает две даты
12 DATE() Извлекает часть даты выражения даты или даты и времени.
13 DATEDIFF() Вычитает две даты
14 DAY() Синонимы для DAYOFMONTH ()
15 DAYNAME() Возвращает имя дня недели
16 DAYOFMONTH() Возвращает день месяца (1-31)
17 DAYOFWEEK() Возвращает индекс дня недели аргумента
18 DAYOFYEAR() Возвращает день года (1-366)
19 EXTRACT Извлекает часть даты
20 FROM_DAYS() Преобразует номер дня в дату
21 FROM_UNIXTIME() Форматирует дату как временную метку UNIX
22 HOUR() Извлекает час
23 LAST_DAY Возвращает последний день месяца для аргумента
24 LOCALTIME(), LOCALTIME Синоним для NOW ()
25 LOCALTIMESTAMP, LOCALTIMESTAMP() Синоним для NOW ()
26 MAKEDATE() Создает дату из года и дня года
27 MAKETIME MAKETIME()
28 MICROSECOND() Возвращает микросекунды из аргумента
29 MINUTE() Возвращает минуту из аргумента
30 MONTH() Возврат месяца с даты
31 MONTHNAME() Возвращает название месяца
32 NOW() Возвращает текущую дату и время
33 PERIOD_ADD() Добавляет период до года
34 PERIOD_DIFF() Возвращает количество месяцев между периодами
35 QUARTER() Возвращает четверть из аргумента date
36 SEC_TO_TIME() Преобразует секунды в формат «HH: MM: SS»
37 SECOND() Возвращает вторую (0-59)
38 STR_TO_DATE() Преобразует строку в дату
39 SUBDATE() При вызове с тремя аргументами синоним DATE_SUB ()
40 SUBTIME() Вычитает время
41 SYSDATE() Возвращает время выполнения функции
42 TIME_FORMAT() Форматы как время
43 TIME_TO_SEC() Возвращает аргумент, преобразованный в секундах
44 TIME() Извлекает временную часть переданного выражения
45 TIMEDIFF() Вычитает время
46 TIMESTAMP() С помощью одного аргумента эта функция возвращает выражение даты или даты и времени. С двумя аргументами сумма аргументов
47 TIMESTAMPADD() Добавляет интервал к выражению datetime
48 TIMESTAMPDIFF() Вычитает интервал из выражения datetime
49 TO_DAYS() Возвращает аргумент даты, преобразованный в дни
50 UNIX_TIMESTAMP() Возвращает временную метку UNIX
51 UTC_DATE() Возвращает текущую дату UTC
52 UTC_TIME() Возвращает текущее время UTC
53 UTC_TIMESTAMP() Возвращает текущую дату и время UTC
54 WEEK() Возвращает номер недели
55 WEEKDAY() Возвращает индекс недели недели
56 WEEKOFYEAR() Возвращает календарную неделю даты (1-53)
57 YEAR() Возвращает год
58 YEARWEEK() Возвращает год и неделю
ADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days) При вызове с формой INTERVAL второго аргумента ADDDATE () является синонимом DATE_ADD (). Связанная функция SUBDATE () является синонимом DATE_SUB (). Информацию об аргументе элемента INTERVAL см. В обсуждении для DATE_ADD (). Mysql> SELECT DATE_ADD ('1998-01-02', INTERVAL 31 DAY); + ------------------------------------------------- -------- + | DATE_ADD ('1998-01-02', INTERVAL 31 DAY) | + ------------------------------------------------- -------- + | 1998-02-02 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT ADDDATE ('1998-01-02', INTERVAL 31 DAY); + ------------------------------------------------- -------- + | ADDDATE ('1998-01-02', INTERVAL 31 DAY) | + ------------------------------------------------- -------- + | 1998-02-02 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) При вызове с формой дней второго аргумента MySQL рассматривает его как целое число дней, которое нужно добавить в выражение. Mysql> SELECT ADDDATE ('1998-01-02', 31); + ------------------------------------------------- -------- + | DATE_ADD ('1998-01-02', INTERVAL 31 DAY) | + ------------------------------------------------- -------- + | 1998-02-02 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) AddTime (выражение1, выражение2) ADDTIME () добавляет expr2 в expr1 и возвращает результат. Expr1 - выражение времени или даты и времени, а expr2 - выражение во времени. Mysql> SELECT ADDTIME ('1997-12-31 23: 59: 59.999999', '1 1: 1: 1.000002'); + ------------------------------------------------- -------- + | DATE_ADD ('1997-12-31 23: 59: 59.999999', '1 1: 1: 1.000002') | + ------------------------------------------------- -------- + | 1998-01-02 01: 01: 01.000001 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) CONVERT_TZ (дт, from_tz, to_tz) Это преобразует значение dt-времени dt из часового пояса, заданного from_tz, в часовой пояс, заданный to_tz, и возвращает полученное значение. Эта функция возвращает NULL, если аргументы недействительны. Mysql> SELECT CONVERT_TZ ('2004-01-01 12:00:00', 'GMT', 'MET'); + ------------------------------------------------- -------- + | CONVERT_TZ ('2004-01-01 12:00:00', 'GMT', 'MET') | + ------------------------------------------------- -------- + | 2004-01-01 13:00:00 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT CONVERT_TZ ('2004-01-01 12:00:00', '+ 00:00', '+ 10:00'); + ------------------------------------------------- -------- + | CONVERT_TZ ('2004-01-01 12:00:00', '+ 00:00', '+ 10:00') | + ------------------------------------------------- -------- + | 2004-01-01 22:00:00 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) CURDATE () Возвращает текущую дату как значение в формате «YYYY-MM-DD» или YYYYMMDD, в зависимости от того, используется ли функция в строке или в числовом контексте. Mysql> SELECT CURDATE (); + ------------------------------------------------- -------- + | CURDATE () | + ------------------------------------------------- -------- + | 1997-12-15 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT CURDATE () + 0; + ------------------------------------------------- -------- + | CURDATE () + 0 | + ------------------------------------------------- -------- + | 19971215 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) CURRENT_DATE и CURRENT_DATE () CURRENT_DATE и CURRENT_DATE () являются синонимами для CURDATE () CURTIME () Возвращает текущее время как значение в формате «HH: MM: SS» или HHMMSS, в зависимости от того, используется ли эта функция в строке или в числовом контексте. Значение выражается в текущем часовом поясе. Mysql> SELECT CURTIME (); + ------------------------------------------------- -------- + | CURTIME () | + ------------------------------------------------- -------- + | 23:50:26 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT CURTIME () + 0; + ------------------------------------------------- -------- + | CURTIME () + 0 | + ------------------------------------------------- -------- + | 235026 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) CURRENT_TIME and CURRENT_TIME() CURRENT_TIME and CURRENT_TIME() are synonyms for CURTIME(). CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW(). DATE(expr) Extracts the date part of the date or datetime expression expr. mysql> SELECT DATE('2003-12-31 01:02:03'); +---------------------------------------------------------+ | DATE('2003-12-31 01:02:03') | +---------------------------------------------------------+ | 2003-12-31 | +---------------------------------------------------------+ 1 row in set (0.00 sec) DATEDIFF(expr1,expr2) DATEDIFF() returns expr1 . expr2 expressed as a value in days from one date to the other. Both expr1 and expr2 are date or date-and-time expressions. Only the date parts of the values are used in the calculation. mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30'); +---------------------------------------------------------+ | DATEDIFF('1997-12-31 23:59:59','1997-12-30') | +---------------------------------------------------------+ | 1 | +---------------------------------------------------------+ 1 row in set (0.00 sec) DATE_ADD(date,INTERVAL expr unit), DATE_SUB(date,INTERVAL expr unit) These functions perform date arithmetic. The date is a DATETIME or DATE value specifying the starting date. The expr is an expression specifying the interval value to be added or subtracted from the starting date. The expr is a string; it may start with a '-' for negative intervals. A unit is a keyword indicating the units in which the expression should be interpreted. The INTERVAL keyword and the unit specifier are not case sensitive. Значения QUARTER и WEEK доступны из MySQL 5.0.0. версия. Mysql> SELECT DATE_ADD ('1997-12-31 23:59:59',    -> INTERVAL '1: 1' MINUTE_SECOND); + ------------------------------------------------- -------- + | DATE_ADD ('1997-12-31 23:59:59', INTERVAL ... | + ------------------------------------------------- -------- + | 1998-01-01 00:01:00 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT DATE_ADD ('1999-01-01', INTERVAL 1 HOUR); + ------------------------------------------------- -------- + | DATE_ADD ('1999-01-01', INTERVAL 1 HOUR) | + ------------------------------------------------- -------- + | 1999-01-01 01:00:00 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) DATE_FORMAT (дата, формат) Эта команда форматирует значение даты в соответствии с строкой формата. В строке формата могут использоваться следующие спецификаторы. Символ '%' требуется перед символами спецификатора формата.
Sr.No. Specifier & Description
1 %a Сокращенное название дня недели (Sun..Sat)
2 %b Сокращенное название месяца (Jan..Dec)
3 %c Месяц, числовое (0,12)
4 %D День месяца с английским суффиксом (0, 1, 2, 3,.)
5 %d День месяца, числовое (00..31)
6 %e День месяца, числовое (0..31)
7 %f Микросекунды (000000..999999)
8 %H Час (00..23)
9 %h Час (01..12)
10 %I Час (01..12)
11 %i Минуты, числовые (00..59)
12 %j День года (001..366)
13 %k Час (0..23)
14 %l Час (1..12)
15 %M Название месяца (January..December)
16 %m Месяц, числовое (00..12)
17 %p До или после полудня
18 %r Время, 12 часов (чч: мм: сс, за которым следуют AM или PM)
19 %S Секунды (00..59)
20 %s Секунды (00..59)
21 %T Время, 24 часа (чч: мм: сс)
22 %U Неделя (00..53), где воскресенье - первый день недели
23 %u Неделя (00..53), где понедельник - первый день недели
24 %V Неделя (01..53), где воскресенье - первый день недели; Используется с% X
25 %v Неделя (01..53), где понедельник - первый день недели; Используется с% x
26 %W Название дня (воскресенье ... Суббота)
27 %w День недели (0 = воскресенье..6 = суббота)
28 %X Год на неделю, где воскресенье - первый день недели, числовые, четыре цифры; Используется с% V
29 %x Год на неделю, где понедельник - первый день недели, числовые, четыре цифры; Используется с% v
30 %Y Год, число, четыре цифры
31 %y Год, числовое (две цифры)
32 %% Литерал.%. персонаж
33 %x X, для any.x. Не перечисленные выше
Mysql> SELECT DATE_FORMAT ('1997-10-04 22:23:00', '% W% M% Y'); + ------------------------------------------------- -------- + | DATE_FORMAT ('1997-10-04 22:23:00', '% W% M% Y') | + ------------------------------------------------- -------- + | Суббота Октябрь 1997 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT DATE_FORMAT ('1997-10-04 22:23:00'    -> '% H% k% I% r% T% S% w'); + ------------------------------------------------- -------- + | DATE_FORMAT ('1997-10-04 22:23:00 ....... | + ------------------------------------------------- -------- + | 22 22 10 10:23:00 PM 22:23:00 00 6 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) DATE_SUB (дата, единица измерения INTERVAL) Это похоже на функцию DATE_ADD (). ДЕНЬ (дата) DAY () является синонимом функции DAYOFMONTH (). DAYNAME (дата) Возвращает имя дня недели для даты. Mysql> SELECT DAYNAME ('1998-02-05'); + ------------------------------------------------- -------- + | DAYNAME ('1998-02-05') | + ------------------------------------------------- -------- + | Четверг | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) DAYOFMONTH (дата) Возвращает день месяца для даты в диапазоне от 0 до 31. Mysql> SELECT DAYOFMONTH ('1998-02-03'); + ------------------------------------------------- -------- + | DAYOFMONTH ('1998-02-03') | + ------------------------------------------------- -------- + | 3 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) DAYOFWEEK (дата) Возвращает индекс недели дня (1 = воскресенье, 2 = понедельник,., 7 = суббота). Эти значения индекса соответствуют стандарту ODBC. Mysql> SELECT DAYOFWEEK ('1998-02-03'); + ------------------------------------------------- -------- + | DAYOFWEEK ('1998-02-03') | + ------------------------------------------------- -------- + | 3 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) DAYOFYEAR (дата) Возвращает день года для даты в диапазоне от 1 до 366. Mysql> SELECT DAYOFYEAR ('1998-02-03'); + ------------------------------------------------- -------- + | DAYOFYEAR ('1998-02-03') | + ------------------------------------------------- -------- + | 34 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) ЭКСТРАКТ (единица от даты) Функция EXTRACT () использует те же типы спецификаторов единиц, что и DATE_ADD () или DATE_SUB (), но извлекает части с даты, а не выполняет арифметику даты. Mysql> SELECT EXTRACT (YEAR FROM '1999-07-02); + ------------------------------------------------- -------- + | ЭКСТРАКТ (ГОД ОТ '1999-07-02) | + ------------------------------------------------- -------- + | 1999 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT EXTRACT (YEAR_MONTH FROM '1999-07-02 01:02:03'); + ------------------------------------------------- -------- + | ЭКСТРАКТ (YEAR_MONTH FROM '1999-07-02 01:02:03') | + ------------------------------------------------- -------- + | 199907 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) FROM_DAYS (N) С учетом числа дней N возвращается значение DATE. Mysql> SELECT FROM_DAYS (729669); + ------------------------------------------------- -------- + | FROM_DAYS (729669) | + ------------------------------------------------- -------- + | 1997-10-07 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Примечание. Используйте FROM_DAYS () с осторожностью по старым датам. Он не предназначен для использования со значениями, которые предшествуют появлению григорианского календаря (1582). FROM_UNIXTIME (UNIX_TIMESTAMP) FROM_UNIXTIME (UNIX_TIMESTAMP, формат) Возвращает представление аргумента unix_timestamp как значение в формате «YYYY-MM-DD HH: MM: SS или YYYYMMDDHHMMSS» в зависимости от того, используется ли эта функция в строке или в числовом контексте. Значение выражается в текущем часовом поясе. Параметр unix_timestamp является внутренним значением метки времени, которое создается функцией UNIX_TIMESTAMP (). Если формат указан, результат форматируется в соответствии со строкой формата, которая используется таким же образом, как указано в записи для функции DATE_FORMAT (). Mysql> SELECT FROM_UNIXTIME (875996580); ЧАС (время) Возвращает час для времени. Диапазон возвращаемого значения составляет от 0 до 23 для значений времени суток. Однако диапазон значений TIME на самом деле намного больше, поэтому HOUR может возвращать значения, превышающие 23. Mysql> SELECT HOUR ('10: 05: 03 '); + ------------------------------------------------- -------- + | ЧАС ('10: 05: 03 ') | + ------------------------------------------------- -------- + | 10 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) LAST_DAY (дата) Принимает значение даты или даты и времени и возвращает соответствующее значение за последний день месяца. Возвращает NULL, если аргумент недействителен. Mysql> SELECT LAST_DAY ('2003-02-05'); + ------------------------------------------------- -------- + | LAST_DAY ('2003-02-05') | + ------------------------------------------------- -------- + | 2003-02-28 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) LOCALTIME и LOCALTIME () LOCALTIME и LOCALTIME () являются синонимами для NOW (). LOCALTIMESTAMP и LOCALTIMESTAMP () LOCALTIMESTAMP и LOCALTIMESTAMP () являются синонимами для NOW (). MAKEDATE (год, DayOfYear) Возвращает дату, год и год. Значение dayofyear должно быть больше 0 или результат будет NULL. Mysql> SELECT MAKEDATE (2001,31), MAKEDATE (2001,32); + ------------------------------------------------- -------- + | MAKEDATE (2001,31), MAKEDATE (2001,32) | + ------------------------------------------------- -------- + | '2001-01-31', '2001-02-01' | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) MAKETIME (час, минута, секунда) Возвращает значение времени, рассчитанное по часовому, минутному и второму аргументам. Mysql> SELECT MAKETIME (12,15,30); + ------------------------------------------------- -------- + | MAKETIME (12,15,30) | + ------------------------------------------------- -------- + | '12: 15: 30 '| + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Микросекунды (выражение) Возвращает микросекунды из выражения времени или выражения datetime (expr) в виде числа в диапазоне от 0 до 999999. Mysql> SELECT MICROSECOND ('12: 00: 00.123456 '); + ------------------------------------------------- -------- + | MICROSECOND ('12: 00: 00.123456 ') | + ------------------------------------------------- -------- + | 123456 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) МИНУТЫ (время) Возвращает минута времени, в диапазоне от 0 до 59. Mysql> SELECT MINUTE ('98 -02-03 10:05:03 '); + ------------------------------------------------- -------- + | MINUTE ('98 -02-03 10:05:03 ') | + ------------------------------------------------- -------- + | 5 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) МЕСЯЦ (дата) Возвращает месяц для даты в диапазоне от 0 до 12. Mysql> SELECT MONTH ('1998-02-03') + ------------------------------------------------- -------- + | МЕСЯЦ ('1998-02-03') | + ------------------------------------------------- -------- + | 2 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) MONTHNAME (дата) Возвращает полное имя месяца для даты. Mysql> SELECT MONTHNAME ('1998-02-05'); + ------------------------------------------------- -------- + | MONTHNAME ('1998-02-05') | + ------------------------------------------------- -------- + | Февраль | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) ТЕПЕРЬ() Возвращает текущую дату и время как значение в формате «YYYY-MM-DD HH: MM: SS» или YYYYMMDDHHMMSS, в зависимости от того, используется ли функция в строковом или числовом контексте. Это значение выражается в текущем часовом поясе. Mysql> SELECT NOW (); + ------------------------------------------------- -------- + | СЕЙЧАС () | + ------------------------------------------------- -------- + | 1997-12-15 23:50:26 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) PERIOD_ADD (P, N) Добавляет N месяцев к периоду P (в формате YYMM или YYYYMM). Возвращает значение в формате YYYYMM. Обратите внимание, что аргумент периода P не является значением даты. Mysql> SELECT PERIOD_ADD (9801,2); + ------------------------------------------------- -------- + | PERIOD_ADD (9801,2) | + ------------------------------------------------- -------- + +---------------------------------------------------------+ | 199803 | +---------------------------------------------------------+ 1 row in set (0.00 sec) PERIOD_DIFF (Р1, Р2) Возвращает количество месяцев между периодами P1 и P2. Эти периоды P1 и P2 должны быть в формате YYMM или YYYYMM. Обратите внимание, что аргументы периода P1 и P2 не являются значениями даты. Mysql> SELECT PERIOD_DIFF (9802,199703); + ------------------------------------------------- -------- + | PERIOD_DIFF (9802,199703) | + ------------------------------------------------- -------- + | 11 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) КВАРТАЛ (дата) Возвращает четверть года на дату, в диапазоне от 1 до 4. Mysql> SELECT QUARTER ('98 -04-01 '); + ------------------------------------------------- -------- + | КВАРТАЛ ('98 -04-01 ') | + ------------------------------------------------- -------- + | 2 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Второй раз) Возвращает второе значение для времени в диапазоне от 0 до 59. Mysql> SELECT SECOND ('10: 05: 03 '); + ------------------------------------------------- -------- + | ВТОРОЙ ('10: 05: 03 ') | + ------------------------------------------------- -------- + | 3 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) SEC_TO_TIME (в секундах) Возвращает аргумент секунд, преобразованный в часы, минуты и секунды, в качестве значения в формате «HH: MM: SS» или HHMMSS в зависимости от того, используется ли функция в строковом или числовом контексте. Mysql> SELECT SEC_TO_TIME (2378); + ------------------------------------------------- -------- + | SEC_TO_TIME (2378) | + ------------------------------------------------- -------- + | 00:39:38 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) STR_TO_DATE (ул, формат) Это обратная функция DATE_FORMAT (). Он принимает строку str и формат строки формата. Функция STR_TO_DATE () возвращает значение DATETIME, если строка формата содержит как дату, так и время. В остальном он возвращает значение DATE или TIME, если строка содержит только дату или время. Mysql> SELECT STR_TO_DATE ('04 / 31/2004 ','% m /% d /% Y '); + ------------------------------------------------- -------- + | STR_TO_DATE ('04 / 31/2004 ','% m /% d /% Y ') | + ------------------------------------------------- -------- + | 2004-04-31 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) SUBDATE (date, INTERVAL expr unit) и SUBDATE (expr, days) При вызове с формой INTERVAL второго аргумента SUBDATE () является синонимом DATE_SUB (). Информацию об аргументе элемента INTERVAL см. В обсуждении для DATE_ADD (). Mysql> SELECT DATE_SUB ('1998-01-02', INTERVAL 31 DAY); + ------------------------------------------------- -------- + | DATE_SUB ('1998-01-02', INTERVAL 31 DAY) | + ------------------------------------------------- -------- + | 1997-12-02 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) Mysql> SELECT SUBDATE ('1998-01-02', INTERVAL 31 DAY); + ------------------------------------------------- -------- + | SUBDATE ('1998-01-02', INTERVAL 31 DAY) | + ------------------------------------------------- -------- + | 1997-12-02 | + ------------------------------------------------- -------- + 1 строка в наборе (0,00 сек) И так далее про дату время И так далее про дату время И так далее про дату время И так далее про дату время И так далее про дату время Что такое временные таблицы? Существуют РСУБД, которые поддерживают временные таблицы. Временные таблицы - отличная функция, позволяющая хранить и обрабатывать промежуточные результаты с использованием тех же возможностей выбора, обновления и объединения, которые вы можете использовать с типичными таблицами SQL Server. Временные таблицы могут быть очень полезными в некоторых случаях для хранения временных данных. Самое важное, что должно быть известно для временных таблиц, это то, что они будут удалены при завершении текущего сеанса клиента. Временные таблицы доступны в MySQL версии 3.23 и далее. Если вы используете более старую версию MySQL, чем 3.23, вы не можете использовать временные таблицы, но вы можете использовать таблицы кучи. Как указывалось ранее, временные таблицы будут сохраняться только до тех пор, пока сеанс будет жив. Если вы запустите код в скрипте PHP, временная таблица будет автоматически уничтожена, когда скрипт завершит выполнение. Если вы подключены к серверу базы данных MySQL через клиентскую программу MySQL, временная таблица будет существовать до тех пор, пока вы не закроете клиента или не вручную уничтожите таблицу. пример Ниже приведен пример использования временной таблицы. Mysql> CREATE TEMPORARY TABLE SALESSUMMARY (    -> product_name VARCHAR (50) NOT NULL    -> , total_sales DECIMAL (12,2) NOT NULL DEFAULT 0.00    -> , avg_unit_price DECIMAL (7,2) NOT NULL DEFAULT 0.00    -> , total_units_sold INT НЕОПРЕДЕЛЕННО НЕ НУЛЬНОЕ ПО УМОЛЧАНИЮ 0 ); Запрос ОК, 0 строк затронуты (0.00 сек) Mysql> INSERT INTO SALESSUMMARY    -> (product_name, total_sales, avg_unit_price, total_units_sold)    -> VALUES    -> ('огурец', 100,25, 90, 2); Mysql> SELECT * FROM SALESSUMMARY; + -------------- + ------------- + ---------------- + --- --------------- + | Product_name | Total_sales | Avg_unit_price | Total_units_sold | + -------------- + ------------- + ---------------- + --- --------------- + | Огурцы | 100,25 | 90,00 | 2 | + -------------- + ------------- + ---------------- + --- --------------- + 1 строка в наборе (0,00 сек) Когда вы выдаете команду SHOW TABLES, ваша временная таблица не будет указана в списке. Теперь, если вы выйдете из сеанса MySQL и затем выполните команду SELECT, вы не найдете данных, доступных в базе данных. Даже ваша временная таблица не будет существовать. Удаление временных таблиц По умолчанию все временные таблицы удаляются MySQL, когда соединение с базой данных завершается. Тем не менее, если вы хотите удалить их между ними, вы можете сделать это, выпустив команду DROP TABLE. Ниже приведен пример удаления временной таблицы. Mysql> CREATE TEMPORARY TABLE SALESSUMMARY (    -> product_name VARCHAR (50) NOT NULL    -> , total_sales DECIMAL (12,2) NOT NULL DEFAULT 0.00    -> , avg_unit_price DECIMAL (7,2) NOT NULL DEFAULT 0.00    -> , total_units_sold INT НЕОПРЕДЕЛЕННО НЕ НУЛЬНОЕ ПО УМОЛЧАНИЮ 0 ); Запрос ОК, 0 строк затронуты (0.00 сек) Mysql> INSERT INTO SALESSUMMARY    -> (product_name, total_sales, avg_unit_price, total_units_sold)    -> VALUES    -> ('огурец', 100,25, 90, 2); Mysql> SELECT * FROM SALESSUMMARY; + -------------- + ------------- + ---------------- + --- --------------- + | Product_name | Total_sales | Avg_unit_price | Total_units_sold | + -------------- + ------------- + ---------------- + --- --------------- + | Огурцы | 100,25 | 90,00 | 2 | + -------------- + ------------- + ---------------- + --- --------------- + 1 строка в наборе (0,00 сек) Mysql> DROP TABLE SALESSUMMARY; Mysql> SELECT * FROM SALESSUMMARY; ОШИБКА 1146: Таблица 'TUTORIALS.SALESSUMMARY' не существует Может возникнуть ситуация, когда вам нужна точная копия таблицы, а CREATE TABLE ... или команды SELECT ... не подходят для ваших целей, потому что копия должна содержать те же индексы, значения по умолчанию и т. Д. Если вы используете MySQL RDBMS, вы можете справиться с этой ситуацией, придерживаясь приведенных ниже шагов: Используйте команду SHOW CREATE TABLE, чтобы получить инструкцию CREATE TABLE, которая определяет структуру, индексы и все элементы исходной таблицы. Измените оператор, чтобы изменить имя таблицы на таблицу клонирования и выполнить оператор. Таким образом, вы получите точную таблицу клонирования. Необязательно, если вам также нужно скопировать содержимое таблицы, введите INSERT INTO или инструкцию SELECT. пример Выполните следующий пример, чтобы создать таблицу клонирования для TUTORIALS_TBL, структура которой выглядит следующим образом: Шаг 1 - Получите полную структуру таблицы. SQL> SHOW CREATE TABLE TUTORIALS_TBL \ G; *************************** 1. строка ******************** *******       Таблица: TUTORIALS_TBL Create Table: CREATE TABLE 'TUTORIALS_TBL' (   'Tutorial_id' int (11) NOT NULL auto_increment,   'Tutorial_title' varchar (100) NOT NULL default '',   'Tutorial_author' varchar (40) NOT NULL default '',   'Submission_date' дата по умолчанию NULL,   PRIMARY KEY ('tutorial_id'),   UNIQUE KEY 'AUTHOR_INDEX' ('tutorial_author') ) TYPE = MyISAM 1 строка в наборе (0,00 сек) Шаг 2 - Переименуйте эту таблицу и создайте другую таблицу. SQL> CREATE TABLE `CLONE_TBL` (   -> 'tutorial_id' int (11) NOT NULL auto_increment,   -> 'tutorial_title' varchar (100) NOT NULL default '',   -> 'tutorial_author' varchar (40) NOT NULL default '',   -> 'submit_date' дата по умолчанию NULL,   -> PRIMARY KEY (`tutorial_id '),   -> UNIQUE KEY «AUTHOR_INDEX» ('tutorial_author') -> ) TYPE = MyISAM; Query OK, 0 строк, затронутых (1,80 с) Шаг 3 - После выполнения шага 2 вы клонируете таблицу в своей базе данных. Если вы хотите скопировать данные из старой таблицы, вы можете сделать это, используя инструкцию INSERT INTO ... SELECT. SQL> INSERT INTO CLONE_TBL (tutorial_id,    -> tutorial_title,    -> tutorial_author,    -> submit_date)    -> SELECT tutorial_id, tutorial_title,    -> tutorial_author, submission_date,    -> FROM TUTORIALS_TBL; Запрос ОК, 3 строки затронуты (0,07 сек) Записи: 3 Дубликаты: 0 Предупреждения: 0 Наконец, у вас будет точная таблица клонов, как вы хотели. Subquery Подзапрос или Внутренний запрос или Вложенный запрос - это запрос в другом SQL-запросе и встроенный в предложение WHERE. Подзапрос используется для возврата данных, которые будут использоваться в основном запросе в качестве условия для дальнейшего ограничения извлекаемых данных. Подзапросы могут использоваться с операторами SELECT, INSERT, UPDATE и DELETE вместе с операторами типа =, <,> ,> =, <=, IN, BETWEEN и т. Д. Существует несколько правил, которым должны следовать подзапросы - Подзапросы должны быть заключены в круглые скобки. Подзапрос может содержать только один столбец в предложении SELECT, если только несколько столбцов не находятся в основном запросе для подзапроса для сравнения его выбранных столбцов. Команда ORDER BY не может использоваться в подзапросе, хотя основной запрос может использовать ORDER BY. Команда GROUP BY может использоваться для выполнения той же функции, что и ORDER BY в подзапросе. Подзапросы, которые возвращают более одной строки, могут использоваться только с несколькими операторами значений, такими как оператор IN. Список SELECT не может содержать ссылки на значения, которые вычисляются для BLOB, ARRAY, CLOB или NCLOB. Подзапрос не может быть немедленно заключен в функцию set. Оператор BETWEEN не может использоваться с подзапросом. Тем не менее, оператор BETWEEN может использоваться в подзапросе. Подзапросы с инструкцией SELECT Подзапросы чаще всего используются с оператором SELECT. Основной синтаксис заключается в следующем: SELECT column_name [, column_name] FROM table1 [, table2] WHERE column_name ОПЕРАТОР    (SELECT column_name [, column_name]    FROM table1 [, table2]    [WHERE]) пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи: + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 35 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Теперь давайте проверим следующий подзапрос с инструкцией SELECT. SQL> SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM CUSTOMERS WHERE SALARY > 4500) ; Это приведет к следующему результату. + ---- + ---------- + ----- + --------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + --------- + ---------- + | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + --------- + ---------- + Подзапросы с инструкцией INSERT Подзапросы также могут использоваться с операторами INSERT. Оператор INSERT использует данные, возвращаемые из подзапроса, для вставки в другую таблицу. Выбранные данные в подзапросе могут быть изменены с помощью любых функций символа, даты или числа. Основной синтаксис следующий. INSERT INTO table_name [ (column1 [, column2 ]) ] SELECT [ *|column1 [, column2 ] FROM table1 [, table2 ] [ WHERE VALUE OPERATOR ] пример Рассмотрим таблицу CUSTOMERS_BKP с аналогичной структурой, такой как таблица CUSTOMERS. Теперь, чтобы скопировать всю таблицу CUSTOMERS в таблицу CUSTOMERS_BKP, вы можете использовать следующий синтаксис. SQL> INSERT INTO CUSTOMERS_BKP SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM CUSTOMERS) ; Подзапросы с инструкцией UPDATE Подзапрос может использоваться в сочетании с оператором UPDATE. Либо один или несколько столбцов в таблице можно обновить при использовании подзапроса с помощью инструкции UPDATE. Основной синтаксис следующий. UPDATE table SET column_name = new_value [ WHERE OPERATOR [ VALUE ] (SELECT COLUMN_NAME FROM TABLE_NAME) [ WHERE) ] пример Предположим, у нас есть таблица CUSTOMERS_BKP, которая является резервной копией таблицы CUSTOMERS. Следующий пример обновляет SALARY в 0,25 раза в таблице CUSTOMERS для всех клиентов, AGE которых больше или равно 27. SQL> UPDATE CUSTOMERS SET SALARY = SALARY * 0.25 WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP WHERE AGE > = 27 ); Это повлияет на две строки, и, наконец, таблица CUSTOMERS будет иметь следующие записи. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 35 | Ахмедабад | 125.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 2125,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Подзапросы с инструкцией DELETE Подзапрос может использоваться в сочетании с оператором DELETE, как и с любыми другими утверждениями, упомянутыми выше. Основной синтаксис следующий. DELETE FROM TABLE_NAME [ WHERE OPERATOR [ VALUE ] (SELECT COLUMN_NAME FROM TABLE_NAME) [ WHERE) ] пример Предположим, у нас есть таблица CUSTOMERS_BKP, которая является резервной копией таблицы CUSTOMERS. В следующем примере удаляются записи из таблицы CUSTOMERS для всех клиентов, AGE которых больше или равно 27. SQL> DELETE FROM CUSTOMERS WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP WHERE AGE > = 27 ); Это повлияет на две строки, и, наконец, таблица CUSTOMERS будет иметь следующие записи. + ---- + ---------- + ----- + --------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + --------- + ---------- + | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + --------- + ---------- + Последовательность представляет собой набор целых чисел 1, 2, 3, ..., которые генерируются по порядку по требованию. Последовательности часто используются в базах данных, потому что многие приложения требуют, чтобы каждая строка в таблице содержала уникальное значение, а последовательности обеспечивали простой способ их генерации. В этой главе описывается использование последовательностей в MySQL. Использование столбца AUTO_INCREMENT Самый простой способ использования последовательностей MySQL - определить столбец как AUTO_INCREMENT и оставить остальное в MySQL, чтобы заботиться. пример Попробуйте следующий пример. Это создаст таблицу, и после этого она введет несколько строк в эту таблицу, где не требуется указывать идентификатор записи, поскольку он автоматически увеличивается с помощью MySQL. Mysql> CREATE TABLE INSECT    -> (    -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,    -> ПЕРВИЧНЫЙ КЛЮЧ (id),    -> имя VARCHAR (30) NOT NULL, # тип насекомого    -> дата DATE NOT NULL, # дата собрана    -> origin VARCHAR (30) NOT NULL #, где собрано ); Запрос ОК, 0 строк затронуты (0,02 сек) Mysql> INSERT INTO INSECT (id, name, date, origin) ЦЕННОСТИ    -> (NULL, 'housefly', '2001-09-10', 'кухня'),    -> (NULL, 'millipede', '2001-09-10', 'driveway'),    -> (NULL, 'кузнечик', '2001-09-10', 'передний двор'); Запрос ОК, 3 строки затронуты (0,02 сек) Записи: 3 Дубликаты: 0 Предупреждения: 0 Mysql> SELECT * FROM INSECT ORDER BY id; + ---- + ------------- + ------------ + ------------ + | Id | Имя | Дата | Происхождение | + ---- + ------------- + ------------ + ------------ + | 1 | Дом | 2001-09-10 | Кухня | | 2 | Многоножки | 2001-09-10 | Подъездной путь | | 3 | Кузнечик | 2001-09-10 | Передний двор | + ---- + ------------- + ------------ + ------------ + 3 ряда в наборе (0,00 сек) Получить значения AUTO_INCREMENT LAST_INSERT_ID () - это функция SQL, поэтому вы можете использовать ее из любого клиента, который понимает, как выдавать SQL-запросы. В противном случае скрипты PERL и PHP предоставляют исключительные функции для получения автоматически увеличиваемого значения последней записи. Пример PERL Используйте атрибут mysql_insertid для получения значения AUTO_INCREMENT, сгенерированного запросом. Этот атрибут доступен через дескриптор базы данных или дескриптор инструкции, в зависимости от того, как вы выдаете запрос. Следующий пример ссылается на нее через дескриптор базы данных. $ Dbh-> do ("INSERT INTO INSECT (имя, дата, происхождение) ЗНАЧЕНИЯ ( 'моли', '2001-09-14', 'подоконник') "); My $ seq = $ dbh -> {mysql_insertid}; Пример PHP После выдачи запроса, который генерирует значение AUTO_INCREMENT, извлеките значение, вызвав функцию mysql_insert_id (). Mysql_query ("INSERT INTO INSECT (имя, дата, происхождение) VALUES ('moth', '2001-09-14', 'windowsill') ", $ conn_id); $ Seq = mysql_insert_id ($ conn_id); Перенумерация существующей последовательности Может быть случай, когда вы удалили много записей из таблицы и хотите перегруппировать все записи. Это можно сделать, используя простой трюк, но вы должны быть очень осторожны, чтобы сделать это и проверить, есть ли в вашей таблице соединение с другой таблицей или нет. Если вы решите, что переупорядочение столбца AUTO_INCREMENT неизбежно, способ сделать это - удалить столбец из таблицы, а затем добавить его снова. В следующем примере показано, как перенумеровать значения id в таблице насекомых, используя эту технику. Mysql> ALTER TABLE INSECT DROP id; Mysql> ALTER TABLE насекомое    -> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,    -> ДОБАВИТЬ ПЕРВИЧНЫЙ КЛЮЧ (id); Запуск последовательности при определенном значении По умолчанию MySQL запустит последовательность из 1, но вы также можете указать любой другой номер во время создания таблицы. В следующем блоке кода есть пример, где MySQL начнет последовательность из 100. Mysql> CREATE TABLE INSECT    -> (    -> id INT UNSIGNED NOT NULL AUTO_INCREMENT = 100,    -> ПЕРВИЧНЫЙ КЛЮЧ (id),    -> имя VARCHAR (30) NOT NULL, # тип насекомого    -> дата DATE NOT NULL, # дата собрана    -> origin VARCHAR (30) NOT NULL #, где собрано ); Кроме того, вы можете создать таблицу, а затем установить начальное значение последовательности с помощью ALTER TABLE. Mysql> ALTER TABLE t AUTO_INCREMENT = 100; Может возникнуть ситуация, когда в таблице имеется несколько повторяющихся записей. При получении таких записей имеет смысл извлекать только уникальные записи, а не извлекать дубликаты записей. Ключевое слово SQL DISTINCT, которое мы уже обсуждали, используется вместе с оператором SELECT для устранения всех дубликатов записей и получения только уникальных записей. Синтаксис Основной синтаксис ключевого слова DISTINCT для устранения дублирующих записей выглядит следующим образом. SELECT DISTINCT column1, column2, ..... columnN FROM table_name WHERE [условие] пример Рассмотрим таблицу CUSTOMERS, имеющую следующие записи. + ---- + ---------- + ----- + ----------- + ---------- + | ID | ИМЯ | ВОЗРАСТ | АДРЕС | SALARY | + ---- + ---------- + ----- + ----------- + ---------- + | 1 | Рамеш | 32 | Ахмедабад | 2000.00 | | 2 | Хилан | 25 | Дели | 1500,00 | | 3 | Каушик | 23 | Кота | 2000.00 | | 4 | Chaitali | 25 | Мумбаи | 6500,00 | | 5 | Хардик | 27 | Бхопал | 8500,00 | | 6 | Комаль | 22 | MP | 4500,00 | | 7 | Muffy | 24 | Индор | 10000,00 | + ---- + ---------- + ----- + ----------- + ---------- + Сначала давайте посмотрим, как следующий запрос SELECT возвращает повторяющиеся записи зарплаты. SQL> SELECT SALARY FROM CUSTOMERS ORDER BY SALARY; Это приведет к следующему результату, когда зарплата 2000 года будет поступать дважды, что является дубликатностью из первоначальной таблицы. + ---------- + | SALARY | + ---------- + | 1500,00 | | 2000.00 | | 2000.00 | | 4500,00 | | 6500,00 | | 8500,00 | | 10000,00 | + ---------- + Теперь давайте использовать ключевое слово DISTINCT с вышеуказанным запросом SELECT и увидеть результат. SQL> SELECT DISTINCT SALARY FROM CUSTOMERS ORDER BY SALARY; Это приведет к следующему результату, когда у нас нет дубликатов. + ---------- + | SALARY | + ---------- + | 1500,00 | | 2000.00 | | 4500,00 | | 6500,00 | | 8500,00 | | 10000,00 | + ---------- +

Оптимизация SQL-запросов

Оглавление

1.    Оптимизация SQL-запросов. 1

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

1.1.1.     Основные шаги оптимизации. 1

1.1.2.     Законы реляционной алгебры.. 1

1.2.     Построение логического плана. 1

1.2.1.     Преобразование запроса в формулу реляционной алгебры.. 1

1.2.2.     Оптимизация формулы реляционной алгебры.. 1

1.2.3.     Иллюстрация логической оптимизации. 1

1.3.     Пример построения логического плана. 1

1.3.1.     Оптимизация запроса. 1

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

1.4.     Построение физического плана. 1

1.4.1.     Шаги построения физического плана. 1

1.4.2.     Отличие физического плана от логического. 1

1.4.3.     Методы выбора записей из исходной таблицы.. 1

1.4.4.     Оценка числа кортежей в промежуточной таблице Q.. 1

1.4.5.     Оценка числа блоков в промежуточной таблице Q.. 1

1.5.     Порядок соединения таблиц. 1

1.5.1.     Левостороннее дерево соединений. 1

1.5.2.     Кустовое дерево соединений. 1

1.5.3.     Правостороннее дерево соединений. 1

1.6.     Методы соединения таблиц. 1

1.6.1.     Метод вложенных циклов (NLJNested Loop Join) 1

1.6.2.     Метод сортировки-слияния (SMJSort Merge Join) 1

1.6.3.     Метод хешированного соединения (HJHash Join) 1

1.6.4.     Число кортежей, блоков и мощности атрибутов в соединении. 1

1.7.     Поиск физического плана с минимальной стоимостью.. 1

1.7.1.     Алгоритм поиска для левостороннего дерева соединений. 1

1.7.2.     Формат экземпляра структуры данных. 1

1.7.3.     Спецификации процедуры AccessPlan. 1

1.7.4.     Спецификации процедуры JoinPlan. 1

1.7.5.     Спецификации процедуры OptPlanReturn. 1

1.8.     Пример построения оптимального физического плана. 1

1.8.1.     Логический план. 1

1.8.2.     Алгоритм поиска оптимального физического плана. 1

1.8.3.     Определение метода выбора записей из исходной таблицы R1. 1

1.8.4.     Определение метода выбора записей из исходной таблицы R2. 1

1.8.5.     Оценка соединения Q1 и Q2 методом NLJ. 1

1.8.6.     Оценка соединения Q1 и Q2 методом SMJ. 1

1.8.7.     Выбор метода соединения Q1 и Q2 и заполнение структуры.. 1

1.8.8.     Оценка и выбор метода соединения Q2 и Q1. 1

1.8.9.     Вывод физического плана. 1

 

1.   Оптимизация SQL-запросов

 

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

 

1.1.1.      Основные шаги оптимизации

 

Поступающий на сервер SQL-запрос подвергается оптимизации с целью уменьшения времени его выполнения. При этом оптимизатор запросов выполняет следующие шаги:

I. Строит логический план выполнения запроса (дерево логических операций).

II. Строит оптимальный физический план выполнения запроса (дерево физических операций).

III. Реализует полученный оптимальный физический план выполнения запроса.

Примечание. Оптимизатор называется восходящим, если при построении оптимального физического плана он просматривает логический план от листьев к корню. Если логический план просматривается от корня к листьям, то такой оптимизатор называется нисходящим.

 

1.1.2.      Законы реляционной алгебры

 

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

 

1.Закон коммутативности декартова произведения.

Имеет место равенство:

R1 × R2 = R2 × R1 ,

где R1 и R2 – отношения (таблицы).

 

2. Закон ассоциативности декартова произведения.

Справедливо равенство:

(R1 × R2) × R3 = R1 × (R2 × R3),

 где R1, R2 и R3 – отношения (таблицы).

 

3. Закон каскада проекций.

Если , где {a1, …, an} и {b1, …, bm} – некоторые множества атрибутов, то имеет место следующее равенство:

.

 

4. Закон каскада селекций.

Если условие F является конъюнкцией нескольких условий, т.е. , то справедливо следующее равенство:

.

 

5. Закон перестановки проекции и селекции:

1. В условие F входят атрибуты только из множества {a1, …, an}.

Имеет место следующее равенство:

.

 

2. В условие F входят атрибуты не только из множества {a1, …, an}.

Справежливо следующее равенство:

,

где b1, …, bm – атрибуты таблицы R, которые входят в условие F, но не принадлежат множеству {a1, …, an}.

 

6. Закон перестановки селекции и декартова произведения.

Если условие f1 включает в себя только атрибуты отношения R1, то имеет место следующее равенство:

.

Следствие. Пусть , причем в f1 входят атрибуты только из отношения R1, а в f2 входят атрибуты только из R2. В этом случае справедливо следующее равенство:

.

 

7. Закон перестановки селекции и объединения.

Имеет место следующее равенство:

.

Примечание. В языке SQL операция объединения отношений моделируется с помощью операции  UNION.

 

8. Закон перестановки селекции и разности отношений.

Справедливо следующее равенство:

,

где R1R2 – множество кортежей, которые принадлежат отношению R1 и не принадлежат R2.

 

9. Закон перестановки проекции и декартова произведения.

Пусть {b1, …, bn} – некоторые атрибуты из R1, {с1, …, сm} – некоторые атрибуты из R2. Имеет место следующее равенство:

 

10. Закон перестановки проекции и объединения.

Справедливо следующее равенство:

.

 

1.2.    Построение логического плана

 

При построении логического плана выполнения SQL-запроса выполняются следующие действия:

1. Запрос преобразуется в формулу реляционной алгебры (явно или неявно).

2. Выполняется преобразование (оптимизация) этой формулы.

 

1.2.1.      Преобразование запроса в формулу реляционной алгебры

 

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

 

π AF(R1× R2 × … × Rn)),                                                                   (5.1)

                                                                                                         

где R1× R2 × … × Rn – декартово произведение отношений (таблиц), указанных за ключевым словом FROM;

σF – операция селекции кортежей декартова произведения в соответствии с условием F, указанным за ключевым словом WHERE;

π A – проекция селекции на множество атрибутов А, перечисленных за ключевым словом SELECT.

Ниже приведён пример преобразования запроса.

Запрос: "Найти фамилию пользователя с кодом 3".

Оператор SELECT

SELECT фамилия

FROM    пользователь

WHERE  код_пользователя = 3;

Формула реляционной  алгебры:

A

 

F

 

R1

 
 

 

 


1.2.2.      Оптимизация формулы реляционной алгебры

 

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

1. Если условие F является конъюнкцией нескольких условий (), то переместить каждую селекцию  внутрь декартова произведения, используя законы 1, 4, 6, 7, 8.

2. Переместить каждую проекцию внутрь декартова произведения, используя законы 1, 3, 5, 9, 10.

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

 

В результате использования правил 1–3 формула реляционной алгебры (5.1), соответствующая исходному запросу, преобразуется в следующую формулу:

 

,                               (5.2)

 

 


где

 – условие, сформулированное в исходном запросе SELECT;

f – условие соединения подзапросов {Qi}.

Подчеркнутые в приведённой выше формуле отношения Q1, …, Qn имеют меньшую размерность, чем исходные отношения R1, …, Rn , и потому запрос по формуле (5.2) выполняется быстрее, чем по формуле (5.1).

По формуле (5.2) можно построить логический план, представленный на рис. 1.1.

 

Рис. 1.1. Логический план выполнения запроса, соответствующий формуле (5.2)

 

1.2.3.      Иллюстрация логической оптимизации

 

1. Выполнение запроса по формуле π A(σF(R1× R2 × … × Rn)), до оптимизации, иллюстрируется рисунком (рис. 1.2).

 

Рис. 1.2. Выполнение запроса по формуле (5.1).

 

2. Выполнение запроса по формуле

,  после оптимизации, иллюстрируется рисунком (рис. 1.3).

 

Рис. 1.3. Выполнение запроса после оптимизации по формуле (5.2).

 

В случае отсутствия оптимизации запроса вначале нужно определить декартово произведение исходных таблиц R1, …, Rn , затем выполнить селекцию σF и взять проекцию πA. Если таблицы R1, …, Rn имеют большую размерность, то время выполнения запроса будет достаточно большим. Поэтому запрос по формуле (5.2) выполняется быстрее, так как отношения Q1, …, Qn имеют меньшую размерность, чем исходные отношения R1, …, Rn .

Примечание. Если исходные таблицы R1, …, Rn размещаются на разных серверах или на одном суперкомпьютере, то подзапросы Q1, …, Qn могут выполняться параллельно.

 

1.3.      Пример построения логического плана

 

1.3.1.      Оптимизация запроса

 

Предположим, что на сервер СУБД поступает запрос SELECT. На сервере хранятся две таблицы, участвующие в запросе (рис. 1.4).

 

 

Рис. 1.4. Исходные таблицы на сервере СУБД.

 

Предположим, что клиент, связанный с сервером СУБД, выдал следующий запрос: "Найти значения остатков, большие 1500, на счетах пользователя с кодом 3". Соответствующий запрос SELECT имеет следующий вид:

 

SELECT остаток

FROM R2

WHERE остаток > 1500 AND номер_счета IN

(SELECT номер_счета

FROM R1

WHERE код_пользователя = 3);

 

Этот оператор SELECT преобразуется в формулу реляционной алгебры (см. п. 1.2.1):

 

 

Эта формула подвергается оптимизации. Оптимизатор вначале строит логический план выполнения запроса, используя законы реляционной алгебры (см. пункты 1.1.2 и 1.2.2, номера законов показаны над равенствами):

 

Последняя формула – результат оптимизации, здесь подчёркнуты подзапросы. По этой формуле оптимизатор строит логический план выполнения запроса (рис. 1.5).

 

 

Рис. 1.5. Логический план выполнения запроса в графическом виде.

 

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

 

1. Определение промежуточных таблиц Q1 и Q2 .

На основе полученной формулы

 

(5.3)

 

определяются промежуточные таблицы Q1 и Q2 :

 

1.

 

Из таблицы R1 (см. рис. 1.4) получим

 

Q1: номер_счета

102

 

2.

 

Из таблицы R2 (см. рис. 1.4) получим

 

Q2: номер_счета остаток

101

2000

102

3000

 

2. Соединение промежуточных таблиц Q1 и Q2 .

Выполняется соединение промежуточных таблиц Q1 и Q2 и  передача результата клиенту. При этом реализуется формула

 

:

 

а) Q = Q1´Q2 :

 

         R1.номер_счета  R2.номер_счета  R2.остаток

102

101

2000

102

102

3000

 

 

б) Z = sR1.номер_счета=R2.номер_счета(Q):

 

         R1.номер_счета  R2.номер_счета  R2.остаток

102

102

3000

 

в) pR2.остаток(Z):

 

         остаток

3000

 

Эта величина остатка посылается клиенту.

 

Примечание. Если таблицы R1 и R2 хранятся на других различных серверах S1 и S2, то подзапросы Q1 и Q2 преобразуются в запросы SELECT и направляются на серверы S1 и S2, где параллельно выполняются.

 

Подзапрос Q1 преобразуется к виду:

SELECT номер_счета

FROM R1

WHERE код_пользователя=3;

 

Подзапрос Q2 преобразуется к виду:

SELECT номер_счета, остаток

FROM R2

WHERE остаток > 1500;

 

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

 

1.4.      Построение физического плана

 

1.4.1.      Шаги построения физического плана

 

При построении оптимального физического плана выполнения SQL-запроса (дерева физических операций) выполняются следующие действия:

 

1. Последовательно строится множество физических планов на основе логического плана (см. разделы 1.2, 1.3). Физические планы в основном отличаются следующим:

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

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

в) методом соединения таблиц (т.е. методом реализации операции естественного соединения  ).

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

 

1.4.2.      Отличие физического плана от логического

 

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

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

 

Рис. 1.6. Логический и физический планы выполнения запроса.

 

Физический план выполняется в следующей последовательности.

1. Здесь операции  реализуются следующим образом: читается вся таблица R1 (TableScan(R1)) и затем каждая запись проверяется, удовлетворяет ли она логическому условию F1, и если да, то из нее выделяются атрибуты, входящие в множество A1 (). Получившаяся промежуточная таблица является правым аргументом соединения.

2. Операции реализуются следующим образом: с помощью индекса читаются записи таблицы R2, удовлетворяющие подусловию φ (IndexScan(R2, φ)). Здесь φ – некоторое подусловие условия F2 по атрибуту, который имеет индекс.

Примеры подусловий φ: a = 5, a > 5, a ≥ 5, a < 5, a ≤ 5 (a – индексированный атрибут таблицы R2).

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

3. Выполняется естественное соединение промежуточных таблиц, полученных на первом и втором шагах, методом сортировки и слияния (SMJ); тут же из получившегося результата выделяется множество атрибутов A.

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

 

 

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

 

C = CCPU + CI/O .

 

После перебора нескольких физических планов оптимизатор выбирает план с минимальной стоимостью.

 

1.4.3.      Методы выбора записей из исходной таблицы

 

1. Чтение всех записей таблицы и их фильтрация.

 

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

 

 

Рис. 1.7. Чтение всех записей.

 

Стоимость работы процессора и дискового ввода-вывода рассчитывается по формулам:

 

CCPU = T(R) · Cfilter ,                                                                           (5.4)

CI/O = B(R) · CB ,

 

где

T(R) – число кортежей (записей) в исходной таблице R;

B(R) – число физических блоков таблицы R;

Сfilter – время фильтрации одной записи в ОП;

CB – время чтения/записи одного блока на диск.

 

 

2. Чтение записей с помощью индекса и их фильтрация.

 

Схема операции (IndexScan + Filter) представлена на рис. 1.8.

 

 

Рис. 1.8. Чтение записей с помощью индекса.

 

Стоимость работы процессора и подсистемы ввода-вывода определяются следующими выражениями:

 

где

T(R) – число записей в таблице R;

B(R) – число блоков таблицы R;

I(R,a) – мощность атрибута "а" в таблице R (число различных значений);

B(Index(R,a)) – число блоков на листовом уровне индекса по атрибуту "а";

Сfilter – время фильтрации одной записи в ОП;

CB – время чтения/записи одного блока на диск;

k – мощность атрибута "а" в запросе (число различных значений, указанных в подзапросе φ).

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

Мощность атрибута в запросе (параметр k) можно оценить с помощью следующих выражений:

 

(5.6)

 

Величину  в формулах (5.5) можно интерпретировать как вероятность, что запись таблицы R удовлетворяет условию φ по атрибуту "а".

 

1.4.4.      Оценка числа кортежей в промежуточной таблице Q

 

Число кортежей оценивается с помощью следующей формулы:

 

T(Q) = T(Rp ,                                                                                  (5.7)

 

где

Q=sF(R) – промежуточной таблица, соответствующая подзапросу Q,

T(Q) – оценка числа кортежей в промежуточной таблице Q,

T(R) – общее число кортежей в исходной таблице R,

p – вероятность того, что кортеж из R удовлетворяет условию поиска F.

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

 

1. Пусть F = f1 AND f­2 . Тогда

 

p = p1p2 ,

 

где pi – вероятность того, что запись из R удовлетворяет подусловию fi  (i=1,2).

 

2. Пусть F = f1 OR f­2 . Тогда

 

p = p1 + p2 – p1p2 .

 

3. Пусть F = NOT f1 . В этом случае

 

p = 1 – p1 .

 

Если в приведенных выше случаях 1–3 fi – подусловие по какому-либо атрибуту "а", то вероятность pi рассчитывается по следующей формуле:

 

 ,

 

где k – мощность атрибута в подзапросе (см. формулу (5.6)),

I(R,a) – мощность атрибута "а" в таблице R.

 

Ниже приведён пример расчёта числа кортежей в промежуточной таблице.

Пусть таблица R включает атрибуты (a, b, c). Число кортежей T(R) = 1000. Мощности атрибутов: I(R,a) = 5, I(R,b) = 10, I(R,c) = 2. Для простоты полагаем, что a, b, c – натуральные положительные числа.

Пусть задано условие выбора записей таблицы R:

 

F = (a < 3 OR b ³ 5) AND c = 2

 

 

 

 


Требуется оценить число записей, удовлетворяющих условию F.

 

Решение.

 

 1. f3 = f1 OR f­2

 

 

2. F = f3 AND f­4

 

 – вероятность того, что запись из R удовлетворяет условию F.

 

3.  T(Q) = T(Rp = 1000·0,38 = 380 – оценка числа записей, удовлетворяющих условию F.

 

1.4.5.      Оценка числа блоков в промежуточной таблице Q

 

Число блоков в промежуточной таблице можно оценить при помощи следующей формулы:

 

 ,

 

где

Q=sF(R) – промежуточной таблица, соответствующая подзапросу Q,

T(Q) - оценка числа кортежей в промежуточной таблице (см. п. 1.4.4),

LB – длина блока (т.е. число записей в блоке),

 - операция округления с избытком.

 

1.5.      Порядок соединения таблиц

 

Существуют три вида деревьев соединений:

1. Левостороннее дерево соединений.

2. Кустовое (ветвящееся) дерево соединений.

3. Правостороннее дерево соединений.

 

1.5.1.      Левостороннее дерево соединений

 

 

Рис. 1.9. Левостороннее дерево соединений.

 

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

·        число переборов вариантов соединений меньше, чем для кустового дерева (для левостороннего дерева оно равно n!, где n – число соединяемых таблиц);

·        для этого типа дерева достаточно просто организовать каналы обработки.

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

Рассмотрим операции соединений 1 и 2 на рис. 1.9: (R S)T. Схема выполнения этих операций показана на рис. 1.10.

 

Рис. 1.10. Организация каналов обработки.

 

В канале только левый аргумент может быть опорным (т.е. храниться в оперативной памяти). Правый аргумент соединения называется тестируемым и может располагаться на диске. Если таблица подзапроса R и результат  соединения  (см. рис. 1.10) умещаются в оперативной памяти, то использование каналов позволяет организовать однопроходной алгоритм соединения таблиц (исходные таблицы R1, S1, T1 читаются с диска один раз).

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

 

1.5.2.      Кустовое дерево соединений

 

 

Рис. 1.11. Кустовое дерево соединений.

 

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

 

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

Например, для реализации однопроходного алгоритма соединения таблиц, представленных на рис. 1.11, необходимо, чтобы в оперативной памяти  размещались таблицы R и , T и .

 

1.5.3.      Правостороннее дерево соединений

 

 

Рис. 1.12. Правостороннее дерево соединений.

 

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

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

 

1.6.      Методы соединения таблиц

 

Ниже рассматриваются три метода соединения таблиц:

·        метод вложенных циклов (NLJNested Loop Join),

·        метод сортировки-слияния (SMJSort Merge Join),

·        хешированное соединение (HJHash Join).

 

1.6.1.      Метод вложенных циклов (NLJNested Loop Join)

 

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

 

Рис. 1.13. Метод соединения NLJ.

 

Формулы оценки стоимости соединения при использовании метода NLJ зависят от:

1) используемого дерева соединений; в дальнейшем будем полагать, что используются левосторонние деревья и применяются каналы,

2) назначения буферов ввода-вывода (рис. 1.14).

 

Рис. 1.14. Схема назначения буферов ввода-вывода.

 

В этом случае формулы для вычисления стоимости соединения NLJ следующий вид:

 

                                                            (5.8)

где

T(Q1), T(Q2) – число кортежей в таблицах подзапросов Q1 и Q2;

B(Q1) – число блоков в таблице Q1;

СI/O(Q2) – время ввода-вывода для получения таблицы Q2;

b – число блоков в буфере для Q1;

Ccomp – время соединения (сравнения) двух кортежей из таблиц Q1 и Q2 в оперативной памяти (ОП);

 - округление с недостатком.

Во второй формуле учитывается возможность многопроходного варианта соединения таблицы Q2, если таблица Q1 не умещается в "b" блоках буфера оперативной памяти. Округление берётся с недостатком, так как одно чтение таблиц с диска учитывается в стоимости выбора записей из исходных таблиц.

 

1.6.2.      Метод сортировки-слияния (SMJSort Merge Join)

 

Соединение таблиц включает следующие шаги:

1. Соединяемые таблицы сортируются по атрибуту соединения     (обозначим его через "а").

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

Условием соединения может быть только равенство атрибутов соединения.

Пример выполнения соединения методом сортировки-слияния приведен на  рис. 1.15.

 

Рис. 1.15. Метод соединения SMJ.

 

Выполняется сравнение записей, на которые указывают указатели таблиц Q1 и Q2 . Перемещение указателей выполняется следующим образом: если выполняется условие "<", то осуществляется перемещение указателя Q1 к следующей записи; если выполняется условие ">", то к следующей записи перемещается указатель Q2 ; при "=" указатели не перемещается и выполняется сравнение со следующей записью таблицы Q2.

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

 

Рис. 1.16. Схема назначения буферов.

 

Формулы для оценки стоимости соединения SMJ имеют следующий вид.

 

Здесь

T(Q1), T(Q2) – число кортежей в таблицах Q1 и Q2

B(Q1), B(Q2) – число блоков в таблицах Q1 и Q2;

I(Q1,a), I(Q2,a) – мощности атрибутов соединения "а" в таблицах Q1 и Q2;

b – число блоков в ОП, отводимых под сортировку таблицы Q1 или Q2;

Ccomp – время соединения двух кортежей из таблиц Q1 и Qв ОП;

Cmove – время перемещения одного кортежа в ОП при сортировке;

CB – время чтения/записи одного блока на диск;

 - округление с избытком;

 - округление с недостатком;

  - не учитывается, если таблицы были уже отсортированы перед началом соединения.

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

Блоки 1¸b таблицы R читаются в буфер (рис. 1.17) и записи этих блоков сортируются. Результат сортировки сохраняется в виде файла. Затем читаются следующие "b" блоков (b¸2b, см. рис. 1.17) и их записи также сортируются, результат сортировки сохраняется во втором файле и т.д.

 

 

Рис. 1.17. Чтение большой таблицы в буфер из b блоков.

 

Сохранённые файлы представлены в виде уровня 1 на рис. 1.18.

Известно, что число операций сравнений и перемещений при сортировке пропорционально величине , где - число сортируемых записей.  - это количество файлов уровня 1.  Поэтому для одного файла . С учётом числа файлов получаем первое слагаемое в формуле 3 (см. выражения (5.9)).

 

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

 

Далее из 1-го файла уровня 1 записи читаются в 1-й блок буфера, из 2-го файла уровня 1 записи читаются во 2-й блок и т.д., и из b-го файла уровня 1 записи читаются в b-й блок (рис. 1.19). В каждом блоке записи уже отсортированы на предыдущем этапе. Поэтому сравниваются первые записи этих блоков по атрибуту сортировки (b сравнений). Запись с минимальным значением атрибута перемещается в файл (одно перемещение). Остальные записи соответствующего блока сдвигаются вверх (блок работает как стек). Затем снова сравниваются первые записи b блоков по атрибуту сортировки и т.д. Если записи в каком-либо блоке исчерпаны, то в этот блок подгружаются записи из связанного с ним файла. После обработки таким способом b файлов уровня 1 будет сформирован файл уровня 2 (см. рис. 1.18), записи в котором отсортированы. Далее в блоки буфера подгружаются записи следующих b файлов уровня 1 и т.д.

По аналогичной схеме (см. рис. 1.19) объединяются файлы уровня 2 и т.д. В конце концов, будет сформирован один отсортированный результирующий файл (см. рис. 1.18). Количество уровней L может быть получено из уравнения  (число файлов на самом нижнем уровне равно 1), т.е. .

 

Рис. 1.19. Сортировка записей из b промежуточных файлов.

 

На каждом уровне (кроме последнего) по описанной выше схеме (см. рис. 1.19) обрабатываются все записи таблицы R (их число равно T(R)). Это объясняет второе слагаемое в формуле 3. В файлах каждого уровня хранятся B(R) блоков. Это объясняет формулу 4. Здесь коэффициент 2 учитывает, что каждый файл каждого уровня записывается на диск, а потом читается.

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

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

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

 

1.6.3.      Метод хешированного соединения (HJHash Join)

 

При хешированном соединении выполняются следующие шаги:

 

1. Выбирается хеш-функция h(a).

2. Записи соединяемых таблиц хешируются, т.е. создаются хеш-разделы.

3. Выполняется соединение записей соответствующих разделов по алгоритму NLJ или SMJ.

 

Этот метод используется при условии равенства атрибутов соединения для очень больших соединяемых таблиц.

Пример двух таблиц, соединяемых методом хешированного соединения, приведён на рис. 1.20.

 

Рис. 1.20. Соединяемые таблицы.

 

1) В качестве хеш-функции выбрано деление номера счета по модулю 10.

2) Обозначим хеш-разделы следующим образом:

Ri – множество номеров счетов из R, у которых остаток от деления на 10 равен i;

Si – множество номеров счетов из S, у которых остаток от деления на 10 равен i.

3) Соединение разделов.

Представим процесс соединения в виде следующей таблицы (табл. 1.1).

 

Табл. 1.1.

Результаты соединения разделов

 

          Si

Ri

S0

S1=(31,

1, 1)

S2=(2)

S3

S4

S5

S6=(26)

S7=(27)

S8

S9

R0=(10, 30)

 

 

 

 

 

 

 

 

 

R1=(1)

 

1

 

 

 

 

 

 

 

 

R2=(2)

 

 

2

 

 

 

 

 

 

 

R3=(3)

 

 

 

 

 

 

 

 

 

R4= Ø

 

 

 

 

 

 

 

 

 

R5=(25)

 

 

 

 

 

 

 

 

 

R6= Ø

 

 

 

 

 

 

 

 

 

R7= Ø

 

 

 

 

 

 

 

 

 

R8= Ø

 

 

 

 

 

 

 

 

 

R9= Ø

 

 

 

 

 

 

 

 

 

 

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

Возможны два варианта реализации хешированного соединения.

1. Однопроходной вариант (рис. 1.21).

Все разделы Ri хранятся в оперативной памяти. Последовательно читаются блоки  S с диска. Для каждой записи из S выполняется хеш-функция i=h(a) и значение атрибута соединения данной записи сравнивается со значениями атрибута соединения записей раздела Ri (для краткости будем говорить данная запись соединяется с записями раздела Ri ).

 

 

Рис. 1.21. Распределение памяти в однопроходном варианте.

 

2. Двухпроходной вариант (рис. 1.22).

Таблицы R и S хешируются и их разделы {Ri} и {Si} сохраняются на диске. Далее в ОП читается весь раздел R0 и  в буфер последовательно читаются блоки раздела S0. Их записи соединяются с записями раздела R0. Далее в оперативную память читается весь раздел  R1 и далее S1 поблочно соединяется с R1 и т.д.

 

Рис. 1.22. Распределение памяти в двухпроходном варианте.

 

Теперь рассмотрим одну интересную особенность хешированного соединения.

В методах NLJ и SMJ соединяемые таблицы уже должны храниться на сервере перед выполнением соединения. В методе HJ соединение таблиц R и S может выполняться асинхронно, по мере поступления записей этих таблиц с других серверов (рис. 1.23).

 

Рис. 1.23. Асинхронное соединение таблиц.

 

На рис. 1.23 цифрами обозначены следующие действия:

1 - сравнение поступившей записи с записями соответствующего противоположного раздела;

2 – вывод соединения двух записей при успешном сравнении атрибутов соединения;

3 – сохранение поступившей записи в соответствующем разделе.

Данная особенность позволяет существенно сократить время соединения таблиц.

 

 

1.6.4.      Число кортежей, блоков и мощности атрибутов в соединении

 

Приведенные ниже формулы являются общими для всех рассмотренных выше методов (NLJ, SMJ и HJ).

 

1. Число кортежей в соединении.

                                             (5.10)

2. Число блоков.

3. Мощности атрибутов:

а) мощность атрибута соединения ("а") в результирующей таблице

;

б) мощности остальных атрибутов (b)

 

Здесь T(Q1), T(Q2) – число кортежей в таблицах Q1 и Q2;

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

I(Qi,a) – мощность атрибута "а" в таблице Qi (i=1,2);

LJOIN – число кортежей соединения в одном блоке.

 

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

 

1.7.      Поиск физического плана с минимальной стоимостью

 

Для поиска оптимального физического плана используется один из алгоритмов динамического программирования.

 

1.7.1.      Алгоритм поиска для левостороннего дерева соединений

 

Вход: логический план выполнения SQL-запроса с таблицами R1, …, Rn (см. раздел 1.2).

Выход: квазиоптимальный физический план выполнения запроса.

//Алгоритм динамического программирования

ДЛЯ i=1,n

     AccessPlan(Ri)   //определение

КОНЕЦ ДЛЯ

ДЛЯ i=2,n

     ДЛЯ всех подмножеств  таких, что |P|=i

                                                        // |P| - количество таблиц в P

          ДЛЯ всех таблиц

               // определение метода соединения , дерево

               // соединения таблиц (PQj) уже создано при выполнении

               // предыдущих циклов

               JoinPlan(PQj,Qj)

          КОНЕЦ ДЛЯ

     КОНЕЦ ДЛЯ

КОНЕЦ ДЛЯ

OptPlanReturn({Q1, …, Qn})  //вывод оптимального плана

//Конец алгоритма

 

1.7.2.      Формат экземпляра структуры данных

 

Алгоритм работает с массивом структур. Экземпляр структуры имеет следующий формат:

 

 

1. W – множество имен таблиц {Qi} таких, что W=XÈY, если |W| > 1, и W – имя таблицы Qi , если |W| = 1.

2. X – подмножество исходных таблиц {Qi}, которые использованы для получения левого аргумента соединения XY.

3. Y – имя таблицы Qi, которая используется в качестве правого аргумента соединения XY.

Примечание. Если W содержит имя только одной таблицы, т.е. |W| = 1, то X и Y – пустые поля.

4. Z – текущая стоимость выполнения плана, включающая стоимости выполнения подзапросов и промежуточных соединений, а также стоимость соединения XY, если |W| > 1, или стоимость выполнения подзапроса, если |W| = 1.

5. ZIO – составляющая ввода-вывода в Z (CI/O).

6. V – опции:

1) T(W) – прогнозируемое число кортежей (записей) в таблице W (т.е. T(XY), если  |W| > 1, или T(Qi), если |W| = 1);

2) B(W) – прогнозируемое число блоков в W;

3) {I(W, Ai)}i – мощности атрибутов в W, по которым было выполнено или будет выполняться соединение;

4) к – идентификатор метода выбора записей из исходной таблицы (если |W| = 1) или метода соединения таблиц (если |W| > 1).

 

1.7.3.      Спецификации процедуры AccessPlan

 

ВходRi – имя исходной таблицы.

Выход: заполненный экземпляр структуры str[i].

Алгоритм.

// оценка стоимости выбора записей из Ri для различных методов:

// j=1 – чтение всей таблицы, j=2 – использование индекса.

ДЛЯ j=1,2

     Cj = CCPUj + CI/Oj 

// CCPUj и CI/Oj вычисляются с помощью формул (5.4) (для j=1)

// или с помощью формул (5.5) и (5.6) (для j=2).

КОНЕЦ ДЛЯ

// определение оптимального метода выбора записей из таблицы Ri,

// т.е. kÎ{1,2}, заполнение экземпляра структуры str[i] (см. п. 1.7.2)

C=min (C1, C2)             // здесь С=Сk

str[i] =  {

               {Qi}, Ø, Ø,      // W, X, Y

               C, CI/O k,           // Z, ZIO

               {T(Qi), B(Qi), {min{T(Qi), I(Ri, Aj)}j, k}  // V

// для заполнения полей T(Qi), B(Qi) используются формулы

// пунктов 1.4.4 и 1.4.5

                }                                                                

Конец алгоритма.

 

1.7.4.      Спецификации процедуры JoinPlan

 

Вход:  список имен таблиц R=(PQj) и имя таблицы S=Qj (см. основной алгоритм в п. 1.7.1)

Выход: заполненный экземпляр структуры str[n].

Алгоритм.

Поиск в массиве структур str экземпляров с номерами m1 и m2,

для которых str[m1].W=R и str[m2].W=S .

// Оценка стоимости соединения для различных методов:

// i=1 – NLJ, i=2 – SMJ, i=3 – HJ ;

// выбрать оптимальный метод соединения kÎ(1,2,3).

ДЛЯ i=1,3

     Ci = CCPUi + CI/Oi

          // CCPUi и CI/Oi вычисляются с помощью формул (5.8) (для i=1)

          // или формул (5.9) (для i=2); метод i=3 не рассматривается.

          //  Необходимая информация для расчета по формулам

          //  хранится в полях str[m1].V и str[m2].V.

КОНЕЦ ДЛЯ

C = min(C1, C2)  //здесь С=Сk; пока это стоимость соединения R и S

// текущая стоимость плана, включающая стоимости чтения

// из исходных таблиц и стоимости промежуточных соединений

С = str[m1].Z + str[m2].Z + C 

СI/O = str[m1].ZIO + str[m2].ZIO + CI/O k  // дисковая составляющая

Поиск в массиве структур str экземпляра "n", для которого str[n].W=P. Если экземпляр "n" не найден, то заполнить пустой экземпляр "n". Если экземпляр "n" найден и выполняется неравенство str[n].Z > C, то переписать экземпляр "n". Выражения для заполнения экземпляра "n":

str[n] =  {PRS, C, CI/O ,                       // W, X, Y, Z, ZIO

                 {T(P), B(P), {I(P, Ai)}i, k} }   // V - см. формулы (5.10)

Конец алгоритма.

1.7.5.      Спецификации процедуры OptPlanReturn

 

Вход:  список таблиц Q={Qi}.

Выход: вывод оптимального плана.

Алгоритм.

Поиск в массиве структур str экземпляра i, где str[i].W=Q

// Вывод шага оптимизации

Печать (Q, "=", str[i].X, "", str[i].Y, "метод", str[i].V.k)

Если str[i].X пусто, то выйти из алгоритма

// Вывод оптимального плана для левого аргумента соединения

OptPlanReturn(str[i].X)

// Вывод метода выбора записей  для правого аргумента

// соединения, которым является исходная таблица.

OptPlanReturn(str[i].Y) 

Конец алгоритма.

 

1.8.      Пример построения оптимального физического плана

 

1.8.1.      Логический план

 

Построим оптимальный физический план для примера, который был рассмотрен ранее в разделе 1.3. В этом примере был построен логический план, представленный на рис. 1.24.

 

Рис. 1.24. Логический план выполнения запроса.

 

Ниже приведены исходные данные для построения физического плана:

 

1. Количество записей в исходных таблицах:

         T(R1)=10000, T(R2)=100000

2. Количество записей в одном блоке таблицы:

         LR1= LR2= 100, LJOIN=1000

3. Индексы по атрибутам и число записей в блоке индекса (L):

    таблица R1: индекс по атрибуту "код_пользователя" (L=200),

    таблица R2: индекс по атрибуту "номер_счета" (L = 200).

Примечание. Записи исходных таблиц могут читаться в отсортированном виде по своим индексированным атрибутам. Записи в таблице R1 сгруппированы по атрибуту "код_пользователя" (кластеризованный индекс), записи в таблице R2 не сгруппированы по атрибуту "остаток".

4. Мощности атрибутов в исходных таблицах:

    I(R1, код_пользователя) = 5000, I(R1, номер_счета) = 10000,

    I(R2, номер_счета) = 100000, I(R2, остаток) – неизвестно.

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

6. Некоторые параметры:

    b = 10 – число блоков в буфере;

    Ccomp = Cmove = Cfilter = 0,01 мс;

    CB = 10 мс – время чтения/записи блока на диск.

Для построения оптимального плана воспользуемся алгоритмом динамического программирования (см. п. 1.7.1).

 

1.8.2.      Алгоритм поиска оптимального физического плана

 

Ниже приведена последовательность расчётов.

 

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

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

(Пользователь):

   AccessPlan(R1)  (см. п. 1.7.3).

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

(Счёт):

   AccessPlan(R2)  (см. п. 1.7.3).

 

Определение метода и порядка соединения :

3. Оценка соединения Q1 и Q2 методом NLJ:

    в JoinPlan(Q1, Q2) (см. п. 1.7.4).

4. Оценка соединения Q1 и Q2 методом SMJ:

    в JoinPlan(Q1, Q2) (см. п. 1.7.4).

5. Выбор метода соединения Q1 и Q2 и заполнение структуры:

    в JoinPlan(Q1, Q2) (см. п. 1.7.4).

6. Оценка и выбор метода соединения Q2 и Q1 (по аналогии с

    пунктами 3 - 4), сравнение вариантов:

    JoinPlan(Q2, Q1) (см. п. 1.7.4).

 

Вывод оптимального физического плана:

7. Вывод физического плана:

    OptPlanReturn({Q1, Q2})  (см. п. 1.7.5).

8. Представление физического плана в графическом виде.

 

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

 

Алгоритм AccessPlan (см. п. 1.7.3) для таблицы R1 ("Пользователь"):

1. j = 1 – чтение всей таблицы (формулы (5.4)):

 

 

2. j = 2 – использование индекса по атрибуту "код_пользователя" (формулы (5.5) и (5.6), здесь "а" – "код_пользователя"):

 

 

C = C2 = 0,32 мс – минимальная стоимость.

CI/O = CI/O2 = 0,3 мс – составляющая ввода-вывода.

 (п. 1.4.4).   

   (п. 1.4.5).

 

При вычислении B(Q1) полагаем, что число записей в блоке  проекции πR1.номер_счета в 10 раз больше, чем в блоке таблицы R1 .

 

Заполнение структуры str[1] (п. 1.7.2):

 

str[1] = {{Q1}, Ø, Ø, 0.32, 0.3,        // W, X, Y, Z, ZIO

   {2, 1, {2}, 2} }                                // V: {T(Q1), B(Q1), {min(T(Q1),

                                                           // I(R1,номер_счёта))}, k }

 

 

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

 

Алгоритм AccessPlan (см. п. 1.7.3) для таблицы R2 ("Счёт"):

1. j = 1 – чтение всей таблицы (формулы (5.4)):

 

 

2. j = 2 – чтения по индексу нет, так как нет индекса по атрибуту "Остаток" (см. запрос Q2  - п. 1.8.1).

C = C1 = 11000 мс .

CI/O = CI/O1 = 10000 мс .

//При вычислении T(Q2) вероятность принята равной 1/3, поскольку

//мощность атрибута "Остаток"  в таблице R2 неизвестна.

 (см. п. 1.4.4).   

  (см. п. 1.4.5).

 

Заполнение структуры str[2] (п. 1.7.2):

 

str[2] ={{Q2}, Ø, Ø, 11000, 10000,   // W, X, Y, Z, ZIO

            {33000, 33, {33000}, 1}}    //V:{T(Q2),B(Q2),

                                                       //{min(T(Q2),I(R2,номер счёта))},k}

 

1.8.5.      Оценка соединения Q1 и Q2 методом NLJ

 

В алгоритме динамического программирования (см. п. 1.7.1):

n = 2, i = 2, P = (Q1, Q2), Qj = Q2  (параметры трёх вложенных циклов).

 

В JoinPlan (Q1, Q2) (см. п. 1.7.4):

R = PQ2 = Q1, S = Q2 , "а" – атрибут "номер_счета".

Алгоритм:

m1 = 1, m2 = 2  // номера экземпляров в структуре str, т.к.   

                         // str[m1=1].W= Q1 и str[m2=2].W= Q2

// Оценка стоимости соединения R и S методом NLJ, i=1

// (формулы (5.8), для оценки используются данные из str[1],

// str[2] - см. пункты 1.8.3 и 1.8.4):

 

1.8.6.      Оценка соединения Q1 и Q2 методом SMJ

 

Продолжение алгоритма JoinPlan (Q1, Q2) (см. п. 1.7.4):

// Оценка стоимости соединения R и S методом SMJ, i=2

// (формулы (5.9), используются данные из str[1], str[2] - см.

//  пункты 1.8.3 и 1.8.4).

// Таблица Q уже отсортирована по номеру счета, так как

// имеется индекс по этому атрибуту.

 

 

1.8.7.      Выбор метода соединения Q1 и Q2 и заполнение структуры

 

Продолжение алгоритма JoinPlan (Q1, Q2) (см. п. 1.7.4):

//  Стоимость соединения Q1 и Q2

 

С = min1 2)= min(660, 340) = С2 =340 (мс)  // SMJ

 

// Текущая стоимость плана

С = str[1].Z + str[2].Z + C = 0,32 + 11000 + 340 @11340 (мс),

// где str[1].Z и str[2].Z – стоимости выбора записей из

// исходных таблиц R1 и R2 (см. пункты 1.8.3 и 1.8.4),

// С (справа) – стоимость соединения по методу SMJ.

 

// Стоимость ввода/вывода

СI/O = str[1].ZIO + str[2].ZIO + CI/O 2 = 0,3 + 10000 + 10 ≈ 10010 (мс).

// Значения полей V структуры str[3] (формулы (5.10) в п. 1.6.4):

 

 

 

.

 

Заполнение структуры str[3] (п. 1.7.2):

 

str[3] =    {{Q1, Q2}, {Q1}, {Q2},      // W, X, Y

                 11340, 10010,                 // Z, ZIO

                 {2, 1, {2}, 2} }                // V - , B, I, k

 

1.8.8.      Оценка и выбор метода соединения Q2 и Q1

 

В алгоритме динамического программирования (см. п. 1.7.1):

n = 2, i = 2, P = (Q1, Q2), Qj = Q1 .

 

В JoinPlan (Q2, Q1) (см. п. 1.7.4):

R = PQ1 = Q2, S = Q1 , "а" – атрибут "номер_счета".

Алгоритм:

m1 = 2, m2 = 1   // номера экземпляров в структуре str, т.к.   

                         // str[m1=2].W= Q2 и str[m2=1].W= Q1

// Оценка стоимости соединения R и S (см. формулы пунктов 1.8.5 и  

// 1.8.6)

1. NLJ, i=1

2. SMJ, i=2

 

//  Стоимость соединения Q2 и Q1

С = min12) = С2= 340 (мс)               // SMJ

 

// Текущая стоимость плана

С = str[2].Z + str[1].Z + C = 11340 (мс)

 

Запись str[3] не изменяется, так как старое значение str[3].Z совпадает с новым значением (C).

 

1.8.9.      Вывод физического плана

 

Алгоритм OptPlanReturn (см. п. 1.7.5):

 

1.  метод 2 (т.е. SMJ)

 

2. Q1 = метод 2

    (т.е. IndexScan(R1, код_пользователя = 3) +

            Filter (реализация проекции по номеру счета)

     )

3. Q2 = метод 1

    (т.е. TableScan(R2) +

            Filter (селекция по условию остаток > 1500 и реализация

            проекции по остатку и  номеру счета)

     )

 

Метод чтения записей из R2 (чтение всех записей) является причиной высокой стоимости выполнения запроса.

 

На рис. 1.25 представлен разработанный оптимальный физический план в графическом виде.

 

 

Рис. 1.25. Представление физического плана в графическом виде.


Григорьев Ю.А., Ревунков Г.И. Банки данных

Постреляционные базы данных

Содержание

Определения

Базы данных

Большой объём долгосрочно хранящихся данных.

СУБД

Система управления базами данных. Чтобы программа могла называться СУБД, она должна обеспечивать следующее:

  • специальные языки, которые предоставляют:
    • DDL - для описания структуры БД;
    • DML - для манипулирования данных (добавление, удаление, изменение, запросы).
  • хранение больших объёмов структурированных данных;
  • восстановление после сбоев;
  • параллельная работа с данными нескольких пользователей;
  • выполнение транзакций - набора действий, из которого выполняются либо все, либо ни одно;
  • защита информации от несанкционированного доступа;
  • возможность оптимизации запросов;
  • поиск информации в огромных объёмах информации.

Технология работы с БД

  • Определение структуры данных:
    • ER-реляция (SQL);
    • объектная реляция (расширенный SQL);
    • объектно-ориентированная (ODL);
    • полуструктурированная (XML).
  • Программирование БД:
    • SQL + объектное расширение SQL;
    • OQL;
    • Datalog;
    • xQuery, xPath;
    • драйвера доступа (ODBC, LINQ, MVC);
    • all in/out;
    • проекция классов;
    • хранимые процедуры, функции, триггеры.
  • Реализация СУБД;
  • Интеграция информации (OLAP, data-mining).

Поколения СУБД

Первое поколение

1960 годы, сетевые и иерархические системы. Применялись в следующих сферах:

  • бронирование и продажа билетов;
  • банковскиие системы;
  • корпоративные системы (покупки, продажи, сотрудники).

Второе поколение

1970-90 годы. Реляционные БД. Связи хранятся в виде таблиц отношений. SQL.

Третье поколение

Постреляционные БД - это БД и СУБД так называемого третьего поколения.

Проблемы реляционных БД и задачи постреляционных БД:

  • уменьшение и удешевление систем;
  • большие объёмы хранимых данных. Реляционные БД нормально справляются с гигабайтами, но уже с трудом с терабайтами и выше;
  • появление третичных устройств хранения (первичные - RAM, вторичные - HDD), то есть съёмных дисков. Суть в том, что скорость чтения всё ниже и ниже;
  • параллельное хранение данных (типа RAID). Запросы теперь нужно разбивать, а потом соединять;
  • данные со сложной структурой (мультимедийные данные). Требуются новые типы данных;
  • появление распределённых архитектур;
  • интеграция информации и наследование БД.

Постреляционные БД

Делятся на два вида:

  • объектно-ориентированные БД;
  • объектно-реляционные БД.

Оба очень близки и различаются, в основном, только внутренней реализацией.

Основные возможности постреляционных БД

Расширение системы типов данных

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

Инкапсуляция

В БД хранятся объекты. У объектов есть данные и методы, открытые и закрытые поля. Для разрешения проблемы необходимости доступа к скрытым полям используются специальные методы: обозреватели (get) и модификаторы (set);

Наследование

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

Полиморфизм и позднее связывание

Типы и классы

Тип - это некоторое описание, как следует работать с переменной или объектом. Используются на этапе компиляции для проверки соответствия.

Класс поддерживает иерархию и от типа отличается:

  • используется для производства (генерации) новых объектов;
  • экстент - множество объектов конкретного класса.

Идентифицируемость объекта

У БД идентификатором объекта является первичный ключ записи таблицы. В программировании идентификатором объекта является его адрес в памяти.

Различаются два понятия: равенство (одинаковый с другим) и идентичность (он сам).

Копирование может быть поверхностным и глубоким. При поверхностном копировании копируется только ссылка, а при глубоком также и внутренняя структура объекта.

Правила и триггеры

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

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

Обновление представления

Обновляемые представления позволяют скрыть от пользователя структуру БД и изменять данные.

Для их реализации могут использоваться правила либо специальные триггеры типа instead.

Язык работы с БД

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

Проблемы взаимодействия ПО и СУБД

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

Модели данных

  • концептуальные
    • ER - сущность-связь
  • физические
    • реляционная;
    • объектная;
    • объектно-реляционная - отношение, содержащие дополнительные возможности;
    • полуструктурированных данных - и сами данные, и структуры, и сведения о них.

Entity-Relationship

Она же ER - модель "сущность-связь".

Нотации

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

Мартина

IDEF/X

Бартера

Чена

Связи:

  • 1-1, один к одному;
  • 1-М, один ко многим;
  • М-1, многие к одному;
  • М-М, многие ко многим.

ISA-связи - базовая и производная сущности. Производная наследует атрибуты и ключ базовой.

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

Пример:

Сущности:

  • Актёр (ИНН, ФИО, Образование);
  • Фильм (Название, Год, Длительность, Название студии);
  • Студия (Название студии, адрес);
  • Актёр-фильм (ИНН, Название, Год).

Три варианта преобразования ISA:

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

Преобразование ER-модели в реляционную

  • Множество сущностей отношение;
  • ключ ключ;
  • связь 1-М к сущности на стороне М добавляется внешний ключ, указывающий на первичный ключ сущности на стороне 1;
  • связь М-М создается дополнительное отношение, содержащее ключи связанных таблиц;
  • слабая сущность отношение с атрибутами слабой сущности плюс ключи поддерживающих сущностей. Например:
    Кафедра( Название кафедры, Название ВУЗа, заведующий кафедрой)

Объектная модель

Уникальный идентификатор объекта - OID. У объектов поддерживаются методы. Есть наследование, инкапсуляция и полиморфизм. Можно создавать собственные типы данных, составные типы (структуры, коллекции, ссылки). Разделение на интерфейс и реализацию.

Объекты - некоторая переменная, может изменять значение, характеризуется своим OID.

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

Объектная модель состоит из:

  • ODL (язык определения объектов) - для описания БД;
  • OML (язык манипулирования данными) - для работы с объектами, расширение для стандартного языка;
  • OQL (язык объектных запросов) - основан на SQL, имеет расширение.

Возможности описания объектных БД

Классы

ODL позволяет описывать классы - объектные типы.

class название
[extends базовый класс : интерфейсы]
(extent название key ключи)
{
	атрибуты
	методы
	связи
};
class Actor
(extent EA)
{
    attribute struct {string f, string i, string o} fio;
    attribute string edu;
    attribute integer inn;
    relationship set<Film> films inverse Film::actors
};
 
class Film
(extent EF key(title, year)) //составной ключ
{
    attribute string title;
    attribute integer year;
    attribute enum {col, bw, sl} type;
    attribute integer len;
    relationship set <Actor> actors inverse Actor::films;
    relationship Studio stud inverse Studio::films;
}; 
 
class Studio
(extent ES key name, mgn) //альтернативный ключ
{
    attribute string name;
    attribute addr;
    relationship set<Film> films inverse Film::stud
    integer mgn();
    integer filmscnt(integer year) raises (noFilm, noyear);
};

Интерфейсы

Интерфейс - аналог класса, который не имеет реализации и объектов.

interface название
[extends интерфейс1 : интерфейс2]
{
	атрибуты
	методы
	связи
};


interface IVuz
{
    attribute ...
    string fun();
    relationship ....
};

Атрибуты

attribute тип название

Коллекции

    set <тип> - множество
    bag<тип> - мультимножество
    array<тип, количество>
    dictionary <тип (ключ), тип (значение)>

Методы

 возвращаемый_тип название (аргумент1, аргумент2, ...) raises(исключение1, исключение2...)

Аргумент

    in/out/inout тип имя

Связи

Продолжаем работать с нашим примером:

ODL

Для нашего примера

Кстати, ключи везде прописывать не обязательно, потому что по умолчанию всегда будет OID. И он будет назначаться всегда, даже если мы объявим ещё и свой ключ.

class Film(extent Films
	key(name, year))
{
 attribute string name;
 attribute integer year;
 attribute integer len;
 attribute enum Ftype {bw, color} type;
 
 relationship Studia stud
	inverse Studia::fs;
 
 relationship Set<Actor> acts 
	inverse Actor::infs;
 
 -- пример метода. Считает актёров и возвращает noActors, если нету ни одного
 integer ActCount() raises(noActors);
 
 void FinYear(in integer year, out Set<Films>) raises(noFilms, badYear);
};
 
class Studia(extent Studies)
{
 attribute string sname;
 attribute Struct Addr
	{
	 string city,
	 string street
	} addr;
 
 relationship Set<Film> fs
	inverse Film::stud;
};
 
class Actor(extent Actors
	key inn)
{
 attribute string inn;
 attribute string fio;
 attribute List<string> edu;
 
 relationship Set<Film> infs
	inverse Film::acts;
};
 
class MF extends Film(extent MFS)
{
 attribute string drawer;
};
 
class Drama extends Film (extent Dranas)
{
 attribute Struct
	{
	 Set<string> authors,
	 string bname
	} book;
};

Для примера с ВУЗом

class Vuz(extent Vs)
{
 attribute string name;
 
 relationship Set<Kaf> Kafs
	inverse Kaf::vuzz;
};
 
-- слабая сущность
class Kaf(extent Ks
	key(kname, vuzz))
{
 attribute string kname;
 
 relationship Vuz vuzz
	inverse Vuz::Kafs;
};

Про связи

Все связи строго бинарны - можно связать только два объекта. Чтобы связать больше объектов (например, три), надо делать так:

class Gr(extent ...)
{
 attribute ...
 
 relationship Set<ADG> gin
	inverse ADG::g;
};
 
class Dis(extent ...)
{
 relationship Set<ADG> din
	inverse ADG::d;
};
 
class Aud(extent ...)
{
 relationship Set<ADG> in
	inverse ADG::a;
};
 
-- этот класс содержит связи
class ADG(extent edgs)
{ 
 relationship Aud a
	inverse Aud::in;
 relationship Dis d
	inverse Dis::din;
 relationship Gr g
	inverse Gr::gin;
};

Переход от объектной модели к реляционной модели

Когда это может понадобиться:

  • при переходе из объектного проекта в реляционную реализацию;
  • при необходимости создать реляционную проекцию в объектной БД.

Преобразования:

  • класс с экземплярами атомарных атрибутов преобразуется в схему отношений с теми же самыми атрибутами;
  • составные атрибуты преобразуются в ненормализованное отношение, которое после этого надо нормализовать во избежание аномалий;
  • методы не преобразуются вообще, они теряются, так как в реляции методов нет;
  • ключ преобразуется в ключ;
  • если ключа не было, то вводится дополнительное поле, которое будет ключом;
  • у структур поля преобразуются в отдельный атрибут;
  • множества преобразуются в множества кортежей.
  • Отношение М-М = отдельная таблица с ключами
  • Отношение 1-М = FK на стороне М

Пример с нашим примером:

Films(name, year, len, type);
Stusies(sname, city, street, sid);
Actor(f, i ,o, edu, inn);

Объектно-реляционная модель данных

Это расширение реляционной модели. В основе лежит реляция - те же самые схемы отношений, экземпляры отношений, но добавляются некоторые возможности:

  • составные атрибуты:
    • структура;
    • коллекция:
      • список;
      • массив;
      • мультимножество;
      • множество структур (вложенное отношение):
Actors(inn, fio, edu(year, Vuz));
  • методы;
    • методы экземпляров;
    • методы классов;
  • ссылки - теперь в качестве значения атрибута можно хранить ссылку на конкретный кортеж:
Studies(sname, addr, sid
Films(name, year, len, type, stud(*(Studies)));

Для соблюдения стандарта SQL'99 связь 1:M создаётся добавлением в таблицу со стороны М ссылки на кортеж таблицы со стороны 1.

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

Сравнение объектной и объектно-реляционной модели

Объектная модель Объектно-реляционная модель
класс → экстент
объект
схема отношения → отношение (таблица)
кортеж
методы методы
структуры, коллекции,
множество структур (классы)
структуры, коллекции,
множество структур (схемы отношений или вложенные отношения)
OID скрыт OID может быть доступен
1 класс - 1 экстент
1 интерфейс - N классов и N их экстентов
1 схема отношений - N отношений (таблиц)
обратной совместимости с реляционной моделью нет обратно совместима с реляционной моделью

Модель полуструктурированных данных

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

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

Полуструктурированный граф:

  • корень - вся БД;
  • конечные вершины - хранимые атомарные атрибуты;
  • промежуточные вершины - объекты (структура данных);
  • дуги - смысл, назначение, связь данных.

Граф по нашему примеру можно построить такой:

Для упрощения показаны лишь некоторые сущности, атрибуты и связи.

XML

XML (Extensible Markup Language) - расширяемый язык данных, используется для линейной записи полуструктурированных данных. И ещё для разметки текста. Чтобы не рисовать тот граф, можно описать всё в XML.

XML бывает двух видов:

  • формально-правильный (well-formed);
  • действительный (valid).

Оба чувствительны к регистру.

Формально-правильный XML

Например:

<?xml version="1.0" encoding="UTF8" standalone="yes"?>
<sometag></sometag> <!-- парный тег -->
<sometag />         <!-- тоже парный, но не требует закрытия>

Требования к XML:

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

Наш пример:

<?xml version="1.0" encoding="UTF8" standalone="yes"?>
<db>
	<film idf="f1" toact="a1" tos="s1">
		<name>Bridge to Terabithia</name>
		<year>2007</year>
		<len>96</len>
		<type>must see</type>
	</film>
	<film idf="f2" toact="a2">
		<name>The Matrix</name>
		<year>1999</year>
		<len>136</len>
		<type>bloody have to see dat</type>
	</film>
	<actor ida="a1" tof="f1">
		<fio>
			<family>Robb</family>
			<fname>Anna</fname>
			<secname>Sophia</secname>
		</fio>
	</actor>
	<actor ida="a2" tof="f2">
		<fio>
			<family>Reeves</family>
			<fname>Keanu</fname>
			<secname>Charles</secname>
		</fio>
	</actor>
	<studio ids="s1" tof="f1">
		<name>Walden Media</name>
	</studio>
</db>

Действительный XML

DTD (Document Type Definition) - определение типов документов. Содержит определённый набор допустимых тегов, атрибутов, правил вложения.

<!ELEMENT название содержимое>

Элементы:

+ - должен быть хотя бы один или больше;
- может быть ни одного или сколько угодно;
? - строго один или ни одного.

А если ничего нет, то строго один.

Наш пример:

<!ELEMENT db (film*, actor*, stud+)>
<!ELEMENT film (name, year, len?, type?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT len (#PCDATA)>
<!ELEMENT type (#PCDATA)>

Атрибуты:

<!ATLIST элемент 
	атрибут1 тип параметры
	атрибут2 тип параметры
	атрибут3 тип параметры
>

Типы атрибутов:

  • CDATA - текст;
  • ID - идентификатор;
  • IDREF - ссылка;
  • IDREFS - ссылки (через пробел);
  • NMTOKEN - лексема;
  • NMTOKENS - лексемы.

Параметры:

  • #REQUIRED - обязательный;
  • #IMPLIED - необязательной;
  • #FIXED - фиксированный.

Пример:

<!ATTLIST film idf ID #REQUIRED toact IDREFS tos IDREF>
<!ATTLIST actor ida ID tof IDREFS>
<!ATTLIST studio ias ID tof IDREFS>

Также можно указать значение по умолчанию и перечень допустимых значений:

<!ATTLIST p align (left|center|right) "left">

Сочетание обоих видов

Они могут сочетаться.

Первый вариант

С непосредственной вставкой:

<?xml version="1.0" encoding="UTF8" standalone="yes"?>
<!DOCTYPE db [
	<!ELEMENT ...>
	<!ATTLIST ...>
             ]>
<db>
	...
</db>
Второй вариант

С включением внешнего файла:

<?xml version="1.0" encoding="UTF8" standalone="no"?>
<!DOCTYPE db SYSTEM "file.dtd">
<db>
</db>

И сам этот file.dtd:

<!ELEMENT ...>
<!ATTLIST ...>

XSD

XSD (XML Schema Definition) - это схемы XML.

Их свойства:

  • добавлена работа с нормальными типами данных (int, bool, string и остальные);
  • позволяют накладывать ограничения (год не может быть меньше 1500);
  • сами являются XML-документами;
  • позволяют использовать пространства имён.

Языки запросов

  • SQL;
  • объектное расширение SQL;
  • OQL;
  • Datalog;
  • XQuery.

SQL

Умеет:

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

Типы данных:

  • integer;
  • float;
  • boolean;
  • char(10);
  • varchar(255);
  • clob;
  • blob;
  • domain.

Синтаксис

Создание таблицы
CREATE TABLE таблица
(
    поле1 тип ограничение,
    поле2 тип ограничение,
    поле3 тип ограничение
);
Ограничения

Могут иметь имена:

CONSTRAINT имя;

Например:

ALTER TABLE таблица
ADD CONSTRAINT имя CHECK(условие);

Виды ограничений:

  • уровня атрибутов:
    • NOT NULL;
    • DEFAULT;
    • UNIQUE;
    • CHECK();
  • уровня кортежей:
    • PRIMARY KEY();
    • FOREIGN KEY() REFERENCES table();
    • DEFERRABLE INITIALLY DEFERRED;
    • CHECK();
  • общего вида - проверяется при любом изменении БД:
    • ASSERTION;
    • триггеры.

Например:

CREATE ASSERTION имя
CHECK((SELECT COUNT(*) FROM таблица1) > (SELECT COUNT(*) FROM таблица2);

Пример триггера:

AFTER UPDATE [OF поле] ON таблица REFERENCING
    OLD ROW AS имя1
    NEW ROW AS имя2
FOR EACH ROW [WHEN(условие)] {тело SQL};
Удаление таблицы
DROP TABLE таблица;
Создание индекса
CREATE [UNIQUE] INDEX имя
ON таблица();
Соединение таблиц
  • таблица1 × таблица2;
  • join;
  • natural join;
  • cross join;
  • outer join:
    • left outer join;
    • right outer join;
    • full outer join.

Примеры

Film(name, year, len, type, stud);

Actor(inn, fio, edu);

Stud(sname, addr);

FA(inn, name, year);

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

CREATE TABLE Film
(
     name VARCHAR(50),
     YEAR INTEGER CHECK(year>1850 AND YEAR <=2012), -- потому что конец света
     len INTEGER NOT NULL DEFAULT 120,
     TYPE CHAR(2),
     stud INTEGER REFERENCES Stud(sid) ON UPDATE CASCADE ON DELETE SET NULL,
 
     PRIMARY KEY(name, YEAR)
);
 
CREATE TABLE Stud
(
     sid INTEGER PRIMARY KEY UNIQUE,
     sname VARCHAR(50) NOT NULL,
     addr VARCHAR(300)
);
 
CREATE TABLE Actor
(
    inn CHAR(10) PRIMARY KEY,
    fio VARCHAR(200),
    edu VARCHAR(50),
    CHECK(edu IN('среднее', 'высшее', 'Щукинское'))
);
 
CREATE TABLE FA
(
    act CHAR(10) NOT NULL REFERENCES Actor(inn),
    fname VARCHAR(50) NOT NULL,
    fyear INTEGER NOT NULL,
 
    FOREIGN KEY(fname, fyear) REFERENCES Film(name, YEAR),
    PRIMARY KEY(act, fname, fyear)
);

Извлечение данных:

SELECT * | поля | выражения | агрегация
FROM таблица | вложенный запрос
WHERE условие [AND | OR | NOT условие];

Примеры:

-- выбрать фильмы, снятые в 60-е года
SELECT *
FROM Film
WHERE YEAR > 1950 AND YEAR < 1960;
 
-- выбрать что-то ещё
SELECT name, YEAR, len/60 AS HOUR
FROM Film
WHERE (name LIKE '%s' OR name LIKE '_a')
  AND EXISTS(SELECT * FA WHERE fname = name)
ORDER BY name, YEAR DESC;
 
-- фильмы студий Лос-Анджелеса
SELECT name, YEAR, sname
FROM Film JOIN Stud ON stud = sid
WHERE addr = 'Los Angeles';
 
-- актёры фильма "The Matrix"
SELECT fio
FROM Actors JOIN FA ON inn = act
WHERE fname = 'The Matrix';
 
-- актёры, которые не снимались ни в одном фильме
SELECT fio
FROM Actor
WHERE inn NOT IN(SELECT act FROM FA);
 
-- актёры, которые снялись хотя бы в одном фильме
SELECT fio
FROM Actor
WHERE inn IN(SELECT act FROM FA);
 
-- актёр, игравший во всех фильмах
SELECT *
FROM Actors
WHERE NOT EXISTS
(
    (
        SELECT название, год
        FROM Фильм
    )
    EXCEPT
    (
        SELECT название, год
        FROM ФА
        WHERE ФА.inn = Актёр.inn
    )
)

Языки запросов

SQL

Синтаксис

Представления
CREATE VIEW(поле1, поле2, поле3) AS
    SELECT name, YEAR, stud
    FROM film;

Обновляемые представления - позволяют не только SELECT, но и изменение данных в таблице. Должно быть на основе одной таблицы и содержать обязательные поля.

Примеры

-- чёрно-белые фильмы с группировкой, условием отбора и сортировкой
SELECT name, MAX(YEAR), stud
FROM film
WHERE TYPE = 'bw' GROUP BY name -- группировка
HAVING MIN(YEAR) > 1930         -- условия отбора групп
ORDER BY name DESC;             -- сортировка
 
-- объединение
SELECT ...
UNION [ALL] ...
SELECT ...
 
-- пересечение
SELECT ...
INTERSECT [ALL] ...
SELECT ...
 
-- разность
SELECT ...
EXCEPT [ALL] ...
SELECT ...
 
-- без повторений
SELECT DISTINCT name
FROM film;

Языкы запросов к XML-документам

Пример XML-документа:

<?xml ... ?>
<db>
    <films>
        <f fid="f1" year=1995>
            <name>Собачье сердце</name>
            <role ra="11">Профессор</role>
            <role ra="22">Пёс</role>
            <stud>МФ</stud>
        </f>
        <f fid="f2" year=1993>
            <name>Терминатор</name>
            <role ra="3">Терминатор</role>
            <stud>WB</stud>
            <stud>F20</stud>
        </f>
    </films>
 
    <acts>
        <a inn="11">
            <pers fio="Иванов Иван Иванович">
                <addr>Москва, Ленина, 1</addr>
                <teatr>Ленком</teatr>
                <teatr>Большой театр</teatr>
                <stud>
                    <name>Мосфильм</name>
                    <addr>Москва, Комсомола, 2</addr>
                </stud>
            </pers>
        </a>
    </acts>
</db>

XPath

XML Path Language. Строит по документу дерево полуструктурированных данных.

Обозначения:

  • // потомки;
  • .. родители;
  • . self.

Сокращённая запись пути до фильма:

/db/films/f/name

Полная запись:

/child::db/child::film/child::f

Сокращённая до фильма 1995 года:

/db/films/f/name[../@year="1995"]

Полная:

/child::db/child::film/child::f/child::name[parent(::)/attribute::year="1995"]
Оси
  • child - потомки. Стоит по умолчанию, потому можно не указывать;
  • attribute - атрибуты @;
  • parent - родители;
  • ancestor - все предки;
  • ancestor-or-self - все предки или я сам;
  • descendant - все потомки вне зависимости от уровня вложенности;
  • descendant-or-self - все потомки или я сам;
  • following - все следующие (без предков и потомков);
  • following-sibling - все следующие на одном уровне за текущим;
  • preceding - все предыдущие (без предков и потомков)
  • preceding-sibling - все предыдущие на одном уровне перед текущим;
  • namespace - пространство имён.
Функции

Имеется много встроенных функций. Основные:

  • сount() - подсчёт;
  • sum() - сумма;
  • min() - минимум;
  • max() - максимум;
  • name() - строка;
  • substring(str, start, size) - подстрока.
Примеры

Все потомки:

/db//f

Все элементы name:

/db//name

Все вложенные через два уровня:

//db/*/*/name

Третий фильм:

//f[3]

Третий фильм, если он снят в 1950 году:

//f[3][@year="1950"]

Все фильмы, снятые в 1950, и взять из них третий:

//f[@year="1950"][3]

Все актёры, которые работали в Ленкоме:

//a[./pers/teatr/text()="Ленком"]

Все родители для театра Ленком:

//teatr[text()="Ленком"]/parent::*

Все актёры, у которых указано более трёх театров или более двух адресов:

//a[count(teatr)>3 OR count(//addr)>2]

Все фильмы, в которых снимались актёры Ивановы Иваны Ивановичи:

//f[//a[pers/@fio="Иванов Иван Иванович"]/@inn=role/@ra]

XQuery

Всё ещё сложнее, чем в XPath - он его расширил. Есть условия, функции, вложенные циклы.

Примеры:

вот один:

let $a = 10, $b = 20, $c = "hello"
for $x in колонка
return $x
return <a>{$x}</a>

вот другой:

for $x in document("filename.xml")/db//a
let $c = $x/count(pers/teatr)
where $c > 2 and $a/pers/addr != "Москва"
return {$x, $c}
return <act fio={$x/pers/@fio}>
Формат вывода

Возврат элемента:

return $x

Возврат значения:

return data($x/pers/...)
Вложенные циклы

Как выглядит вложенный цикл:

for $x in document("filename.xml")//a,
    $y in $x//teatr
return <newel>{$a/@inn $y/text()}</newel>
order by $y/text()
Функции

Объявление функции:

declare function fun($var as XS:integer) as element(act)*
   {return element act {$var}}

Вызов функции:

return {fun(10)}

SQL

Хранимые процедуры

Описание процедуры:

CREATE PROCEDURE Proc1 (<IN, OUT, inout>, имя тип)
DECLARE имя тип -- объявление процедуры
BEGIN
    -- объявление переменных
    SET a = 10;
    SET b = NULL;
    SET c = (SELECT COUNT(*) FROM таблица);
 
    -- условия
    IF a > 10 THEN a = 4 elseif a < 10 THEN a = 16 ELSE a = 9000 endif;
 
    -- цикл
    while условие do
        -- тело цикла
    END while;
END;

Вызов процедуры:

CALL someProc(10, 'abc');

Функции

Функции похожи на хранимые процедуры, но отличаются:

  • обязана возвращать значение;
  • все параметры только входящие.

Важно, что return не возвращает управление.

CREATE FUNCTION func(a INT, b CHAR(2)) RETURNS INT
DECLARE ...
BEGIN
    -- тело функции
END;

Функции вызываются из запросов. Функции могут быть:

  • скалярные - возвращают одно значение (обращение к полю):
SELECT a, func1(a) FROM T
  • табличные - возвращают набор записей (обращение к таблице);
SELECT a, b FROM func2('...')

Cursor

Это итератор по строкам результата запроса (как QSqlRecord в QSqlQueryModel):

DECLARE C cursor FOR
    SELECT name, YEAR FROM someTable
    WHERE city = 'Москва'
BEGIN
    OPEN C; -- выполнение запроса
    l: loop
        fetch FROM C INTO ... -- проход по строкам
        IF состояние THEN leave l endif;
    END loop;
    close C;
END;

Перехват исключений в где-то

DECLARE <undo, exit, continue> handler
    FOR состояние1, состояние2, состояние3
    -- действие

Перехват исключений в Microsoft SQL Server

-- ловля исключений
BEGIN try
    -- какие-нибудь действия
END try;
 
-- блок обработчиков
BEGIN catch
    SELECT error_number(), error_message() ...
END catch;

Вызов исключений:

raiserror(код сообщения, серьёзность, состояние)

Расширения SQL(99)

Рекурсия

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

-- просто таблица
Road(fr, TO, len);
 
-- рекурсия
WITH Recursive R(f, t, l)
    AS(
        -- база рекурсии
        SELECT fr, TO, len FROM Road
        UNION
        -- индукция рекурсии
        SELECT r1.fr, r2.t, r1.len + r2.l
        FROM Road r1, R, r2 -- итерационный вызов R        WHERE r1.to = r2.f
    );
 
-- теперь можно запросить эту рекурсию
SELECT * FROM R;

Чтобы рекурсия не выполнялась вечно, должна быть соблюдена монотонность - на каждом шаге итерации вычисляемое значение должно только пополняться, из него не должны исчезать ранее определённые кортежи. Чтобы это выполнялось, запрещается в вычисляемой части использовать DISTINCT, GROUP BY, EXCEPT, INTERSECT и другие функции агрегирования.

Преобразование

PIVOT - преобразование столбца в строку

Исходная таблица:

Tab
year mounth cnt
2007 Jan 10
2008 Feb 20

Получится:

SELECT YEAR, Jan, Feb ...
FROM (SELECT YEAR, mounth, cnt FROM Tab) t -- t - это псевдоним подзапроса
PIVOT(SUM(cnt) FOR mounth IN (Jan, Feb ...)) p -- p - это псевдоним PIVOT'а
year Jan Feb ...
2007 100 250 ...
2008 ... ... ...

Ранжирование

SELECT
    ROW_NUMBER() OVER (ORDER BY name) AS N1,
    rank()       OVER (ORDER BY name) AS N2,
    dense_rank() OVER (ORDER BY name) AS N3,
    ntile(3)     OVER (ORDER BY name) AS N4,
        name
    FROM Tab;
Tab
N1 N2 N3 N4 name
1
2
1
2
1
2
1
1
A
B
3
4
3
3
3
3
1
2
C
C
5
6
5
5
4
4
2
3
D
D
7 7 5 3 E

DDL-триггеры

Триггеры на изменение схемы данных.

CREATE TRIGGER имя ON <DATABASE, ALL server>
FOR событие CREATE_TABLE
after ...
AS
    -- тело события
    ...
    eventdata(); -- возвращает XML

Сложные типы данных

Объявление:

CREATE teble tab(
    ia INT,
    ab INT array[3],           -- массив
    mc INT multiset,           -- мультимножество
    r ROW(r1 INT, r2 CHAR(3)); -- структура
    );

Добавление значений:

INSERT INTO tab
VALUES(
    10,
    array[1, 2, 3],
    multiset(1, 1, 5, 7, 7)
    (15, 'abc');

Получение значений:

SELECT 
    ia,
    ab[1], ab[2],
    r.r1, r.r2
FROM tab;

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

Создание нового типа данных

Они же пользовательские типы данных (UDT).

CREATE TYPE Addr AS
    (
     city CHAR(10),
     str CHAR(20) defailt ''
    )
 
 -- объявление метода
 method fulladdr() RETURNS CHAR(30);
 
 -- определение метода
 CREATE method fulladdr() RETURNS CHAR(30)
 FOR Addr
 BEGIN
    -- туловко метода
 END;

SQL

Пользовательские типы данных

User Defined Types - UDT.

Создаём свой тип:

CREATE TYPE Addr AS
(
    city CHAR(20),
    street VARCHAR(100)
)
-- объявление метода
method fullad() RETURNS VARCHAR(130);
 
-- определение метода
CREATE method fullad() RETURNS VARCHAR(130)
FOR Addr
BEGIN
    RETURN SELF.city || SELF.street
END;

Используем его при описании других:

CREATE TYPE Studia AS
(
    sname VARCHAR(50),
    addr Addr
);
 
CREATE TYPE Actor AS
(
    inn INT,
    fio VARCHAR(50),
    addr Addr
);

Создаём таблицы со ссылками:

CREATE TABLE Tact OF Actor
(
    PRIMARY KEY (inn),
    REF IS Ida system generated
);
 
CREATE TABLE TSt
(
    REF IS Ids system generated
)

Создаём тип со ссылками:

CREATE TYPE Film AS
(
    title VARCHAR(80),
    YEAR unt,
    len INT,
    TYPE CHAR(2),
    st REF(Studia) [SCOPE TSt] -- SCOPE показывает, что это на конкретную талицу
);

Ещё таблицы:

CREATE TABLE FA
(
    act REF(Actor) SCOPE TAct,
    film REF(Film) SCOPE TF
);
 
CREATE TABLE TF OF Film
(
    REF IS Idf system generated
);

Запросы к UDT

-- один ко многим
SELECT YEAR, len st->sname, st->addr.city, st->addr.fullad()
FROM TF
WHERE title = 'The Matrix'
 
-- многие ко многим (обращение к одной таблице, которая её реализует)
SELECT film->title, film->YEAR, film->st->name
FROM FA
WHERE act->fio='Иванов'
 
-- разыменование ссылок
SELECT deref(act)
FROM FA
WHERE film->title='The Matrix' -- выведет всех актёров этого фильма

Методы

Создаются системой автоматически.

Методы обозреватели

Они же getter. Совпадают с названием поля, не имеют параметров. Нужны для получения значений полей.

SELECT f.title(), f.len()
FROM TF
WHERE f.type='BW'
Методы модификаторы

Они же setter. Для изменения значения полей.

Методы генераторы

Они же конструкторы.

DECLARE newA Addr;
DECLARE newS Stud;
 
SET newA = Addr();   -- вызов конструктора
newA.city('Москва');
newA.street('Ленина, 2');
 
SET newS = Studia(); -- вызов конструктора
newS.sname('Мосфильм');
news.addr(newA);
 
INSERT INTO TSt VALUES(newS);

Сравнение типов

CREATE ORDERING FOR Addr
<EQUALS ONLY | ORDER FULL | RELATIVE WITH f> BY STATE
-- f - это функция, выполняющая сравнение двух параметров
-- она не стандартная, её надо создать
CREATE FUNCTION f(x1 Addr, x2 Addr) RETURNS INT
    IF x1.city > x2.city TNEN RETURN 1;
    ELSE IF x1.city < x2.city TNEN RETURN -1;
    ELSE IF x1.street > x2.street TNEN RETURN 1;
    ELSE IF x1.street < x2.street TNEN RETURN -1;
    ELSE RETURN 0;
    END IF;

Производные типы

CREATE TYPE имя UNDER базовый тип AS
(
    поле тип,
    ...
    [[NOT] instantiable] -- можно ли на его основе создать ещё тип
    [NOT] final          -- можно ли его переопределять
    <REF IS system generated | REF USING тип | REF USING (атрибут)>
);
 
[overriding]
[<instance | static | constructor>]
method название(параметры) RETURNS тип
[SELF AS <RESULT | locator>]
[parameter STYLE <SQL | Java | ...>]
[[NOT] deteministic]
[no SQL | contains SQL | ...]
[RETURN <NULL ON NULL INPUT | called ON NULL input>]

OQL

Object Query Language.

class Film(extent EF)
{
    attribute string title;
    attribute string year;
    attribute string len;
    attribute string type;
 
    relationship Stud st inverse Stud::fl;
    relationship set <Actor> acts inverse Actor::films;
 
    set <Stud> StofFl();
 
    -- метод
    int firstFilm();
}
 
class Actor(extent EA)
{
    attribute string fio;
    attribute int inn;
 
    relationship set <Film> films inverse ... ;
 
    -- атрибут-структура
    attribute Struct{string city, string street} addr;
}

Запросы на OQL

Связь М-М, все актеры, которые снимались в фильме:

SELECT a.fio
FROM EF f, f.acts a
WHERE f.title="Иванов" AND f.year < 1950
SELECT a.fio, a.addr
FROM EA a
WHERE for all f in a.films : f.st.sname="Мосфильм"

Коллекция - элемент, множество связанных объектов и вложенный подзапрос. Пример с группировкой:

4 SELECT st, y , sumlen: sum(SELECT P.f.len FROM PARTITION P)
1 FROM ES st, st.fms F
2 WHERE f.year>2000
3 GROUP BY st:st.name, y:f.year

PARTITION - результат группировки, коллекция всех объектов, которые попали в отдельную группу. Здесь st и f. WHERE работает до группировки. HAVING накладывает ограничения на группы. Если он есть, то выполняется 4-ым шагом ( до SELECT'а).

HAVING MIN(SELECT p.f.len FROM PARTITION P)>60.

Сортировка:

ORDER BY ASC st, year

Агрегаты

COUNT() - Для любых
MIN() - для подлежащих сортировке
SUM() - только для числовых
AVG() - только для числовых
MAX() - для подлежащих сортировке

Можно применять к коллекции:

COUNT(EF) - кол-во элементов в экстенте.


Поддерживаются кванторы:

SELECT a
FROM EA a
WHERE FOR ALL F IN a.films:F.st.name="ЛенФильм" AND f.year=2016
FOR ALL IN - квантор всеобщности
SELECT a
FROM EA a
WHERE EXISTS f1 IN a.films:f.yaer<2000

Запрос на единственность:

SELECT s
FROM ES s
WHERE COUNT(s.fms)=1
Те студии, которые сняли только один фильм.

По умолчанию возвращается мультимножество структур.

SELECT a.fio, f.year
Bag<struct{struct{f, i, o}, integer year}>

Если хочется SET:

SELECT DISTINCT

Если хочется LIST:

ORDER BY

Можно и свою коллекцию:

SELECT struct(fam:a.fio.f, yearMade:f.year)
Если поле одно, то структура не формируется.


(SELECT a
FROM EA a, a.films f
WHERE f.stud.name="МосФильм")
EXCEPT
(SELECT a
FROM EA a, EF f
WHERE f.stud.name="Экран")
 
Аналогично можно с UNION и INTERSECT

Datalog

Язык логических запросов Database Logic. Основан на использовании предикатов.

Предикат - функция, принимающая аргументы, возвращает true или false. Аргументы могут быть константы или переменные.

Атом - предикат, с подставленными в него аргументами. Атомы бывают:

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

Количество и последовательность аргументом должны совпадать абсолютно.

// реляционный предикат
Actor("123", "Иванов", "высшее") // если есть такой актёр, то вернёт true, иначе false

Для создания запроса используются правила "если ... то":

// в общем виде
заголовок <-- набор >= подцель AND подцель AND ...
 
// конкретно
ЧёрноБелыеФильмы(н,г,ст) <-- Фильм (н, г, д, т, ст) AND т = "ч/б"

Есть анонимные переменные - не используются для выполнения сравнения и получения результата. Ставятся на место обычных переменных, заменяя их знаком подчёркивания: "_".

Правила

Вычисление правил:

  1. определение кортежей из реляционный подцелей без отрицания;
  2. получение согласованного набора кортежей;
  3. для согласованного набора проверяются все подцели;
  4. для истинных подцелей формируем результат.

Согласованный набор - это когда одним и тем же переменным соответствуют одни и те же значения (результат выполнения естественного соединения):

АВФ(фио,н) <-- Актёр(i, фио, _) AND ФА(н, 1979, i) AND i > 1000

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

Реляционные операции

Для результатов можно использовать операции реляционной алгебры:

  • объединение;
  • разность;
  • проекция;
  • селекция;
  • декартово произведение;
  • естественное соединение.
// декартово произведение
S(a,b,x,y) <-- X(a,b) AND Y(x,y)
 
// естественное соединение
S(a,z,x) <-- X(a,z) AND (z, x)

Примеры:

// фильмы, снятые на Мосфильме
ФильмМосфильм(н,г) <-- Фильм(н, г, _, _, ст) AND ст = "Мосфильм"
 
// актёры с МосФильма, работавщие в 1990
АктМосфильм(фио) <-- Актёр(i, фио, _) AND ФА(н, 1990, i) AND Фильм(н, 1990, _, _, "Мосфильм")
 
// актёры, никогда не работавшие на МосФильме
АктНикогдаМосфильм(фио) <-- Актёр(i, фио, _) AND NOT ФА(н, г, i) AND Фильм(н, г, _, _, "Мосфильм")
 
// студия, снявшая более одного фильма
СтБольшеОдногоФильма(ст) <-- Фильм(н, г, _, _, ст) AND Фильм(н2, г2, _, _, ст) AND (н2 != н)

ДНФ

Если в запросе сочетаются И / ИЛИ / вложенные подзапросы, то используется дизъюнктивно-нормальная форма. Конъюнкт - это литералы (атом или атом с отрицанием), соединённые через И. Конъюнкты объединяются в правила.

Рекурсия

Надо, например, построить маршрут по городам:

Road(от, до, ц, тип)
// база рекурсии
Path(от, до) <-- Road(от, до, _, _)
// индукция рекурсии
Path(от, до) <-- Road(от, до, _, _)
Path(от, до) <-- Road(от, до1, _, _) AND Path(до1, до)

Рекурсия выполняется, пока есть изменения.

Виды рекурсии:

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

Изолированность рекурсии - чтобы её определить, строится граф рекурсии.

Работа с СУБД

Виды взаимодействия с СУБД-сервером

Работа на стороне СУБД-сервера

Несколько видов:

  • система правил, триггеры, ограничения (DML, DDL);
    • SQL/PSM;
    • подключение внешних модулей (например, CLR.NET);
  • внешние вызовы, (call-out):
    • вызов внешней программы:
      • в синхронном режиме - управление возвращается в вызвавшую программу;
      • в асинхронном режиме - после вызова вызвавщая продолжает работать, не ждёт;
      • из библиотеки.
    • вызов внешних объектов (COM, ActiveX):
      • создаётся объект-посредник;
      • обращение через него к функциям и методам нужного;
  • обращение к внешним БД:
    • через связные серверы;
    • через проекции.

Работа на стороне клиента

Тоже несколько вариантов:

  • CLI (ODBC/JDBC);
  • встраиваемый SQL;
  • обращение к объектному представлению (call-in);
  • обращение к управляемому объекту (Server Managment Objects).

Варианты клиент-серверных приложений

Трёхуровневая архитектура, "тонкий клиент":

  1. СУБД;
  2. прослойка в виде сервера приложений;
  3. клиент.

Импорт и экспорт данных

Разовая выгрузка из СУБД либо наоборот - загрузка данных в СУБД. Используется, например, XML.

Репликации

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

Приципы взаимодействия клиента и сервера СУБД

Иерархия СУБД:

  1. среда - хранение данных и выполнение процессов (сервера и клиента);
  2. кластер;
  3. каталог - коллекция схем;
  4. схема - коллекция объектов.

Для работы с БД устанавливается соединение с ней. Соединений может быть сколько угодно. Но один момент времени может быть активно только одно соединение.

Клиент и сервер работают в сеансе. Сеанс - последовательность команд.

Приложения БД

Существует несколько видов:

  1. встроенный SQL - статический, базовый язык, внутрь него помещаются команды на SQL-языке. Далее функции и вызовы функций через компилятор. Подключается библиотека, связанная с конкретной СУБД;
  2. динамический SQL - в приложении клиента создаётся запрос, выполняются следующие шаги:
    1. prepare - подготовка;
    2. execute - выполнение.

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

CLR.NET

Можно создавать библиотеки (сборки) и подключать:

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

Архитектура:

  1. среда разработки (Visual Studio);
  2. библиотека классов .NET;
  3. CLR;
  4. сервер.

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

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

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

  • сборка мусора;
  • поддержка системных данных;
  • обеспечение безопасности;
  • обработка ошибок.

Пример чего-то:

class SomeClass
{
 public:
    // инициализация переменных
    init() {S = 0;}
 
    // sum нигде не объявлен, но мы догадываемся, что это сумма
    SQLInt32 terminate() {return sum;}
 
    acomulate(SQLInt32 a) {sum = sum + a;}
 
    // слияние (каких-то) групп
    merge() {}
 
 private:
    Int32 S;
}

Интеграция информации

Несколько вариантов:

  • федеративные БД. Плюсы: соединяем каждого с каждым, минусы: слишком много интерфейсов;
  • хранилища данных. В них заливается информация из источников данных (с необходимыми преобразованиями). Изменение информации не предусматривается, только просмотр. Слив информации может осуществляться: раз в сутки, пакетами (инкриментами) или онлайн-транзакциями (мгновенно). Промежуточные компоненты хранилища:
    • извлечение данных. Шаблоны запросов с наборами функций для обращения к источникам данных;
    • слияние и преобразование;
  • медиаторы (виртуальные хранилища данных). Отличие от просто хранилищ - не существует физически, просто транслирует запросы к источникам данных. Обеспечивают представление данных в виде единой обобщённой структуры. Функции:
    • оболочка - аналогично компонентам извлечения у хранилищ данных;
    • фильтрация данных;
    • агрегация;
    • произ.чтототам. Не удалось разобрать из-за хардкорной экономии мела.

Хранилища данных

Являются:

  • предметно-ориентированными. Используются в системах поддержки принятия решений. Ориентированы на предметную область;
  • интегрированными;
  • неизменными. Необходимо сохранять переодичность и изменчивость данных (в какой момент на каком счету у какого клиенты было сколько денег). Потому новые данные не изменяют старые, а дополняют;
  • имеют структуру для хранения хронологических данных.

Есть OLTP и OLAP системы.

Пользовательские интерфейсы:

  • заранее предопределённые запросы;
  • система поддержки принятия решений;
  • программный датамайнинг (автоматический, без человека).

Хранилища данных предназначены для решения аналитических задач.

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

Есть комбинированные разновидности:

  • независимые витрины данных;
  • двухуровневые хранилища данных;
  • трёхуровневые хранилища данных.

Архитектура хранилищ данных

Архитектура может быть представлена следующей схемой:

ETL:

  • extraction - извлечение;
  • tranzaction - преобразование. Есть такое понятие - грязные данные. Это данные с ошибками, опечатками и так далее. Производится операция очистки грязных данных. Кроме очистки также могут осуществляться объединение, дублирование и другие операции;
  • loading - загрузка.

OLAP системы

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

Пример запроса:

SELECT MONTH, SUM(price)
FROM Sales
WHERE city ='Москва'
GROUP BY MONTH

Зачем он нужен, например:

  • оценка работы фирмы;
  • прогноз продаж;
  • выявление причин.

Что есть в OLAP системах:

  1. факты и таблицы фактических значений - сведения о событиях, транзакциях, действиях;
  2. измерения (товары, магазины).

Ещё есть кубы данных. Бывают:

  • фактические - хранят фактические данные;
  • формальные - кроме фактических данных хранят ещё и агрегированные данные.

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

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

А ещё есть ROLAP - реляционные OLAP, хранятся в обычных реляционных СУБД. Используются схемы "звезда" или "снежинка".

Схема "звезда"

Используются таблицы измерений.

Типовой запрос:

SELECT *
FROM ТФ3 |><| TP1 |><| ... |><| ... TPN
WHERE условие
GROUP BY группирующий атрибут

Операции:

  • рассечение - выделение из куба некоторого пространства для анализа его содержимого. Рассечение задаётся оператором GROUP BY и группирующими атрибутами;
  • расслоение - выбор слоя для проведения анализа внутри него. Задаётся оператором WHERE;
  • уточнение - уменьшение шага разбиения;
  • округление - увеличение шага разбиения.

Плюсы:

  • быстрее выполняются запросы.

Минусы:

  • дублирование данных.

Схема "снежинка"

Те же таблицы измерений.

Плюсы:

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

Минусы:

  • дольше выполняются запросы.

Сетка представлений

Это правила разбиения некоторого измерения на части. Например, можно делить по дням, а можно по месяцам.

Датамайнинг

Автоматическое извлечение данных:

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

Задачи датамайнинга:

  • классификация;
  • регрессия;
  • кластеризация;
  • ассоциативные правила - наборы объектов;
  • сиквенциальный анализ - последовательности.

Классификация

I=ij - множество объектов.

ij=x1,x2...xm,y, где y - характеристика.

Задачи классификации

  • создать правило 1Rule если ... то. Определять класс объекта по одной характеристике;
  • поиск ассоциативных правил.

Кластеризация

I=ij - множество объектов.

ij=x1,x2...xm.

Нужно выделить объекты по кластерам. Два подхода:

  • неиерархический;
  • иерархический.

SQL Injection

Если вы вводите пользовательский ввод через веб-страницу и вставляете его в базу данных SQL, есть вероятность, что вы оставите себя широко открытыми для проблемы безопасности, известной как SQL Injection. В этой главе вы узнаете, как помочь предотвратить это, и помогите вам защитить свои сценарии и заявления SQL в сценариях на стороне сервера, например, PERL Script.
Инъекция обычно возникает, когда вы запрашиваете у пользователя ввод данных, например их имя, а вместо имени они дают вам инструкцию SQL, которую вы бессознательно выполняете в своей базе данных. Никогда не доверяйте предоставленным пользователем данным, обрабатывайте эти данные только после проверки; Как правило, это выполняется путем сопоставления шаблонов.
В приведенном ниже примере имя ограничено буквенно-цифровыми символами плюс подчеркивание и длиной от 8 до 20 символов (при необходимости измените эти правила).

If (preg_match ("/ ^ \ w {8,20} $ /", $ _GET ['username'], $ matches)) {
   $ Result = mysql_query ("SELECT * FROM CUSTOMERS
      WHERE name = $ matches [0] ");
} Else {
   Echo "имя пользователя не принимается";
}
Чтобы продемонстрировать проблему, рассмотрите этот отрывок -

// предполагаемый ввод
$ Name = "Qadir", DELETE FROM CUSTOMERS; ";
Mysql_query ("SELECT * FROM CUSTOMSRS WHERE name = '{$ name}'");
Предполагается, что вызов функции должен получить запись из таблицы CUSTOMERS, где столбец имен соответствует имени, указанному пользователем. В обычных условиях имя $ name будет содержать только буквенно-цифровые символы и, возможно, пробелы, такие как строка ilia. Но здесь, добавляя совершенно новый запрос к $ name, вызов в базу данных превращается в катастрофу; Запрошенный DELETE-запрос удаляет все записи из таблицы CUSTOMERS.
К счастью, если вы используете MySQL, функция mysql_query () не допускает стекирование запросов или выполнение нескольких SQL-запросов в одном вызове функции. Если вы попытаетесь выполнить стек запросов, вызов завершится с ошибкой.
Тем не менее, другие расширения базы данных PHP, такие как SQLite и PostgreSQL, успешно выполняют сложенные запросы, выполняя все запросы в одной строке и создавая серьезную проблему безопасности.
Предотвращение внедрения SQL
Вы можете легко управлять всеми escape-символами на языках сценариев, таких как PERL и PHP. Расширение MySQL для PHP предоставляет функцию mysql_real_escape_string (), чтобы избежать ввода символов, которые являются особыми для MySQL.
If (get_magic_quotes_gpc ()) {
   $ Name = stripslashes ($ name);
}
$ Name = mysql_real_escape_string ($ name);
Mysql_query ("SELECT * FROM CUSTOMERS WHERE name = '{$ name}'");
LIKE Quandary
Чтобы устранить затруднительное положение LIKE, пользовательский механизм экранирования должен преобразовывать пользовательские символы «%» и «_» в литералы. Используйте addcslashes (), функцию, которая позволяет указать диапазон символов для выхода.
$ Sub = addcslashes (mysql_real_escape_string ("% str"), "% _");
// $ sub == \% str \ _
Mysql_query ("SELECT * FROM messages
   WHERE subject LIKE '{$ sub}%' ");