Связи между таблицами MS SQL: обзор основных отношений и типов соединения
Связи между таблицами в базе данных — основа хранения данных в СУБД.
Связи в базе данных MS SQL позволяют нормализировать БД, настроить отношение между данными таблиц и сделать эффективные выборки данных. Главное — понять, как настраивать и использовать связи между таблицами MS SQL. Это необходимое условие для работы с любой БД.
Ниже рассмотрим основные концепции связей: Foreign Key и JOINs.
Foreign Key
Создание связей MS SQL между таблицами происходит через внешний ключ (foreign key). Данный ключ связывает поле (значение) исходной таблицы с Primary Key внешней таблицы. Через внешний ключ можно не только производить выборку данных, но и контролировать удаление данных в главной таблице:
- NO ACTION — не производит никаких действий;
- SET NULL — зависимые данные установятся в NULL при удалении записи из главной таблицы (primary table);
- CASCADE — удаляются зависимые данные. Опасная операция. В реальной жизни используется редко.
Подробнее об этом — на курсе «Аналитик данных». За 12 месяцев разберетесь в основных данных, научитесь делать таблицы, соединять и обрабатывать несколько сразу, использовать оконные функции. Станете настоящим экспертом в аналитике!
ALTER TABLE ADD CONSTRAINT FK__ FOREIGN KEY () REFERENCES () ON UPDATE ON UPDATE
Типы соединения JOINs
Когда отношения между таблицами установлены, можно делать выборки данных из этих связанных таблиц.
Существует несколько механизмов соединения двух таблиц в запросе: это основные типы JOINs для MS SQL SERVER. И они практически всегда совпадают для всех реляционных СУБД.
Рассмотрим основные типы JOINs. Будем считать, что у нас есть левая и правая таблицы, которые соединяем через JOIN. *Левая и правая относительно слова JOIN.
Есть несколько механизмов соединения двух таблиц в запросе. Например, Oracle содержит Natural Join, который соединяет колонки с одинаковыми именами в таблицах. Используется крайне редко.
Обо всех способах соединения — на курсе «Аналитик данных». Уделяйте учебе всего два часа в день — и научитесь обновлять, удалять и добавлять записи, использовать разные соединения, чтобы решать реальные задачи.
LEFT (OUTER) JOIN
Всегда выводите данные по левой таблице. Если правая таблица не содержит связанных данных, то выводите NULL для этих значений.
select * from A left join B on A.ID = B.A_ID
A1 | B1 |
A2 | B2 |
A3 | NULL |
RIGHT (OUTER) JOIN
Обратное от Left Join. Используют редко. Всегда можно переписать на Left Join — тогда запрос легче читать. В частных случаях бывает, что Right Join дает лучшую статистику выполнения и оптимизирует запрос.
A left join B = B right join A:
select * from B right join A on A.ID = B.A_ID
A1 | B1 |
A2 | B2 |
A3 | NULL |
Аналитик данных: новая работа через 5 месяцев
Получится, даже если у вас нет опыта в IT
INNER JOIN
Выводите значения для строки из левой таблицы, только если есть связанные данные в правой таблице. Часто используют, чтобы отфильтровать данные левой таблицы и выводить только те записи, по которым есть значения в правой.
На курсе «Аналитик данных» вы не только изучите теорию, но и выполните практические задания. Если возникнут сложности — помогут кураторы с реальным опытом в аналитике. Благодаря их помощи подготовите интересные проекты для портфолио.
select * from A inner join B on A.ID = B.A_ID -- аналог запроса на left join select * from A left join B on A.ID = B.A_ID where B.ID is not null
A1 | B1 |
A2 | B2 |
CROSS JOIN
Это пересечение всех строк из левой таблицы со всеми строками правой таблицы.
select * from A cross join B
A1 | B1 |
A1 | B2 |
A2 | B1 |
A2 | B2 |
FULL JOIN
Представьте, что это смешанное сочетание Left Join и Right Join. Вначале выводятся значения левой таблицы, а правой заполняются NULL, затем — наоборот.
Запрос выводит пересечение значений. Если нет пересечений, то выводит значения по A и B c NULL:
select * from A full join B on A.ID = B.A_ID
A1 | B1 |
A2 | B2 |
A3 | NULL |
NULL | B4 |
Типы отношений между таблицами
Используем Foreign Key и JOINs и создадим реальный пример бизнес-задачи. А еще рассмотрим настройку связей между таблицами.
Введем сущности Clinics, Doctors, Patients и Appointments.
- Доктор работает или не работает только в одной клинике.
- У доктора может быть вышестоящий менеджер.
- Пациент может обращаться в разные клиники к разным докторам.
Создадим таблицы БД, пока без связей с сурогатными Primary Keys:
CREATE TABLE dbo.Clinics ( ID int, Name varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, CONSTRAINT Clinics_PK PRIMARY KEY (ID) ); CREATE TABLE dbo.Patients ( ID int, Name varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, CONSTRAINT Patients_PK PRIMARY KEY (ID) ); CREATE TABLE dbo.Doctors ( ID int, Name varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, Clinic_ID int NULL, Manager_ID int NULL, CONSTRAINT Doctors_PK PRIMARY KEY (ID) ); CREATE TABLE dbo.Appointments ( ID int, [Date] datetime2(0) NOT NULL, Patient_ID int NOT NULL, Doctor_ID int NOT NULL, CONSTRAINT Appointments_PK PRIMARY KEY (ID) );
insert into dbo.Clinics values (1, 'First Clinic'), (2, 'Second Clinic') insert into dbo.Doctors values (10, 'Doctor', 1, NULL), (11, 'Assistent Doctor', 1, 10), (12, 'Another Doctor', 2, NULL), (13, 'Retired Doctor', NULL, NULL), (15, 'Assist 2 Doctor', 1, 11) insert into dbo.Patients values (100, 'First Patient'), (101, 'Second Patient') insert into dbo.Appointments values (1000, GETDATE(), 100, 10), (1001, GETDATE(), 101, 10), (1002, GETDATE(), 100, 12)
Отношения «один к одному»
Используйте данную связь, когда значению из таблицы соответствует только одна запись из внешней таблицы. «Доктор может работать только в одной клинике». Можем предположить, что связь между Clinics и Doctors будет «один к одному»:
ALTER TABLE dbo.Doctors ADD CONSTRAINT FK_Doctors_ClinicID FOREIGN KEY (Clinic_ID) REFERENCES dbo.Clinics(ID);
select d.Name, c.Name from dbo.Doctors d left join dbo.Clinics c on c.ID = d.Clinic_ID;
Отношение «один ко многим»
Одной записи из таблицы соответствуют несколько записей из внешней. Данный тип связи очень распространен при построении схемы БД.
«Хотя доктор может принадлежать только одной клинике, клиники, в свою очередь, содержат штат докторов». Это отношение «один ко многим»:
select c.Name, d.Name from dbo.Clinics c inner join dbo.Doctors d on d.Clinic_ID = c.ID;
CLINIC | DOCTOR |
First Clinic | Doctor |
First Clinic | Assistent Doctor |
First Clinic | Assist 2 Doctor |
Second Clinic | Another Doctor |
Отношение «многие ко многим»
Организуется через промежуточную таблицу, в которой есть внешние ключи на разные таблицы.
О временных таблицах вы подробнее узнаете на курсе «Аналитик данных». Научитесь работать с временными таблицами, использовать оконные функции и соединять таблицы в SQL, применять их для сложных запросов.
В таблице Appointments есть связь на таблицы Doctors и Patients. Таким образом, организована связь между пациентами и докторами: пациент может посещать нескольких докторов, а доктора — принимать нескольких пациентов.
ALTER TABLE dbo.Appointments ADD CONSTRAINT FK_Appointments_DoctorID FOREIGN KEY (Doctor_ID) REFERENCES dbo.Doctors(ID); ALTER TABLE dbo.Appointments ADD CONSTRAINT FK_Appointments_PatientID FOREIGN KEY (Patient_ID) REFERENCES dbo.Patients(ID);
Это довольно распространенный вопрос на собеседовании для SQL-разработчика. Если программист может на примере объяснить, как строится связь «многие ко многим», — это уже хороший показатель для интервьюера.
Как получить список посещений пользователя с указанием клиники и докторов:
select p.Name, a.[Date], d.Name, c.Name from dbo.Patients p inner join dbo.Appointments a on a.Patient_ID = p.ID inner join dbo.Doctors d on d.ID = a.Doctor_ID inner join dbo.Clinics c on c.ID = d.Clinic_ID where p.ID = 100;
PATIENT | DATE | DOCTOR | CLINIC |
First Patient | 2022-08-06 07:41:45.000 | Doctor | First Clinic |
First Patient | 2022-08-06 07:41:45.000 | Another Doctor | Second Clinic |
Связь с самим собой
Такой тип связи называется рекурсивным, или иерархическим: связывание строки со строкой из той же таблицы. Полезно при отображении древовидной структуры.
Таблица Doctors содержит колонку Manager, в которой указано, кто из докторов является менеджером текущего доктора. Здесь связь на строку из той же таблицы докторов.
Как рекурсивно получить список докторов, у которых определенный доктор является вышестоящим менеджером:
with cte as ( select d.ID, d.Name from dbo.Doctors d where d.ID = 10 union all select d2.ID, d2.Name from dbo.Doctors d2 inner join cte on cte.ID = d2.Manager_ID ) select * from cte
Памятка/шпаргалка по SQL
Изучение настоящей шпаргалки не сделает вас мастером SQL, но позволит получить общее представление об этом языке программирования и возможностях, которые он предоставляет. Рассматриваемые в шпаргалке возможности являются общими для всех или большинства диалектов SQL.
Для более полного погружения в SQL рекомендую изучить эти руководства по MySQL и PostgreSQL от Метанита. Они хороши тем, что просты в изучении и позволяют быстро начать работу с названными СУБД.
При обнаружении ошибок, опечаток и неточностей, не стесняйтесь писать мне в личку.
Что такое SQL?
SQL — это язык структурированных запросов (Structured Query Language), позволяющий хранить, манипулировать и извлекать данные из реляционных баз данных (далее — РБД, БД).
Почему SQL?
- получать доступ к данным в системах управления РБД
- описывать данные (их структуру)
- определять данные в БД и управлять ими
- взаимодействовать с другими языками через модули SQL, библиотеки и предваритальные компиляторы
- создавать и удалять БД и таблицы
- создавать представления, хранимые процедуры (stored procedures) и функции в БД
- устанавливать разрешения на доступ к таблицам, процедурам и представлениям
Процесс SQL
При выполнении любой SQL-команды в любой RDBMS (Relational Database Management System — система управления РБД, СУБД, например, PostgreSQL, MySQL, MSSQL, SQLite и др.) система определяет наилучший способ выполнения запроса, а движок SQL определяет способ интерпретации задачи.
В данном процессе участвует несколького компонентов:
- диспетчер запросов (Query Dispatcher)
- движок оптимизации (Optimization Engines)
- классический движок запросов (Classic Query Engine)
- движок запросов SQL (SQL Query Engine) и т.д.
Классический движок обрабатывает все не-SQL-запросы, а движок SQL-запросов не обрабатывает логические файлы.
Команды SQL
Стандартными командами для взаимодействия с РБД являются CREATE , SELECT , INSERT , UPDATE , DELETE и DROP . Эти команды могут быть классифицированы следующим образом:
- DDL — язык определения данных (Data Definition Language)
N | Команда | Описание |
---|---|---|
1 | CREATE | Создает новую таблицу, представление таблицы или другой объект в БД |
2 | ALTER | Модифицирует существующий в БД объект, такой как таблица |
3 | DROP | Удаляет существующую таблицу, представление таблицы или другой объект в БД |
- DML — язык изменения данных (Data Manipulation Language)
N | Команда | Описание |
---|---|---|
1 | SELECT | Извлекает записи из одной или нескольких таблиц |
2 | INSERT | Создает записи |
3 | UPDATE | Модифицирует записи |
4 | DELETE | Удаляет записи |
- DCL — язык управления данными (Data Control Language)
N | Команда | Описание |
---|---|---|
1 | GRANT | Наделяет пользователя правами |
1 | REVOKE | Отменяет права пользователя |
Обратите внимание: использование верхнего регистра в названиях команд SQL — это всего лишь соглашение, большинство СУБД нечувствительны к регистру. Тем не менее, форма записи инструкций, когда названия команд пишутся большими буквами, а названия таблиц, колонок и др. — маленькими, позволяет быстро определять назначение производимой с данными операции.
Что такое таблица?
Данные в СУБД хранятся в объектах БД, называемых таблицами (tables). Таблица, как правило, представляет собой коллекцию связанных между собой данных и состоит из определенного количества колонок и строк.
Таблица — это самая распространенная и простая форма хранения данных в РБД. Вот пример таблицы с пользователями (users):
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 25 | Moscow | active |
2 | Vika | 26 | Ekaterinburg | inactive |
3 | Elena | 27 | Ekaterinburg | active |
4 | Oleg | 28 | Moscow | inactive |
Что такое поле?
Каждая таблица состоит из небольших частей — полей (fields). Полями в таблице users являются userId, userName, age, city и status. Поле — это колонка таблицы, предназначенная для хранения определенной информации о каждой записи в таблице.
Обратите внимание: вместо userId и userName можно было бы использовать id и name , соответственно. Но при работе с несколькими объектами, содержащими свойство id , бывает сложно понять, какому объекту принадлежит идентификатор, особенно, если вы, как и я, часто прибегаете к деструктуризации. Что касается слова name , то оно часто оказывается зарезервизованным, т.е. уже используется в среде, в которой выполняется код, поэтому я стараюсь его не использовать.
Что такое запись или строка?
Запись или строка (record/row) — это любое единичное вхождение (entry), существующее в таблице. В таблице users 5 записей. Проще говоря, запись — это горизонтальное вхождение в таблице.
Что такое колонка?
Колонка (column) — это вертикальное вхождение в таблице, содержащее всю информацию, связанную с определенным полем. В таблице users одной из колонок является city , которая содержит названия городов, в которых проживают пользователи.
Что такое нулевое значение?
Нулевое значение (NULL) — это значение поля, которое является пустым, т.е. нулевое значение — это значение поля, не имеющего значения. Важно понимать, что нулевое значение отличается от значения 0 и от значения поля, содержащего пробелы ( `). Поле с нулевым значением — это такое поля, которое осталось пустым при создании записи. Также, следует учитывать, что в некоторых СУБД пустая строка ( » ) — это NULL`, а в некоторых — это разные значения.
Ограничения
Ограничения (constraints) — это правила, применяемые к данным. Они используются для ограничения данных, которые могут быть записаны в таблицу. Это обеспечивает точность и достоверность данных в БД.
Ограничения могут устанавливаться как на уровне колонки, так и на уровне таблицы.
Среди наиболее распространенных ограничений можно назвать следующие:
- NOT NULL — колонка не может иметь нулевое значение
- DEFAULT — значение колонки по умолчанию
- UNIQUE — все значения колонки должны быть уникальными
- PRIMARY KEY — первичный или основной ключ, уникальный идентификатор записи в текущей таблице
- FOREIGN KEY — внешний ключ, уникальный идентификатор записи в другой таблице (таблице, связанной с текущей)
- CHECK — все значения в колонке должны удовлетворять определенному условию
- INDEX — быстрая запись и извлечение данных
Любое ограничение может быть удалено с помощью команды ALTER TABLE и DROP CONSTRAINT + название ограничения. Некоторые реализации предоставляют сокращения для удаления ограничений и возможность отключать ограничения вместо их удаления.
Целостность данных
В каждой СУБД существуют следующие категории целостности данных:
- целостность объекта (Entity Integrity) — в таблице не должно быть дубликатов (двух и более строк с одинаковыми значениями)
- целостность домена (Domain Integrity) — фильтрация значений по типу, формату или диапазону
- целостность ссылок (Referential integrity) — строки, используемые другими записями (строки, на которые в других записях имеются ссылки), не могут быть удалены
- целостность, определенная пользователем (User-Defined Integrity) — дополнительные правила
Нормализация БД
Нормализация — это процесс эффективной организации данных в БД. Существует две главных причины, обуславливающих необходимость нормализации:
- предотвращение записи в БД лишних данных, например, хранения одинаковых данных в разных таблицах
- обеспечение «оправданной» связи между данными
Нормализация предполагает соблюдение нескольких форм. Форма — это формат структурирования БД. Существует три главных формы: первая, вторая и, соответственно, третья. Я не буду вдаваться в подробности об этих формах, при желании, вы без труда найдете необходимую информацию.
Синтаксис SQL
Синтаксис — это уникальный набор правил и рекомендаций. Все инструкции SQL должны начинаться с ключевого слова, такого как SELECT , INSERT , UPDATE , DELETE , ALTER , DROP , CREATE , USE , SHOW и т.п. и заканчиваться точкой с запятой ( ; ) (точка с запятой не входит в синтаксис SQL , но ее наличия, как правило, требуют консольные клиенты СУБД для обозначения окончания ввода команды). SQL не чувствителен к регистру, т.е. SELECT , select и SeLeCt являются идентичными инструкицями. Исключением из этого правила является MySQL , где учитывается регистр в названии таблицы.
Примеры синтаксиса
-- выборка SELECT col1, col2, . colN FROM tableName; SELECT DISTINCT col1, col2, . colN FROM tableName; SELECT col1, col2, . colN FROM tableName WHERE condition; SELECT col1, col2, . colN FROM tableName WHERE condition1 AND|OR condition2; SELECT col2, col2, . colN FROM tableName WHERE colName IN (val1, val2, . valN); SELECT col1, col2, . colN FROM tableName WHERE colName BETWEEN val1 AND val2; SELECT col1, col2, . colN FROM tableName WHERE colName LIKE pattern; SELECT col1, col2, . colN FROM tableName WHERE condition ORDER BY colName [ASC|DESC]; SELECT SUM(colName) FROM tableName WHERE condition GROUP BY colName; SELECT COUNT(colName) FROM tableName WHERE condition; SELECT SUM(colName) FROM tableName WHERE condition GROUP BY colName HAVING (function condition); -- создание таблицы CREATE TABLE tableName ( col1 datatype, col2 datatype, . colN datatype, PRIMARY KEY (одна или более колонка) ); -- удаление таблицы DROP TABLE tableName; -- создание индекса CREATE UNIQUE INDEX indexName ON tableName (col1, col2, . colN); -- удаление индекса ALTER TABLE tableName DROP INDEX indexName; -- получение описания структуры таблицы DESC tableName; -- очистка таблицы TRUNCATE TABLE tableName; -- добавление/удаление/модификация колонок ALTER TABLE tableName ADD|DROP|MODIFY colName [datatype]; -- переименование таблицы ALTER TABLE tableName RENAME TO newTableName; -- вставка значений INSERT INTO tableName (col1, col2, . colN) VALUES (val1, val2, . valN) -- обновление записей UPDATE tableName SET col1 = val1, col2 = val2, . colN = valN [WHERE condition]; -- удаление записей DELETE FROM tableName WHERE condition; -- создание БД CREATE DATABASE [IF NOT EXISTS] dbName; -- удаление БД DROP DATABASE [IF EXISTS] dbName; -- выбор БД USE dbName; -- завершения транзакции COMMIT; -- отмена изменений ROLLBACK;
Типы данных
Каждая колонка, переменная и выражение в SQL имеют определенный тип данных (data type). Основные категории типов данных:
Точные числовые
Тип данных | От | До |
---|---|---|
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 |
Приблизительные числовые
Тип данных | От | До |
---|---|---|
float | -1.79E + 308 | 1.79E + 308 |
real | -3.40E + 38 | 3.40E + 38 |
Дата и время
Тип данных | От | До |
---|---|---|
datetime | Jan 1, 1753 | Dec 31, 9999 |
smalldatetime | Jan 1, 1900 | Jun 6, 2079 |
date | Дата сохраняется в виде June 30, 1991 | |
time | Время сохраняется в виде 12:30 P.M. |
Строковые символьные
N | Тип данных | Описание |
---|---|---|
1 | char | Строка длиной до 8,000 символов (не-юникод символы, фиксированной длины) |
2 | varchar | Строка длиной до 8,000 символов (не-юникод символы, переменной длины) |
3 | text | Не-юникод данные переменной длины, длиной до 2,147,483,647 символов |
Строковые символьные (юникод)
N | Тип данных | Описание |
---|---|---|
1 | nchar | Строка длиной до 4,000 символов (юникод символы, фиксированной длины) |
2 | nvarchar | Строка длиной до 4,000 символов (юникод символы, переменной длины) |
3 | ntext | Юникод данные переменной длины, длиной до 1,073,741,823 символов |
Бинарные
N | Тип данных | Описание |
---|---|---|
1 | binary | Данные размером до 8,000 байт (фиксированной длины) |
2 | varbinary | Данные размером до 8,000 байт (переменной длины) |
3 | image | Данные размером до 2,147,483,647 байт (переменной длины) |
Смешанные
N | Тип данных | Описание |
---|---|---|
1 | timestamp | Уникальные числа, обновляющиеся при каждом изменении строки |
2 | uniqueidentifier | Глобально-уникальный идентификатор (GUID) |
3 | cursor | Объект курсора |
4 | table | Промежуточный результат, предназначенный для дальнейшей обработки |
Операторы
Оператор (operators) — это ключевое слово или символ, которые, в основном, используются в инструкциях WHERE для выполнения каких-либо операций. Они используются как для определения условий, так и для объединения нескольких условий в инструкции.
В дальнейших примерах мы будем исходить из предположения, что переменная a имеет значение 10 , а b — 20 .
Арифметические
Оператор | Описание | Пример |
---|---|---|
+ (сложение) | Сложение значений | a + b = 30 |
— (вычитание) | Вычитание правого операнда из левого | b — a = 10 |
* (умножение) | Умножение значений | a * b = 200 |
/ (деление) | Деление левого операнда на правый | b / a = 2 |
% (деление с остатком/по модулю) | Деление левого операнда на правый с остатком (возвращается остаток) | b % a = 0 |
Операторы сравнения
Оператор | Описание | Пример |
---|---|---|
= | Определяет равенство значений | a = b -> false |
!= | Определяет НЕравенство значений | a != b -> true |
<> | Определяет НЕравенство значений | a <> b -> true |
> | Значение левого операнда больше значения правого операнда? | a > b -> false |
Значение левого операнда меньше значения правого операнда? | a < b ->true | |
>= | Значение левого операнда больше или равно значению правого операнда? | a >= b -> false |
Значение левого операнда меньше или равно значению правого операнда? | a true | |
! | Значение левого операнда НЕ меньше значения правого операнда? | a ! < b ->false |
!> | Значение левого операнда НЕ больше значения правого операнда? | a !> b -> true |
Логические операторы
N | Оператор | Описание |
---|---|---|
1 | ALL | Сравнивает все значения |
2 | AND | Объединяет условия (все условия должны совпадать) |
3 | ANY | Сравнивает одно значение с другим, если последнее совпадает с условием |
4 | BETWEEN | Проверяет вхождение значения в диапазон от минимального до максимального |
5 | EXISTS | Определяет наличие строки, соответствующей определенному критерию |
6 | IN | Выполняет поиск значения в списке значений |
7 | LIKE | Сравнивает значение с похожими с помощью операторов подстановки |
8 | NOT | Инвертирует (меняет на противоположное) смысл других логических операторов, например, NOT EXISTS, NOT IN и т.д. |
9 | OR | Комбинирует условия (одно из условий должно совпадать) |
10 | IS NULL | Определяет, является ли значение нулевым |
11 | UNIQUE | Определяет уникальность строки |
Выражения
Выражение (expression) — это комбинация значений, операторов и функций для оценки (вычисления) значения. Выражения похожи на формулы, написанные на языке запросов. Они могут использоваться для извлечения из БД определенного набора данных.
Базовый синтаксис выражения выглядит так:
SELECT col1, col2, . colN FROM tableName WHERE [condition|expression];
Существуют различные типы выражений: логические, числовые и выражения для работы с датами.
Логические
Логические выражения извлекают данные на основе совпадения с единичным значением.
SELECT col1, col2, . colN FROM tableName WHERE выражение для поиска совпадения с единичным значением;
Предположим, что в таблице users имеются следующие записи:
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 25 | Moscow | active |
2 | Vika | 26 | Ekaterinburg | inactive |
3 | Elena | 27 | Ekaterinburg | active |
4 | Oleg | 28 | Moscow | inactive |
Выполняем поиск активных пользователей:
SELECT * FROM users WHERE status = active;
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 25 | Moscow | active |
3 | Elena | 27 | Ekaterinburg | active |
Числовые
Используются для выполнения арифметических операций в запросе.
SELECT numericalExpression as operationName [FROM tableName WHERE condition];
Простой пример использования числового выражения:
SELECT (10 + 5) AS addition;
addition |
---|
15 |
Существует несколько встроенных функций, таких как count() , sum() , avg() , min() , max() и др. для выполнения так называемых агрегирующих вычислений данных таблицы или колонки.
SELECT COUNT(*) AS records FROM users;
records |
---|
4 |
- AVG — вычисляет среднее значение
- SUM — вычисляет сумму значений
- MIN — вычисляет наименьшее значение
- MAX — вычисляет наибольшее значение
- COUNT — вычисляет количество записей в таблице
Также существует несколько встроенных функций для работы со строками:
- CONCAT — объединение строк
- LENGTH — возвращает количество символов в строке
- TRIM — удаляет пробелы в начале и конце строки
- SUBSTRING — извлекает подстроку из строки
- REPLACE — заменяет подстроку в строке
- LOWER — переводит символы строки в нижний регистр
- UPPER — переводит символы строки в верхний регистр и т.д.
- ROUND — округляет число
- TRUNCATE — обрезает дробное число до указанного количества знаков после запятой
- CEILING — возвращает наименьшее целое число, которое больше или равно текущему значению
- FLOOR — возвращает наибольшее целое число, которое меньше или равно текущему значению
- POWER — возводит число в указанную степень
- SQRT — возвращает квадратный корень числа
- RAND — генерирует случайное число с плавающей точкой в диапазоне от 0 до 1
Выражения для работы с датами
Эти выражения, как правило, возвращают текущую дату и время.
SELECT CURRENT_TIMESTAMP;
Current_Timestamp |
---|
2021-06-20 12:45:00 |
CURRENT_TIMESTAMP — это и выражение, и функция ( CURRENT_TIMESTAMP() ). Другая функция для получения текущей даты и времени — NOW() .
Другие функции для получения текущей даты и времени:
- CURDATE / CURRENT_DATE — возвращает текущую дату
- CURTIME / CURRENT_TIME — возвращает текущее время и т.д.
Функции для разбора даты и времени:
- DAYOFMONTH(date) — возвращает день месяца в виде числа
- DAYOFWEEK(date) — возвращает день недели в виде числа
- DAYOFYEAR(date) — возвращает номер дня в году
- MONTH(date) — возвращает месяц
- YEAR(date) — возвращает год
- LAST_DAY(date) — возвращает последний день месяца в виде даты
- HOUR(time) — возвращает час
- MINUTE(time) — возвращает минуты
- SECOND(time) — возвращает секунды и др.
Функции для манипулирования датами:
- DATE_ADD(date, interval) — выполняет сложение даты и определенного временного интервала
- DATE_SUB(date, interval) — выполняет вычитание из даты определенного временного интервала
- DATEDIFF(date1, date2) — возвращает разницу в днях между двумя датами
- TO_DAYS(date) — возвращает количество дней с 0-го дня года
- TIME_TO_SEC(time) — возвращает количество секунд с полуночи и др.
Для форматирования даты и времени используются функции DATE_FORMAT(date, format) и TIME_FORMAT(date, format) , соответственно.
Создание БД
Для создания БД используется инструкция CREATE DATABASE .
CREATE DATABASE dbName; -- или CREATE DATABASE IF NOT EXISTS dbName;
Условие IF NOT EXISTS позволяет избежать получения ошибки при попытке создания БД, которая уже существует.
Название БД должно быть уникальным в пределах СУБД.
Создаем БД testDB :
CREATE DATABASE testDB;
Получаем список БД:
SHOW DATABASES;
Database |
---|
information_schema |
postgres |
testDB |
Удаление БД
Для удаления БД используется инструкция DROP DATABASE .
DROP DATABASE dbName; -- или DROP DATABASE IF EXISTS dbName;
Условие IF EXISTS позволяет избежать получения ошибки при попытке удаления несуществующей БД.
DROP DATABASE testDB;
Обратите внимание: при удалении БД уничтожаются все данные, которые в ней хранятся, так что будьте предельно внимательны при использовании данной команды.
Проверяем, что БД удалена:
SHOW DATABASES;
Для получения списка таблиц используется инструкция SHOW TABLES .
Database |
---|
information_schema |
postgres |
Выбор БД
При наличии нескольких БД, перед выполнением каких-либо операций, необходимо выбрать БД. Для этого используется инструкция USE .
USE dbName;
Предположим, что мы не удаляли testDB . Тогда мы можем выбрать ее так:
USE testDB;
Создание таблицы
Создание таблицы предполагает указание названия таблицы и определение колонок таблицы и их типов данных. Для создания таблицы используется инструкция CREATE TABLE .
CREATE TABLE tableName ( col1 datatype, col2 datatype, . colN datatype, PRIMARY KEY (хотя бы одна колонка) );
Для создания таблицы путем копирования другой таблицы используется сочетание CREATE TABLE и SELECT .
Пример создания таблицы users , где первичным ключом являются идентификаторы пользователей, а поля для имени и возраста пользователя не могут быть нулевыми:
CREATE TABLE users ( userId INT, userName VARCHAR(20) NOT NULL, age INT NOT NULL, city VARCHAR(20), status VARCHAR(8), PRIMARY KEY (id) );
Проверяем, что таблица была создана:
DESC users;
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
userId | int(11) | NO | PRI | ||
userName | varchar(20) | NO | |||
age | int(11) | NO | |||
city | varchar(20) | NO | |||
status | varchar(8) | YES | NULL |
Удаление таблицы
Для удаления таблицы используется инструкция DROP TABLE .
Обратите внимание: при удалении таблицы, навсегда удаляются все хранящиеся в ней данные, индексы, триггеры, ограничения и разрешения, так что будьте предельно внимательны при использовании данной команды.
Удаляем таблицу users :
DROP TABLE users;
Теперь, если мы попытаемся получить описание users , то получим ошибку:
DESC users; -- ERROR 1146 (42S02): Table 'testDB.users' doesn't exist
Добавление колонок
Для добавления в таблицу колонок используется инструкция INSERT INTO .
INSERT INTO tableName (col1, col2, . colN) VALUES (val1, val2, . valN);
Названия колонок можно не указывать, однако, в этом случае значения должны перечисляться в правильном порядке.
INSERT INTO tableName VALUES (val1, val2, . valN);
Во избежание ошибок, рекомендуется всегда перечислять названия колонок.
Предположим, что мы не удаляли таблицу users . Заполним ее пользователями:
INSERT INTO users (userId, userName, age, city, status) VALUES (1, 'Igor', 25, 'Moscow', 'active'); INSERT INTO users (userId, userName, age, city, status) VALUES (2, 'Vika', 26, 'Ekaterinburg', 'inactive'); INSERT INTO users (userId, userName, age, city, status) VALUES (3, 'Elena', 27, 'Ekaterinburg', 'active');
В таблицу можно добавлять несколько строк за один раз.
INSERT INTO users (userId, userName, age, city, status) VALUES (1, 'Igor', 25, 'Moscow', 'active'), (2, 'Vika', 26, 'Ekaterinburg', 'inactive'), (3, 'Elena', 27, 'Ekaterinburg', 'active');
Также, как было отмечено, при добавлении строки названия полей можно опускать:
INSERT INTO users VALUES (4, 'Oleg', 28, 'Moscow', 'inactive');
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 25 | Moscow | active |
2 | Vika | 26 | Ekaterinburg | inactive |
3 | Elena | 27 | Ekaterinburg | active |
4 | Oleg | 28 | Moscow | inactive |
Заполнение таблицы с помощью другой таблицы
INSERT INTO tableName [(col1, col2, . colN)] SELECT col1, col2, . colN FROM anotherTable [WHERE condition];
Выборка полей
Для выборки полей из таблицы используется инструкция SELECT . Она возвращает данные в виде результирующей таблицы (результирующего набора, result-set).
SELECT col1, col2, . colN FROM tableName;
Для выборки всех полей используется такой синтаксис:
SELECT * FROM tableName;
Произведем выборку полей userId , userName и age из таблицы users :
SELECT userId, userName, age FROM users;
userId | userName | age |
---|---|---|
1 | Igor | 25 |
2 | Vika | 26 |
3 | Elena | 27 |
4 | Oleg | 28 |
Предложение WHERE
Предложение WHERE используется для фильтрации возвращаемых данных. Оно используется совместно с SELECT , UPDATE , DELETE и другими инструкциями.
SELECT col1, col2, . col2 FROM tableName WHERE condition;
Условие (condition), которому должны удовлетворять возвращаемые записи, определяется с помощью операторов сравнения или логических операторов типа > , < , = , NOT , LIKE и т.д.
Сделаем выборку полей userId , userName и age активных пользователей:
SELECT userId, userName, age FROM users WHERE status = 'active';
userId | userName | age |
---|---|---|
1 | Igor | 25 |
3 | Elena | 27 |
Сделаем выборку полей userId , age и city пользователя с именем Vika .
SELECT userId, age, city FROM users WHERE userName = 'Vika';
userId | age | city |
---|---|---|
2 | 26 | Ekaterinburg |
Обратите внимание: строки в предложении WHERE должны быть обернуты в одинарные кавычки ( » ), а числа, напротив, указываются как есть.
Операторы AND и OR
Конъюнктивный оператор AND и дизъюнктивный оператор OR используются для соединения нескольких условий при фильтрации данных.
AND
SELECT col1, col2, . colN FROM tableName WHERE condition1 AND condition2 . AND conditionN;
Возвращаемые записи должны удовлетворять всем указанным условиям.
Сделаем выборку полей userId , userName и age активных пользователей старше 26 лет:
SELECT userId, userName, age FROM users WHERE status = active AND age > 26;
userId | userName | AGE |
---|---|---|
3 | Elena | 27 |
OR
SELECT col1, col2, . colN FROM tableName WHERE condition1 OR condition2 . OR conditionN;
Возвращаемые записи должны удовлетворять хотя бы одному условию.
Сделаем выборку тех же полей неактивных пользователей или пользователей, младше 27 лет:
SELECT userId, userName, age FROM users WHERE status = inactive OR age < 27;
userId | userName | age |
---|---|---|
1 | Igor | 25 |
2 | Vika | 26 |
Обновление полей
Для обновления полей используется инструкция UPDATE . SET . Эта инструкция, обычно, используется в сочетании с предложением WHERE .
UPDATE tableName SET col1 = val1, col2 = val2, . colN = valN [WHERE condition];
Обновим возраст пользователя с именем Igor :
UPDATE users SET age = 30 WHERE username = 'Igor';
Если в данном случае опустить WHERE , то будет обновлен возраст всех пользователей.
Удаление записей
Для удаления записей используется инструкция DELETE . Эта инструкция также, как правило, используется в сочетании с предложением WHERE .
DELETE FROM tableName [WHERE condition];
Удалим неактивных пользователей:
DELETE FROM users WHERE status = 'inactive';
Если в данном случае опустить WHERE , то из таблицы users будут удалены все записи.
Предложения LIKE и REGEX
LIKE
Предложение LIKE используется для сравнения значений с помощью операторов с подстановочными знаками. Существует два вида таких операторов:
- проценты ( % )
- нижнее подчеркивание ( _ )
% означает 0, 1 или более символов. _ означает точно 1 символ.
SELECT col1, col2, . colN FROM tableName WHERE col LIKE 'xxx%' -- или WHERE col LIKE '%xxx%' -- или WHERE col LIKE '%xxx' -- или WHERE col LIKE 'xxx_' -- и т.д.
N | Инструкция | Результат |
---|---|---|
1 | WHERE col LIKE 'foo%' | Любые значения, начинающиеся с foo |
2 | WHERE col LIKE '%foo%' | Любые значения, содержащие foo |
3 | WHERE col LIKE '_oo%' | Любые значения, содержащие oo на второй и третьей позициях |
4 | WHERE col LIKE 'f%%' | Любые значения, начинающиеся с f и состоящие как минимум из 1 символа |
5 | WHERE col LIKE '%oo' | Любые значения, оканчивающиеся на oo |
6 | WHERE col LIKE '_o%o' | Любые значения, содержащие o на второй позиции и оканчивающиеся на o |
7 | WHERE col LIKE 'f_o' | Любые значения, содержащие f и o на первой и третьей позициях, соответственно, и состоящие из трех символов |
Сделаем выборку неактивных пользователей:
SELECT * FROM users WHERE status LIKE 'in%';
userId | userName | age | city | status |
---|---|---|---|---|
2 | Vika | 26 | Ekaterinburg | inactive |
4 | Oleg | 28 | Moscow | inactive |
Сделаем выборку пользователей 30 лет и старше:
SELECT * FROM users WHERE age LIKE '3_';
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 30 | Moscow | active |
REGEX
Предложение REGEX позволяет определять регулярное выражение, которому должна соответствовать запись.
SELECT col1, col2, . colN FROM tableName WHERE colName REGEXP регулярное выражение;
В регулярное выражении могут использоваться следующие специальные символы:
- ^ — начало строки
- $ — конец строки
- . — любой символ
- [символы] — любой из указанных в скобках символов
- [начало-конец] — любой символ из диапазона
- | — разделяет шаблоны
Сделаем выборку пользователей с именами Igor и Vika :
SELECT * FROM users WHERE userName REGEXP 'Igor|Vika';
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 30 | Moscow | active |
2 | Vika | 26 | Ekaterinburg | inactive |
Предложение TOP / LIMIT / ROWNUM
Данные предложения позволяют извлекать указанное количество или процент записей с начала таблицы. Разные СУБД поддерживают разные предложения.
SELECT TOP number|percent col1, col2, . colN FROM tableName [WHERE condition];
Сделаем выборку первых трех пользователей:
SELECT TOP 3 * FROM users;
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 30 | Moscow | active |
2 | Vika | 26 | Ekaterinburg | inactive |
3 | Elena | 27 | Ekaterinburg | active |
SELECT * FROM users LIMIT 3, [offset];
Параметр offset (смещение) определяет количество пропускаемых записей. Например, так можно извлечь первых двух пользователей, начиная с третьего:
SELECT * FROM users LIMIT 2, 2;
SELECT * FROM users WHERE ROWNUM
Предложения ORDER BY и GROUP BY
ORDER BY
Предложение ORDER BY используется для сортировки данных по возрастанию ( ASC ) или убыванию ( DESC ). Многие СУБД по умолчанию выполняют сортировку по возрастанию.
SELECT col1, col2, . colN FROM tableName [WHERE condition] [ORDER BY col1, col2, . colN] [ASC | DESC];
Обратите внимание: колонки для сортировки должны быть указаны в списке колонок для выборки.
Сделаем выборку пользователей, отсортировав их по городу и возрасту:
SELECT * FROM users ORDER BY city, age;
userId | userName | age | city | status |
---|---|---|---|---|
2 | Vika | 26 | Ekaterinburg | inactive |
3 | Elena | 27 | Ekaterinburg | active |
1 | Igor | 25 | Moscow | active |
4 | Oleg | 28 | Moscow | inactive |
Теперь выполним сортировку по убыванию:
SELECT * FROM users ORDER BY city, age DESC;
Определим собственный порядок сортировки по убыванию:
SELECT * FROM users ORDER BY (CASE city WHEN 'Ekaterinburg' THEN 1 WHEN 'Moscow' THEN 2 ELSE 100 END) ASC, city DESC;
GROUP BY
Предложение GROUP BY используется совместно с инструкцией SELECT для группировки записей. Оно указывается после WHERE и перед ORDER BY .
SELECT col1, col2, . colN FROM tableName WHERE condition GROUP BY col1, col2, . colN ORDER BY col1, col2, . colN;
Сгруппируем активных пользователей по городам:
SELECT city, COUNT(city) AS amount FROM users WHERE status = active GROUP BY city ORDER BY city;
city | amount |
---|---|
Ekaterinburg | 2 |
Moscow | 2 |
Ключевое слово DISTINCT
Ключевое слово DISTINCT используется совместно с инструкцией SELECT для возврата только уникальных записей (без дубликатов).
SELECT DISTINCT col1, col2, . colN FROM tableName [WHERE condition];
Сделаем выборку городов проживания пользователей:
SELECT DISTINCT city FROM users;
city |
---|
Ekaterinburg |
Moscow |
Соединения
Соединения (joins) используются для комбинации записей двух и более таблиц.
Предположим, что кроме users , у нас имеется таблица orders с заказами пользователей следующего содержания:
orderId | date | userId | amount |
---|---|---|---|
101 | 2021-06-21 00:00:00 | 2 | 3000 |
102 | 2021-06-20 00:00:00 | 2 | 1500 |
103 | 2021-06-19 00:00:00 | 3 | 2000 |
104 | 2021-06-18 00:00:00 | 3 | 1000 |
Сделаем выборку полей userId , userName , age и amount из наших таблиц посредством их соединения:
SELECT userId, userName, age, amount FROM users, orders WHERE users.userId = orders.userId;
userId | userName | age | amount |
---|---|---|---|
2 | Vika | 26 | 3000 |
2 | Vika | 26 | 1500 |
3 | Elena | 27 | 2000 |
3 | Elena | 27 | 1000 |
При соединении таблиц могут использоваться такие операторы, как = , < , >, <> , = , != , BETWEEN , LIKE и NOT , однако наиболее распространенным является = .
Существуют разные типы объединений:
- INNER JOIN — возвращает записи, имеющиеся в обеих таблицах
- LEFT JOIN — возвращает записи из левой таблицы, даже если такие записи отсутствуют в правой таблице
- RIGHT JOIN — возвращает записи из правой таблицы, даже если такие записи отсутствуют в левой таблице
- FULL JOIN — возвращает все записи объединяемых таблиц
- CROSS JOIN — возвращает все возможные комбинации строк обеих таблиц
- SELF JOIN — используется для объединения таблицы с самой собой
Предложение UNION
Предложение/оператор UNION используется для комбинации результатов двух и более инструкций SELECT . При этом, возвращаются только уникальные записи.
В случае с UNION , каждая инструкция SELECT должна иметь:
- одинаковый набор колонок для выборки
- одинаковое количество выражений
- одинаковые типы данных колонок и
- одинаковый порядок колонок
Однако, они могут быть разной длины.
SELECT col1, col2, . colN FROM table1 [WHERE condition] UNION SELECT col1, col2, . colN FROM table2 [WHERE condition];
Объединим наши таблицы users и orders :
SELECT userId, userName, amount, date FROM users LEFT JOIN orders ON users.useId = orders.userId UNION SELECT userId, userName, amount, date FROM users RIGHT JOIN orders ON users.userId = orders.userId;
userId | userName | amount | date |
---|---|---|---|
1 | Igor | NULL | NULL |
2 | Vika | 3000 | 2021-06-21 00:00:00 |
2 | Vika | 1500 | 2021-06-20 00:00:00 |
3 | Elena | 2000 | 2021-06-19 00:00:00 |
3 | Elena | 1000 | 2021-06-18 00:00:00 |
4 | Alex | NULL | NULL |
Предложение UNION ALL
Предложение UNION ALL также используется для объединения результатов двух и более инструкций SELECT . При этом, возвращаются все записи, включая дубликаты.
SELECT col1, col2, . colN FROM table1 [WHERE condition] UNION ALL SELECT col1, col2, . colN FROM table2 [WHERE condition];
Существует еще два предложения, похожих на UNION :
- INTERSECT — используется для комбинации результатов двух и более SELECT , но возвращаются только строки из первого SELECT , совпадающие со строками из второго SELECT
- EXCEPT|MINUS — возвращаются только строки из первого SELECT , отсутствующие во втором SELECT
Синонимы
Синонимы (aliases) позволяют временно изменять названия таблиц и колонок. "Временно" означает, что новое название используется только в текущем запросе, в БД название остается прежним.
Синтаксис синонима таблицы:
SELECT col1, col2, . colN FROM tableName AS aliasName [WHERE condition];
Синтаксис синонима колонки:
SELECT colName AS aliasName FROM tableName [WHERE condition];
Пример использования синонимов таблиц:
SELECT U.userId, U.userName, U.age, O.amount FROM users AS U, orders AS O WHERE U.userId = O.userId;
userId | userName | age | amount |
---|---|---|---|
2 | Vika | 26 | 3000 |
2 | Vika | 26 | 1500 |
3 | Elena | 27 | 2000 |
3 | Elena | 27 | 1000 |
Пример использования синонимов колонок:
SELECT userId AS user_id, userName AS user_name, age AS user_age FROM users WHERE status = active;
user_id | user_name | user_age |
---|---|---|
1 | Igor | 30 |
3 | Elena | 27 |
Индексы
Создание индексов
Индексы — это специальные поисковые таблицы (lookup tables), которые используются движком БД в целях более быстрого извлечения данных. Проще говоря, индекс — это указатель или ссылка на данные в таблице.
Индексы ускоряют работу инструкции SELECT и предложения WHERE , но замедляют работу инструкций UPDATE и INSERT . Индексы могут создаваться и удаляться, не оказывая никакого влияния на данные.
Для создания индекса используется инструкция CREATE INDEX , позволяющая определять название индекса, индексируемые колонки и порядок индексации (по возрастанию или по убыванию).
К индексам можно применять ограничение UNIQUE для того, чтобы обеспечить их уникальность.
Синтаксис создания индекса:
CREATE INDEX indexName ON tableName;
Синтаксис создания индекса для одной колонки:
CREATE INDEX indexName ON tableName (colName);
Синтакис создания уникальных индексов (такие индексы используются не только для повышения производительности, но и для обеспечения согласованности данных):
CREATE UNIQUE INDEX indexName ON tableName (colName);
Синтаксис создания индексов для нескольких колонок (композиционный индекс):
CREATE INDEX indexName ON tableName (col1, col2, . colN);
Решение о создании индексов для одной или нескольких колонок следует принимать на основе того, какие колонки будут часто использоваться в запросе WHERE в качестве условия для сортировки строк.
Для ограничений PRIMARY KEY и UNIQUE автоматически создаются неявные индексы.
Удаление индексов
Для удаления индексов используется инструкция DROP INDEX :
DROP INDEX indexName;
Несмотря на то, что индексы предназначены для повышения производительности БД, существуют ситуации, в которых их использования лучше избегать.
К таким ситуациям относится следующее:
- индексы не должны использоваться в маленьких таблицах
- в таблицах, которые часто и в большом объеме обновляются или перезаписываются
- в колонках, которые содержат большое количество нулевых значений
- в колонках, над которыми часто выполняются операции
Обновление таблицы
Команда ALTER TABLE используется для добавления, удаления и модификации колонок существующей таблицы. Также эта команда используется для добавления и удаления ограничений.
-- добавление новой колонки ALTER TABLE tableName ADD colName datatype; -- удаление колонки ALTER TABLE tableName DROP COLUMN colName; -- изменение типа данных колонки ALTER TABLE tableName MODIFY COLUMN colName newDatatype; -- добавление ограничения `NOT NULL` ALTER TABLE tableName MODIFY colName datatype NOT NULL; -- добавление ограничения `UNIQUE` ALTER TABLE tableName ADD CONSTRAINT myUniqueConstraint UNIQUE (col1, col2, . colN); -- добавление ограничения `CHECK` ALTER TABLE tableName ADD CONSTRAINT myUniqueConstraint CHECK (condition); -- добавление первичного ключа ALTER TABLE tableName ADD CONSTRAINT myPrimaryKey PRIMARY KEY (col1, col2, . colN); -- удаление ограничения ALTER TABLE tableName DROP CONSTRAINT myUniqueContsraint; -- mysql ALTER TABLE tableName DROP INDEX myUniqueContsraint; -- удаление первичного ключа ALTER TABLE tableName DROP CONSTRAINT myPrimaryKey; -- mysql ALTER TABLE tableName DROP PRIMARY KEY;
Добавляем в таблицу users новую колонку — пол пользователя:
ALTER TABLE users ADD sex char(1);
Удаляем эту колонку:
ALTER TABLE users DROP sex;
Очистка таблицы
Команда TRUNCATE TABLE используется для очистки таблицы. Ее отличие от DROP TABLE состоит в том, что сохраняется структура таблицы ( DROP TABLE полностью удаляет таблицу и все ее данные).
TRUNCATE TABLE tableName;
Очищаем таблицу users :
TRUNCATE TABLE users;
Проверяем, что users пустая:
SELECT * FROM users; -- Empty set (0.00 sec)
Представления
Представление (view) — это не что иное, как инструкция, записанная в БД под определенным названием. Другими словами, представление — это композиция таблицы в форме предварительно определенного запроса.
Представления могут содержать все или только некоторые строки таблицы. Представление может быть создано на основе одной или нескольких таблиц (это зависит от запроса для создания представления).
Представления — это виртутальные таблицы, позволяющие делать следующее:
- структурировать данные способом, который пользователи находят наиболее естественным или интуитивно понятным
- ограничивать доступ к данным таким образом, что пользователь может просматривать и (иногда) модифицировать только то, что ему нужно и ничего более
- объединять данные из нескольких таблиц для формирования отчетов
Создание представления
Для создания представления используется инструкция CREATE VIEW . Как было отмечено, представления могут создаваться на основе одной или нескольких таблиц, и даже на основе другого представления.
CREATE VIEW viewName AS SELECT col1, col2, . colN FROM tableName [WHERE condition];
Создаем представление для имен и возраста пользователей:
CREATE VIEW usersView AS SELECT userName, age FROM users;
Получаем данные с помощью представления:
SELECT * FROM usersView;
userName | age |
---|---|
Igor | 30 |
Vika | 26 |
Elena | 27 |
Oleg | 28 |
WITH CHECK OPTION
WITH CHECK OPTION — это настройка инструкции CREATE VIEW . Она позволяет обеспечить соответствие всех UPDATE и INSERT условию, определенном в представлении.
Если условие не удовлетворяется, выбрасывается исключение.
CREATE VIEW usersView AS SELECT userName, age FROM users WHERE age IS NOT NULL WITH CHECK OPTION;
Обновление представления
Представление может быть обновлено при соблюдении следующих условий:
- SELECT не содержит ключевого слова DISTINCT
- SELECT не содержит агрегирующих функций
- SELECT не содержит функций установки значений
- SELECT не содержит операций установки значений
- SELECT не содержит предложения ORDER BY
- FROM не содержит больше одной таблицы
- WHERE не содержит подзапросы
- запрос не содержит GROUP BY или HAVING
- вычисляемые колонки не обновляются
- все ненулевые колонки из базовой таблицы включены в представление в том же порядке, в каком они указаны в запросе INSERT
Пример обновления возраста пользователя с именем Igor в представлении:
UPDATE usersView SET age = 31 WHERE userName = 'Igor';
Обратите внимание: обновление строки в представлении приводит к ее обновлению в базовой таблице.
В представление могут добавляться новые строки с помощью команды INSERT . При выполнении этой команды должны соблюдаться те же правила, что и при выполнении команды UPDATE .
С помощью команды DELETE можно удалять строки из представления.
Удаляем из представления пользователя, возраст которого составляет 26 лет:
DELETE FROM usersView WHERE age = 26;
Обратите внимание: удаление строки в представлении приводит к ее удалению в базовой таблице.
Удаление представления
Для удаления представления используется инструкция DROP VIEW :
DROP VIEW viewName;
Удаляем представление usersView :
DROP VIEW usersView;
HAVING
Предложение HAVING используется для фильтрации результатов группировки. WHERE используется для применения условий к колонкам, а HAVING — к группам, созданным с помощью GROUP BY .
HAVING должно указываться после GROUP BY , но перед ORDER BY (при наличии).
SELECT col1, col2, . colN FROM table1, table2, . tableN [WHERE condition] GROUP BY col1, col2, . colN HAVING condition ORDER BY col1, col2, . colN;
Транзакции
Транзакция — это единица работы или операции, выполняемой над БД. Это последовательность операций, выполняемых в логическом порядке. Эти операции могут запускаться как пользователем, так и какой-либо программой, функционирующей в БД.
Транзакция — это применение одного или более изменения к БД. Например, при создании/обновлении/удалении записи мы выполняем транзакцию. Важно контролировать выполнение таких операций в целях обеспечения согласованности данных и обработки возможных ошибок.
На практике, запросы, как правило, не отправляются в БД по одному, они группируются и выполняются как часть транзакции.
Свойства транзакции
Транзакции имеют 4 стандартных свойства (ACID):
- атомарность (atomicity) — все операции транзакции должны быть успешно завершены. В противном случае, транзакция прерывается, а все изменения отменяются (происходит откат к предыдущему состоянию)
- согласованность (consistency) — состояние должно изменться в полном соответствии с операциями транзакции
- изоляция или автономность (isolation) — транзакции не зависят друг от друга и не оказывают друг на друга никакого влияния
- долговечность (durability) — результат звершенной транзакции должен сохраняться при поломке системы
Управление транзакцией
Для управления транзакцией используются следующие команды:
- BEGIN|START TRANSACTION — запуск транзакции
- COMMIT — сохранение изменений
- ROLLBACK — отмена изменений
- SAVEPOINT — контрольная точка для отмены изменений
- SET TRANSACTION — установка характеристик текущей транзакции
Команды для управления транзакцией могут использоваться только совместно с такими запросами как INSERT , UPDATE и DELETE . Они не могут использоваться во время создания и удаления таблиц, поскольку эти операции автоматически отправляются в БД.
Удаляем пользователя, возраст которого составляет 26 лет, и отправляем изменения в БД:
BEGIN TRANSACTION DELETE FROM users WHERE age = 26; COMMIT;
Удаляем пользователя с именем Oleg и отменяем эту операцию:
BEGIN DELETE FROM users WHERE username = 'Oleg'; ROLLBACK;
Контрольные точки создаются с помощью такого синтаксиса:
SAVEPOINT savepointName;
Возврат к контрольной точке выполняется так:
ROLLBACK TO savepointName;
Выполняем три запроса на удаление данных из users , создавая контрольные точки перед каждый удалением:
START TRANSACTION SAVEPOINT sp1; DELETE FROM users WHERE age = 26; SAVEPOINT sp2; DELETE FROM users WHERE userName = 'Oleg'; SAVEPOINT sp3; DELETE FROM users WHERE status = 'inactive';
Отменяем два последних удаления, возвращаясь к контрльной точке sp2 , созданной после первого удаления:
ROLLBACK TO sp2;
Делаем выборку пользователей:
SELECT * FROM users;
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 31 | Moscow | active |
3 | Elena | 27 | Ekaterinburg | active |
4 | Oleg | 28 | Moscow | inactive |
Как видим, из таблицы был удален только пользователь с возрастом 26 лет.
Для удаление контрольной точки используется команда RELEASE SAVEPOINT . Естественно, после удаления контрольной точки, к ней нельзя будет вернуться с помощью ROLLBACK TO .
Команда SET TRANSACTION используется для инициализации транзакции, т.е. начала ее выполнения. При этом, можно определять некоторые характеристики транзакции. Например, так можно определить уровень доступа транзакции (доступна только для чтения или для записи тоже):
SET TRANSACTION [READ WRITE | READ ONLY];
Временные таблицы
Некоторые СУБД поддерживают так называемые временные таблицы (temporary tables). Такие таблицы позволяют хранить и обрабатывать промежуточные результаты с помощью таких же запросов, как и при работе с обычными таблицами.
Временные таблицы могут быть очень полезными при необходимости хранения временных данных. Одной из главных особенностей таких таблиц является то, что они удаляются по завершении текущей сессии. При запуске скрипта временная таблица удаляется после завершения выполнения этого скрипта. При доступе к БД с помощью клиентской программы, такая таблица будет удалена после закрытия этой программы.
Временная таблица создается с помощью инструкции CREATE TEMPORARY TABLE , в остальном синтаксис создания таких таблиц идентичен синтаксису создания обычных таблиц.
Временная таблица удаляется точно также, как и обычная таблица, с помощью инструкции DROP TABLE .
Клонирование таблицы
Может возникнуть ситуация, когда потребуется получить точную копию существующей таблицы, а CREATE TABLE или SELECT окажется недостаточно в силу того, что мы хотим получить не только идентичную структуру, но также индексы, значения по умолчанию и т.д. копируемой таблицы.
В mysql , например, это можно сделать так:
- вызываем команду SHOW CREATE TABLE для получения инструкции, выполненной при создании таблицы, включая индексы и прочее
- меняем название таблицы и выполняем запрос. Получаем точную копию таблицы
- опционально: если требуется содержимое копируемой таблицы, можно также использовать инструкции INSERT INTO или SELECT
Подзапросы
Подзапрос — это внутренний (вложенный) запрос другого запроса, встроенный (вставленный) с помощью WHERE или других инструкций.
Подзапрос используется для получения данных, которые будут использованы основным запросом в качестве условия для фильтрации возвращаемых записей.
Подзапросы могут использоваться в инструкциях SELECT , INSERT , UPDATE и DELETE , а также с операторами = , < , >, >= ,
Правила использования подзапросов:
- они должны быть обернуты в круглые скобки
- подзапрос должен содержать только одну колонку для выборки, если основной запрос не содержит несколько таких колонок, которые сравниваются в подзапросе
- в подзапросе нельзя использовать команду ORDER BY , это можно сделать в основном запросе. В подзапросе для замены ORDER BY можно использовать GROUP BY
- подзапросы, возвращающие несколько значений, могут использоваться только с операторами, которые работают с наборами значений, такими как IN
- список SELECT не может содержать ссылки на значения, которые оцениваются (вычисляются) как BLOB , ARRAY , CLOB или NCLOB
- подзапрос не может быть сразу передан в функцию для установки значений
- команду BETWEEN нельзя использовать совместно с подзапросом. Тем не менее, в самомподзапросе указанную команду использовать можно
Подзапросы, обычно, используются в инструкции SELECT .
SELECT col1, col2, . colN FROM table1, table2, . tableN WHERE colName operator (SELECT col1, col2, . colN FROM table1, table2, tableN [WHERE condition]);
SELECT * FROM users WHERE userId IN ( SELECT userId FROM users WHERE status = 'active' );
userId | userName | age | city | status |
---|---|---|---|---|
1 | Igor | 30 | Moscow | active |
3 | Elena | 27 | Ekaterinburg | active |
Подзапросы могут использоваться в инструкции INSERT . Эта инструкция добавляет в таблицу данные, возвращаемые подзапросом. При этом, данные, возвращаемые подзапросом, могут быть модифицированы любыми способами.
INSERT INTO tableName col1, col2, . colN SELECT col1, col2, . colN FROM table1, table2, . tableN [WHERE operator [value]];
Подзапросы могут использоваться в инструкции UPDATE . При этом, данные из подзапроса могут использоваться для обновления любого количества колонок.
UPDATE tableName SET col = newVal [WHERE operator [value] ( SELECT colName FROM tableName [WHERE condition] ) ];
Данные, возвращаемые подзапросом, могут использоваться и для удаления записей.
DELETE FROM tableName [WHERE operator [value] ( SELECT colName FROM tableName [WHERE condition] ) ];
Последовательности
Последовательность — это набор целых чисел (1, 2, 3 и т.д.), генерируемых автоматически. Последовательности часто используются в БД, поскольку многие приложения нуждаются в уникальных значениях, используемых для идентификации строк.
Приведенные ниже примеры рассчитаны на mysql .
Простейшим способом определения последовательности является использование AUTO_INCREMENT при создании таблицы:
CREATE TABLE tableName ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), -- другие строки );
Для того, чтобы заново пронумеровать строки с помощью автоматически генерируемых значений (например, при удалении большого количества строк), можно удалить колонку, содержащую такие значения и создать ее заново. Обратите внимание: такая таблица не должна быть частью объединения.
ALTER TABLE tableName DROP id; ALTER TABLE tableName ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (id);
По умолчанию значения, генерируемые с помощью AUTO_INCREMENT , начинаются с 1. Для того, чтобы установить другое начальное значение достаточно указать, например, AUTO_INCREMENT = 100 — в этом случае нумерация строк начнется со 100.
- Веб-разработка
- Программирование
- SQL
Оператор SQL INSERT для вставки данных в таблицу БД
Оператор SQL INSERT предназначен для вставки значений столбцов в таблицу баз данных. В результате его применения в таблице базы данных появляется новая строка.
Оператор INSERT имеет следующий синтаксис:
INSERT INTO ИМЯ_ТАБЛИЦЫ [(ИМЕНА СТОЛБЦОВ)] VALUES (ВСТАВЛЯЕМЫЕ_ЗНАЧЕНИЯ)
Квадратные скобки [], в которые заключен элемент запроса (ИМЕНА СТОЛБЦОВ), означают, что этот элемент является необязательным.
Вставка значений в таблицу с указанием или без указания столбцов
Рассмотрим подробнее применение оператора INSERT с указанием имён столбцов и без указания, остановимся на случаях, когда указывать имена столбцов всё же требуется.
Будем работать с базой данных портала объявлений. В ней есть таблица ADS, содержащая данные о объявлениях, поданных за неделю.
Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке .
А скрипт для создания базы данных "Портал объявлений 1", её таблицы и заполения таблицы данных - в файле по этой ссылке .
Для использующих же MySQL приводим содержание оператора CREATE для создания таблицы:
CREATE TABLE ADS ( Id INT (11) NOT NULL DEFAULT '100', Category varchar (25) DEFAULT 'Some Category', Part varchar (25) DEFAULT 'Some Part', Units INT (5) DEFAULT NULL , Money INT (10) DEFAULT NULL , PRIMARY KEY (Id) )
Пример 1. Итак, есть база данных портала объявлений. Таблица ADS выглядит так:
Id | Category | Part | Units | Money |
1 | Транспорт | Автомашины | 110 | 17600 |
2 | Недвижимость | Квартиры | 89 | 18690 |
3 | Недвижимость | Дачи | 57 | 11970 |
4 | Транспорт | Мотоциклы | 131 | 20960 |
5 | Стройматериалы | Доски | 68 | 7140 |
6 | Электротехника | Телевизоры | 127 | 8255 |
7 | Электротехника | Холодильники | 137 | 8905 |
8 | Стройматериалы | Регипс | 112 | 11760 |
9 | Досуг | Книги | 96 | 6240 |
10 | Недвижимость | Дома | 47 | 9870 |
11 | Досуг | Музыка | 117 | 7605 |
12 | Досуг | Игры | 41 | 2665 |
Для вставки новой строки в эту таблицу на MySQL используем следующий запрос:
INSERT INTO ADS (Id, Category, Part, Units, Money) VALUES (13, 'Недвижимость', 'Гаражи', 22, 4620)
Или без указания имён столбцов:
INSERT INTO ADS VALUES (13, 'Недвижимость', 'Гаражи', 22, 4620)
MS SQL Server в ответ на такой запрос выдаст сообщение об ошибке, так как при создании таблицы было указано, что значения столбца Id являются идентификаторами и вставляются при добавлении новых строк автоматически с приращением 1. Поэтому на MS SQL Server нужно использовать следующий запрос (можете скопировать его и вставить в окно запросов):
USE adportal1; INSERT INTO ADS (Category, Part, Units, Money) VALUES ('Недвижимость', 'Гаражи', 22, 4620);
В результате выполнения запроса в таблице появится новая строка:
13 | Недвижимость | Гаражи | 22 | 4620 |
Из примера видно, что для вставки числовых значений в таблицу значения нужно указывать без кавычек, а для вставки строковых значений - в одинарных кавычках.
В запросе на вставку данных можно список столбцов можно указать не в том порядке, который задан при создании таблицы, и тогда данные следует указывать также в изменённом порядке.
Пример 2. Таким будет запрос на MySQL, в котором порядок следования столбцов изменён:
INSERT INTO ADS (Category, Id, Money, Part, Units) VALUES ('Недвижимость', 13, 4620, 'Гаражи', 22)
В результате выполнения запроса в таблице появится такая же новая строка, как и в примере 1.
Если вы используете MS SQL Server, то в запросе не нужно указывать столбец Id и запрос с изменённым порядком следования столбцов будет таким:
USE adportal1; INSERT INTO ADS (Category, Money, Part, Units) VALUES ('Недвижимость', 4620, 'Гаражи', 22)
Вставка значений по умолчанию (DEFAULT) и неопределённых значений (NULL)
Заметим, что при создании таблицы было предусмотрено, что значения столбцов могут иметь значения по умолчанию (DEFAULT). На MySQL для столбца Id можно предусмотреть значение 100. На MS SQL Server со строгим автоматическим приращением идентификатора это не допускается. В остальном же всё одинаково: для стобцов Category и Part значения по умолчанию - соответственно Some Category и Some Part, для столбцов Units и Money - значения NULL. Если в запросе на вставку данных на MySQL некоторые столбцы отсутствуют, то в них будут вставлены значения по умолчанию. На MS SQL в качестве значений нужно указать DEFAULT.
Пример 3. База данных и таблица - те же.
Запрос на MySQL. Вставим новые значения, указывая лишь столбец Id и его значение:
INSERT INTO ADS (Id) VALUES (14)
Все столбцы кроме Id получили значения по умолчанию. После выполнения этого запроса новая строка будет содержать следующие данные:
14 | Some Category | Some Part | NULL | NULL |
На MS SQL Server такой запрос недопустим.
Поскольку все столбцы могут иметь значения по умолчанию, можно использовать в запросе на вставку данных ключевое слово DEFAULT и не указывать имена столбцов.
Пример 4. Запрос на MySQL. Вставим новые значения, используя ключевое слово DEFAULT и не указывая имён столбцов:
INSERT INTO ADS VALUES ( DEFAULT , DEFAULT , DEFAULT , DEFAULT , DEFAULT )
Теперь все столбцы получили значения по умолчанию. После выполнения этого запроса новая строка будет содержать следующие данные:
100 | Some Category | Some Part | NULL | NULL |
Запрос на MS SQL Server (без указания столбца Id):
USE adportal1; INSERT INTO ADS VALUES ( DEFAULT , DEFAULT , DEFAULT , DEFAULT )
Вместо многократного использования слова DEFAULT можно использовать конструкцию DEFAULT VALUES, которая есть во многих диалектах SQL. Следует помнить, что в MySQL эта конструкция отсутствует.
Пример 5. Вставим новые значения, используя констукцию DEFAULT VALUES (запрос можно использовать и на MS SQL Server c предваряющей конструкцией USE adportal1):
INSERT INTO ADS DEFAULT VALUES
После выполнения этого запроса новая строка будет содержать следующие данные:
след. номер | Some Category | Some Part | NULL | NULL |
Вставка значений с использованием оператора SET в MySQL
В MySQL дополнительно существует альтернативная конструкция для вставки значений в таблицу с использованием оператора SET. Она похожа на конструкцию оператора UPDATE и имеет следующий синтаксис:
INSERT INTO ИМЯ_ТАБЛИЦЫ SET ИМЯ_СТОЛБЦА_1=ЗНАЧЕНИЕ, ИМЯ_СТОЛБЦА_2=ЗНАЧЕНИЕ, . ИМЯ_СТОЛБЦА_N=ЗНАЧЕНИЕ
В подобных запросах можно указывать имена не всех столбцов, при этом не указанные столбцы принимают значения по умолчанию.
Пример 6. База данных и таблица - те же, что и в предыдущих примерах.
Вставим в таблицу строку, при этом столбцы Units и Money примут значения по умолчанию:
INSERT INTO ADS SET Category='Недвижимость', Part='Гаражи'
В результате выполнения запроса в таблице появится новая строка:
13 | Недвижимость | Гаражи | NULL | NULL |
Использование механизма автоматического приращения при вставке данных
Механизм автоматического приращения предназначен для автоматического генерирования уникальных значений первичного ключа в таблице. При его использовании не требуется проверять все значения первичного ключа, чтобы определить максимальное значение. При создании новой записи можно указать в качестве значения первичного ключа 0 или NULL и в таблицу будет автоматически вставлено значение, увеличенное на единицу по сравнению с максимальным значением.
В разных диалектах SQL синтаксис автоматического приращения различается. В MySQL используется ключевое слово AUTO_INCREMENT. Таблица с использованием механизма AUTO_INCREMENT в MySQL создаётся так:
CREATE TABLE ADS ( Id INT (11) NOT NULL AUTO_INCREMENT , Category varchar (25) DEFAULT 'Some Category', Part varchar (25) DEFAULT 'Some Part', Units INT (5) DEFAULT NULL , Money INT (10) DEFAULT NULL , PRIMARY KEY (Id) )
В SQL Server используется ключевое слово IDENTITY (N, M), где N - начальное значение столца, M - шаг приращения. Так, указав IDENTITY (1, 1) мы обеспечим начальное значение первичного ключа 1 и приращение на 1 значения при каждой вставке новой строки:
CREATE TABLE ADS ( Id int IDENTITY (1, 1) PRIMARY KEY , Category varchar (25) DEFAULT 'Some Category', Part varchar (25) DEFAULT 'Some Part', Units INT (5) DEFAULT NULL , Money INT (10) DEFAULT NULL )
Вставка нескольких строк в таблицу
Применение рассмотренного выше механизма автоматического приращения позволяет вставлять в таблицу базы данных сразу несколько строк, не заботясь об уникальности значений первичного ключа.
Для этого применяется либо однострочный, либо многострочный оператор INSERT. Рассмотрим сначала синтаксис однострочного варианта.
Пример 7. Если используется механизм автоматического приращения значений первичного ключа, то на MySQL вставить новые строки в таблицу можно, применив несколько раз оператор INSERT и указав в качестве значений первичного ключа 0 или NULL:
INSERT INTO ADS VALUES ( NULL , 'Электротехника', 'Телевизоры', 127, 8255); INSERT INTO ADS VALUES ( NULL , 'Электротехника', 'Холодильники', 137, 8905); INSERT INTO ADS VALUES ( NULL , 'Стройматериалы', 'Регипс', 112, 11760); INSERT INTO ADS VALUES ( NULL , 'Досуг', 'Книги', 96, 6240);
Допустим, перед вставкой новых строк записи в таблице завершались строкой со значением первичного ключа 5. В результате выполнения запроса в таблице появятся новые строки:
6 | Электротехника | Телевизоры | 127 | 8255 |
7 | Электротехника | Холодильники | 137 | 8905 |
8 | Стройматериалы | Регипс | 112 | 11760 |
9 | Досуг | Книги | 96 | 6240 |
На MS SQL Server нет необходимости указывать значения столбца Id. Аналогичный запрос будет следующим:
USE adportal1; INSERT INTO ADS VALUES ('Электротехника', 'Телевизоры', 127, 8255); INSERT INTO ADS VALUES ('Электротехника', 'Холодильники', 137, 8905); INSERT INTO ADS VALUES ('Стройматериалы', 'Регипс', 112, 11760); INSERT INTO ADS VALUES ('Досуг', 'Книги', 96, 6240);
В MySQL и SQL Server существует многострочный оператор INSERT. Его отличие от однострочного варианта в том, что для вставки нескольких строк он используется один раз, а после ключевого слова VALUES указывается не один, а несколько списков значений добавляемых строк.
Пример 8. Вставим строки с теми же значениями, что и в предыдущем примере, используя многострочный оператор INSERT.
Запрос на MySQL:
INSERT INTO ADS VALUES ( NULL , 'Электротехника', 'Телевизоры', 127, 8255), ( NULL , 'Электротехника', 'Холодильники', 137, 8905), ( NULL , 'Стройматериалы', 'Регипс', 112, 11760), ( NULL , 'Досуг', 'Книги', 96, 6240);
Запрос на MS SQL Server:
USE adportal1; INSERT INTO ADS VALUES ('Электротехника', 'Телевизоры', 127, 8255), ('Электротехника', 'Холодильники', 137, 8905), ('Стройматериалы', 'Регипс', 112, 11760), ('Досуг', 'Книги', 96, 6240);
Результат применения - тот же, что и в предыдущем примере.
Примеры запросов к базе данных "Портал объявлений-1" есть также в уроках об операторах UPDATE, DELETE, HAVING и UNION.
SQL INSERT INTO: примеры вставки строк в таблицу БД MySQL
SQL оператор INSERT используется для вставки записей в существующую таблицу.
Синтаксис этого оператора следующий:
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name. )] VALUES (expression. ),(. ). или INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name. )] SELECT . или INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name SET col_name=expression, col_name=expression, .
Создадим тестовую таблицу
Давайте создадим таблицу table1 со столбцами a, b, c в нашей MySQL базе данных:
CREATE TABLE `table1` ( `a` INT(11), `b` INT(11), `c` INT(11) );
Запрос на вставку строки
Простой запрос, который вставляет строку со столбцами 111, 222 и 333 выглядит так:
INSERT INTO table1 (a, b, c) VALUES (111, 222, 333);
Еще один способ сделать то же самое:
INSERT INTO table1 SET a=111, b=222, c=333;
Столбцы, которые вы не перечислите заполняются значениями по умолчанию, которые вы предусматриваете при создании таблицы, даже если это просто NULL.
У таблиц обычно есть поле id с первичным ключом (PRIMARY KEY) таблицы. Если этому полю установлено значение AUTOINCREMENT т.е. оно заполняется автоматически, то в таком случае вы не должны его перечислять в списке столбцов оператора INSERT.
Вставка без перечисления столбцов
Если количество значений, которые мы вставляем = количеству столбцов в таблице, то можно не перечислять столбцы, и наш запрос может выглядеть так:
INSERT INTO table1 VALUES (111, 222, 333);
Этот способ крайне не рекомендуется. Дело в том, что со временем вы можете менять таблицы, например добавлять в них новые столбцы, а это значит, что все запросы записанные таким способом просто перестанут работать и вам придется менять их по всему вашему приложению. Поэтому, навсегда забываем этот способ. Я его привел, только чтобы вы так не делали.
Вставка сразу нескольких строк с помощью INSERT INTO
Если нам нужно вставить несколько строк, то мы просто перечисляем группы значений через запятую выглядит это так:
INSERT INTO table1 (a, b, c) VALUES (1, 222, 333), (2, 555, 666), (3, 555, 333);
Таким образом мы вставили 3 строки в нашу таблицу table1. Их может быть и больше. В MySQL четкого предела нет, однако он все таки существует и зависит от параметра max_allowed_packet который ограничивает размер запроса. Если вы установите SET GLOBAL max_allowed_packet=524288000; то размер запроса будет ограничен 500MB но делайте это в очень крайнем случае. Обычно всегда можно найти решение и разделить 1 большой запрос, на несколько более мелких и вставлять например не больше 1000 строк за один цикл.
Как вставить значение из другой таблицы INSERT INTO . SELECT .
Допустим у нас есть еще одна таблица table2 которая по структуре точно такая же как и первая. Нам в таблицу table2 нужно вставить все строки из table1.
Вставляем значения из table1 в таблицу table2:
INSERT INTO table2 (a, b, c) SELECT a, b, c FROM table1;
Вам следует позаботиться об уникальности ключей, если они есть в таблице, в которую мы вставляем. Например при дублировании PRIMARY KEY мы получим следующее сообщение об ошибке:
/* ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY' */
Если вы делаете не какую-то единичную вставку при переносе данных, а где-то сохраните этот запрос, например в вашем PHP скрипте, то всегда перечисляйте столбцы.
Как не рекомендуется делать (без перечисления столбцов):
INSERT INTO table2 SELECT * FROM table1;
Если у вас со временем изменится количество столбцов в таблице, то запрос перестанет работать. При выполнении запроса MySQL в лучшем случае просто будет возвращать ошибку:
/* Ошибка SQL (1136): Column count doesn't match value count at row 1 */
Либо еще хуже: значения вставятся не в те столбцы.
Вставка из другой таблицы с условием INSERT INTO . SELECT . WHERE .
А теперь представим, что нам нужно вставить только те строки из table1, у которых столбец "c" равен 333. Тогда наш запрос будет выглядеть так
INSERT INTO table2 (a, b, c) SELECT a, b, c FROM table1 WHERE c = 333;
То есть мы просто вставляем данные в таблицу, которые выбрали из другой таблицы при помощи обычного SELECT запроса
Теперь представим, что у нас в таблице table2 - 4 столбца, а в table1 - 3. При этом четвертый столбец в table2 обязательный. Чтобы выйти из этой ситуации, нужно передать какое-нибудь подходящее значение в этот лишний столбец. У нас чисто абстрактная задача, поэтому давайте передадим туда просто единицу.
INSERT INTO table2 (a, b, c, d) SELECT a, b, c, 1 FROM table1 WHERE c = 333;
Теперь в столбец d у нас записалась единица и проблема решена.
Вставка в определенный раздел INSERT INTO . PARTITION .
Если вам нужно вставить строки в определенный раздел таблицы, то нужно после таблицы указать PARTITION (название раздела), например так:
INSERT INTO table1 PARTITION (p1) VALUES(1, 2, 3);
Вставка в несколько разделов. Первая строка вставляется в раздел p1, а вторая в p2
INSERT INTO table1 PARTITION (p1, p2) VALUES(1, 2, 3), (4, 5, 6);
Вставка строк, некоторые из которых уже существуют в целевой таблице
Существование строк определяется по значению уникальных ключей. В зависимости от ситуации мы можем выбрать разные способы поведения при совпадении значений уникальных столбцов.
Игнорирование INSERT IGNORE INTO
Например если мы вставляем строку с PK = 1, и при этом в таблице уже есть PK = 1 то MySQL выдаст ошибку:
/* ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' */
Выполнение запроса на этом прервется, однако нам в некоторых случаях хотелось бы просто вставить данные, игнорируя ошибки. В этом нам поможет INSERT IGNORE INTO:
INSERT IGNORE INTO table1 (a, b, c) VALUES (1, 222, 333), (2, 555, 666), (3, 555, 333);
Просто добавляем IGNORE в наш запрос и ошибки будут игнорироваться
Вставка с заменой существующих значений REPLACE INTO
REPLACE работает также INSERT, но если совпадают уникальные ключи, то старая строка (или строки!) удаляется до вставки новой.
В таком случае наш пример выглядит следующим образом:
REPLACE INTO table1 (a, b, c) VALUES (1, 222, 333), (2, 555, 666), (3, 555, 333);
Обновление некоторых полей, при существовании строк ON DUPLICATE KEY UPDATE
При совпадении ключей, мы можем также заменить некоторые или все поля в строке.
Наш запрос будет выглядеть так:
INSERT INTO table1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=VALUES(c);
В данном примере если у нас какой-то уникальный ключ совпадает, то мы не производим вставку, а обновляем существующую строку или строки путем присваивания столбцу "c" значения, которое у нас перечислено в VALUES.
Иными словами, если ключ совпадает, то мы просто обновим данные столбца "с" а остальные столбцы трогать не будем.
Иногда нам нужно при совпадении ключей обновить все значения. Этом можно сделать просто перечислив все столбцы:
INSERT INTO table1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE a=VALUES(a), b=VALUES(b), c=VALUES(c);
При обновлении столбцов мы также можем использовать разные выражения, например:
INSERT INTO table1 (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
Выражения для вставляемых значений в VALUES
При вставке значений, мы можем использовать выражения и даже использовать в своих выражениях значения других столбцов.
Пример использования выражений:
INSERT INTO table1 (a, b, c) VALUES (1, 222, 333 + a), (2, 555, 666 + b);
Таким образом мы для формирования столбца "c" использовали столбцы "a" и "b".
Приоритет вставки INSERT LOW_PRIORITY / HIGH_PRIORITY
Установление приоритета нужно для решение проблем с конкурентными вставками. При вставках происходит блокировка строк и если 2 INSERT запроса требуют блокировки одних и тех же строк, для своего выполнения, то иногда может потребоваться повысить или понизить приоритет некоторых запросов, по отношению к другим. Это можно сделать указав приоритет LOW_PRIORITY или HIGH_PRIORITY
Наш запрос будет выглядеть так для LOW_PRIORITY:
INSERT LOW_PRIORITY INTO table1 (a, b, c) VALUES(1, 2, 3);
INSERT HIGH_PRIORITY INTO table1 (a, b, c) VALUES(1, 2, 3);
Свежие записи
- SQL UPDATE: примеры обновления строк в таблице
- PHP: substr и мощные альтернативы, чтобы вырезать часть строки
- Степень в C, C++ и С#: как возвести число в любую степень, побитовые операции
- Скачать ShowKeyPlus: ссылка на последнюю официальную версию, скачивание, установка
- Как создать файл в Linux: 12 способов
- SQL INSERT INTO: примеры вставки строк в таблицу БД MySQL
- PHP: str_replace - замена или удаление подстроки в строке
- Функция date() в php: распространенные форматы, примеры, советы
- cURL в PHP: примеры POST, GET запросов с headers, cookie, JSON и многопоточностью
- JSON в PHP: примеры json_encode, json_decode, работа с кириллицей и utf-8
- Файл gitignore - примеры и документация
- Сортировка массивов в php: ksort, asort и прочие sort'ы
- jQuery onclick: как выполнить код при клике на кнопку
- 500 Internal Server Error - в чем причина?
- SMTP от Yandex: как отправить письма из PHP - пример настроек
- No such file or directory - в чем причина?
- Как получить первый элемент массива в php
- Cтроку в массив по разделителю в PHP: explode, str_split, strtok - что выбрать?
- 301 редирект на https с www через htaccess
- Как в php добавить к массиву другой массив?
- 301 редирект на https без www с помощью htaccess
- Регулярные выражения в PHP
- PHP json_decode — как декодировать результат в массив?
- Yii2 ActiveRecord шпаргалка по составлению запросов
- Поиск подстроки в строке с помощью PHP
- Отправка почты на php
- Как подключить php код в html
- Конвертировать массив в строку при помощи PHP
- Подключение одного php файла в другой
- Подборка ссылок для веб-разработчика
- Проблема с кириллицей в PHPWord