<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>@sqlite</title><subtitle>Работа с базами данных SQLite3</subtitle><author><name>@sqlite</name></author><id>https://teletype.in/atom/sqlite</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/sqlite?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@sqlite?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=sqlite"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/sqlite?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-13T20:39:43.334Z</updated><entry><id>sqlite:TRANSACTION</id><link rel="alternate" type="text/html" href="https://teletype.in/@sqlite/TRANSACTION?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=sqlite"></link><title>Часть 9: Транзакции в базах данных. BEGIN TRANSACTION, COMMIT, ROLLBACK, SAVEPOINT</title><published>2022-01-06T16:33:43.720Z</published><updated>2022-01-06T16:38:35.691Z</updated><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/ea/13/ea1370ae-fee2-46a6-99ba-bd2a1f583e99.png&quot;&gt;Напомню, что команда BEGIN TRANSACTION говорит СУБД о том, что клиент хочет начать транзакцию и при этом СУБД должна изолировать данные, с которыми будет работать пользователь в транзакции. В этой статье мы ознакомимся с синтаксисом команды BEGIN TRANSACTION и некоторыми ее особенностями в SQLite3.</summary><content type="html">
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#vmlM&quot;&gt;Синтаксис и использование оператора BEGIN TRANSACTION в SQLite&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#yxaJ&quot;&gt;Команда COMMIT в базах данных SQLite (оператор COMMIT в SQLite3)&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#jTan&quot;&gt;Команда ROLLBACK в базах данных SQLite (оператор ROLLBACK в SQLite3)&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#STG4&quot;&gt;Команда SAVEPOINT в базах данных SQLite (оператор SAVEPOINT в SQLite3)&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;p id=&quot;S4em&quot;&gt;Напомню, что команда BEGIN TRANSACTION говорит СУБД о том, что клиент хочет начать транзакцию и при этом СУБД должна изолировать данные, с которыми будет работать пользователь в транзакции. В этой статье мы ознакомимся с синтаксисом команды BEGIN TRANSACTION и некоторыми ее особенностями в SQLite3.&lt;/p&gt;
  &lt;h3 id=&quot;vmlM&quot;&gt;Синтаксис и использование оператора BEGIN TRANSACTION в SQLite&lt;/h3&gt;
  &lt;p id=&quot;hBVX&quot;&gt;Рассмотрим первую команду из группы &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/tema-9-komandy-upravleniya-tranzakciyami-v-bazax-dannyx-sqlite3-tcl-operatory.html&quot; target=&quot;_blank&quot;&gt;управления транзакциями в SQLite3&lt;/a&gt;. Команда BEGIN TRANSACTION в SQLite позволяет начать транзакцию. Давайте рассмотрим синтаксис команды BEGIN TRANSACTION в SQLite3.&lt;/p&gt;
  &lt;figure id=&quot;6VaH&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ea/13/ea1370ae-fee2-46a6-99ba-bd2a1f583e99.png&quot; width=&quot;953&quot; /&gt;
    &lt;figcaption&gt;Команда BEGIN TRANSACTION в базах данных SQLite&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DJ9a&quot;&gt;Синтаксис команды BEGIN TRANSACTION в базах SQLite3 довольно прост: сначала идут два ключевых слово BEGIN TRANSACTION, а далее уже идут команды транзакции. Этот синтаксис СУБД SQLite3 позволяет упростить еще сильнее, мы можем не писать ключевое слово TRANSACTION.&lt;/p&gt;
  &lt;p id=&quot;MvHK&quot;&gt;SQLite3 позволяет выбрать режим блокировки при выполнении транзакции, для этого используются ключевые слова: DEFERRED, IMMEDIATE, EXCLUSIVE.&lt;/p&gt;
  &lt;p id=&quot;KbFs&quot;&gt;&lt;em&gt;DEFERRED - &lt;/em&gt;База данных блокируется на запись при выполнение первого оператора чтения или записи, который находится внутри тела транзакции (после команды BEGIN). При такой блокировки база данных будет доступна другим пользователям только для чтения, но не для записи. Режим DEFERRED является стандартным в SQLite3 и его можно не указывать.&lt;/p&gt;
  &lt;p id=&quot;pVyg&quot;&gt;&lt;em&gt;IMMEDIATE&lt;/em&gt; - Выполнит блокировку базы данных после ключевого слова BEGIN.&lt;/p&gt;
  &lt;p id=&quot;CWVk&quot;&gt;&lt;em&gt;EXCLUSIVE&lt;/em&gt; - Заблокирует базу данных для других пользователей не только на запись, но и на чтение. Блокировка происходит после ключевого слова BEGIN.&lt;/p&gt;
  &lt;p id=&quot;AglV&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;yxaJ&quot;&gt;Команда COMMIT в базах данных SQLite (оператор COMMIT в SQLite3)&lt;/h3&gt;
  &lt;p id=&quot;ZWG8&quot;&gt;Рассмотрим вторую команду &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/tema-9-komandy-upravleniya-tranzakciyami-v-bazax-dannyx-sqlite3-tcl-operatory.html&quot; target=&quot;_blank&quot;&gt;управления транзакциями в базах данных SQLite&lt;/a&gt;. COMMIT TRANSACTION в SQLite3 позволяет подтвердить операции, выполненные внутри транзакции. Хочу обратить ваше внимание, что &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-sql-zaprosy-klyuchevye-slova-komandy-predlozheniya-i-sintaksis-yazyka-sql.html&quot; target=&quot;_blank&quot;&gt;SQL предложение&lt;/a&gt;, содержащее команду &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-9-1-komanda-begin-transaction-v-bazax-dannyx-sqlite3-sql-operator-begin-transaction.html&quot; target=&quot;_blank&quot;&gt;BEGIN&lt;/a&gt; и предложение, содержащее команду COMMIT – это две разных команды для &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/arxitektura-subd-arxitektura-baz-dannyx-logicheskaya-struktura-subd-opisanie-dannyx-v-baze-dannyx-bazy-dannyx-sxema-dannyx.html&quot; target=&quot;_blank&quot;&gt;СУБД&lt;/a&gt;, между которыми может быть множество запросов к базе данных распределенных во времени. Оператор COMMIT в базах данных SQLite подтверждает изменения, внесенные транзакцией. Давайте взглянем на синтаксис команды COMMIT в SQLite3. Хотя я и использую термин оператор, вместо команда, позволю напомнить, что &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-4-sql-operatory.html&quot; target=&quot;_blank&quot;&gt;SQL операторы&lt;/a&gt; и команды — это разные языковые конструкции.&lt;/p&gt;
  &lt;figure id=&quot;nods&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3c/ed/3cedad97-ebd8-48b9-9294-4121e178cb2c.png&quot; width=&quot;728&quot; /&gt;
    &lt;figcaption&gt;Синтаксис команды COMMIT в базах данных SQLite&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;K6c3&quot;&gt;Синтаксис оператора COMMIT TRANSACTION в SQLite3 очень прост: ключевое слово COMMIT, которое можно заменить словом END, за которым идет ключевое слово TRANSACTION. SQLite3 позволяет не писать ключевое слово TRANSACTION. Давайте посмотрим на примере работу команды COMMIT TRANSACTION в базах данных SQLite3.&lt;/p&gt;
  &lt;p id=&quot;MZdy&quot;&gt;Пример использования оператора COMMIT в базах данных SQLite&lt;/p&gt;
  &lt;pre id=&quot;9zzO&quot; data-lang=&quot;sql&quot;&gt;--Начинаем транзакцию

BEGIN;

-- Выберем первых 10 записей из таблицы City

SELECT * FROM city LIMIT 10;

-- Удаляем первую строку из таблицы city

DELETE FROM city WHERE  id = 1;

-- Посмотрим на первых 10 записей

SELECT * FROM city LIMIT 10;

/* 
 * Пока вы не выполните команду COMMIT,
 * строка не будет удалена, так как транзакция еще не подтверждена,
 * в этом можно убедиться, подключившись к базе данных World
 * другим клиентом, выполнив SELECT
 */

COMMIT;&lt;/pre&gt;
  &lt;p id=&quot;MZli&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;lkdk&quot;&gt;На самом деле это пример ради примера, удалить первую строку из таблицы &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-4-komanda-delete-v-sqlite3-operator-delete-v-sqlite.html&quot; target=&quot;_blank&quot;&gt;командой DELETE &lt;/a&gt;мы могли бы и не используя транзакции. Так же хочу заметить, что если вы попробуете установить второе соединение с базой данных World в тот момент, когда транзакция не завершена, то таблица City будет доступна только для чтения из-за свойства изоляции транзакции. А теперь, воспользовавшись &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-1-komanda-select-v-sqlite3-operator-select-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;командой SELECT&lt;/a&gt;, убедимся, что внесенные изменения вступили в силу.&lt;/p&gt;
  &lt;pre id=&quot;D6YP&quot; data-lang=&quot;sql&quot;&gt;-- Посмотрим на первых 10 записей после подтверждения транзакции

SELECT * FROM city LIMIT 10;&lt;/pre&gt;
  &lt;p id=&quot;6NR8&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;3yuz&quot;&gt;По сути, пока вы не выполните команду COMMIT, SQLite3 не внесет ни одного изменения в &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/bazy-dannyx-vidy-i-tipy-baz-dannyx-struktura-relyacionnyx-baz-dannyx-proektirovanie-baz-dannyx-setevye-i-ierarxicheskie-bazy-dannyx.html&quot; target=&quot;_blank&quot;&gt;базу данных&lt;/a&gt; (не выполнит ни одну команду после оператора BEGIN). Как только вы сказали SQLite COMMIT, все изменения будут выполнены.&lt;/p&gt;
  &lt;p id=&quot;vh6r&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;jTan&quot;&gt;Команда ROLLBACK в базах данных SQLite (оператор ROLLBACK в SQLite3)&lt;/h3&gt;
  &lt;p id=&quot;O3Gv&quot;&gt;Рассмотрим третью команду из&lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/tema-9-komandy-upravleniya-tranzakciyami-v-bazax-dannyx-sqlite3-tcl-operatory.html&quot; target=&quot;_blank&quot;&gt; группы управления транзакциями&lt;/a&gt; – команду ROLLBACK TRANSACTION. Команда ROLLBACK TRANSACTION в базах данных SQLite используется для отмены запросов, введенных после команды &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-9-1-komanda-begin-transaction-v-bazax-dannyx-sqlite3-sql-operator-begin-transaction.html&quot; target=&quot;_blank&quot;&gt;BEGIN&lt;/a&gt;. Если команда &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-9-2-komanda-commit-v-bazax-dannyx-sqlite-operator-commit-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;COMMIT&lt;/a&gt; подтверждает изменения, то оператор ROLLBACK TRANSACTION их откатывает и завершает транзакцию. Давайте посмотрим на синтаксис команды ROLLBACK в базах данных SQLite3.&lt;/p&gt;
  &lt;figure id=&quot;ffJw&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/43/7e/437e4772-4c72-47ff-adb7-3e8fbe6aad52.png&quot; width=&quot;1293&quot; /&gt;
    &lt;figcaption&gt;Синтаксис команды ROLLBACK TRANSACTION в SQLite. Синтаксис оператора ROLLBACK TRANSACTION в базах данных SQLite3&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;JXe0&quot;&gt;Синтаксис оператора ROLLBACK в SQLite3 очень прост: сначала идет ключевое слово ROLLBACK, а затем идет ключевое слово TRANSACTION, которое можно не писать. Сейчас не обращайте внимание на SAVEPOINT, на мой взгляд это отдельная конструкция, которую мы рассмотрим в следующей записи. Давайте рассмотрим пример использования команды ROLLBACK TRANSACTION в SQLite.&lt;/p&gt;
  &lt;p id=&quot;gnEt&quot;&gt;Для примера использования оператора ROLLBACK TRANSACTION в SQLite3  будем использовать демонстрационную базу данных World.db3. Совет: если вы самостоятельно будете повторять пример ROLLBACK TRANSACTION в SQLite, то выполняйте все команды по очереди, а не копируйте весь листинг целиком.&lt;/p&gt;
  &lt;pre id=&quot;6VFt&quot; data-lang=&quot;sql&quot;&gt;--Начинаем транзакцию

BEGIN;

/*
 * Выберем первых 10 записей из таблицы City
 * (в результате мы получим записи со 2
 * по 11, т.к. ранее мы уже удалили запись с id =1)
 */

SELECT * FROM city LIMIT 10;

-- Удаляем вторую строку из таблицы city

DELETE FROM city WHERE  id = 2;

-- Посмотрим на первых 10 записей и увидим, что вывелись записи с 3 по 12

SELECT * FROM city LIMIT 10;

/*
 * Пока вы не выполните команду ROLLBACK,
 * транзакция не будет завершена,а вы
 * будете видеть все изменения
 */

ROLLBACK;&lt;/pre&gt;
  &lt;p id=&quot;JgYO&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;g8hd&quot;&gt;А теперь давайте убедимся в том, что оператор ROLLBACK TRANSACTION сработал и мы не внесли никаких изменений в таблицу базы данных SQLite3. Для этого мы выведем записи со второй по одиннадцатую &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-1-komanda-select-v-sqlite3-operator-select-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;командой SELECT&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;I5xM&quot; data-lang=&quot;sql&quot;&gt;/*
 * Посмотрим на первых 10 записей после подтверждения транзакции,
 * вы увидите записи со 2 по 11
 */
 
SELECT * FROM city LIMIT 10;&lt;/pre&gt;
  &lt;p id=&quot;m3iK&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;QkT0&quot;&gt;Обратите внимание: иногда я использую слово оператор, вместо слова команда, это не совсем правильно с формальной точки зрения, так как &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-4-sql-operatory.html&quot; target=&quot;_blank&quot;&gt;SQL операторы&lt;/a&gt; не являются командами, так же часто вы можете услышать словосочетание &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-sql-zaprosy-klyuchevye-slova-komandy-predlozheniya-i-sintaksis-yazyka-sql.html&quot; target=&quot;_blank&quot;&gt;SQL запрос&lt;/a&gt;, когда на самом деле человек говорит про SQL предложение. Пока вы не выполните команду ROLLBACK, SQLite3 не завершит транзакцию и не отменит изменения, внесенные данной транзакцией. Как только вы сказали SQLite ROLLBACK, все изменения будут отменены, а транзакция завершена.&lt;/p&gt;
  &lt;p id=&quot;LaPj&quot;&gt;Не важно какие команды выполнялись внутри транзакции, команда ROLLBACK TRANSACTION отменит любые. Вы создали базу данных &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-6-1-komanda-create-v-sqlite3-ddl-operator-create.html&quot; target=&quot;_blank&quot;&gt;командой CREATE&lt;/a&gt; или вы добавили несколько строк в таблицу &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-2-komanda-insert-v-sqlite3-operator-insert-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;командой INSERT&lt;/a&gt;, да даже если вы удалили таблицу &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-6-3-komanda-drop-v-sqlite3-ddl-operator-drop-v-sqlite.html&quot; target=&quot;_blank&quot;&gt;командой DROP&lt;/a&gt;... ROLLBACK TRANSACTION вернет базу данных к тому состоянию, в каком она была до транзакции.&lt;/p&gt;
  &lt;p id=&quot;Ep1n&quot;&gt;Так же важно понимать, что если вы завершите транзакцию командой COMMIT, то оператор ROLLBACK вам уже не поможет, так как изменения были подтверждены. Обычно приложения, использующие базы данных и транзакции, принимают решения о том, как завершить транзакцию на основе действий пользователя или каких-либо внешних факторов, например, вы совершаете платеж картой в магазине, и тут неожиданно гаснет свет и терминал отключается: в этом случае деньги магазину переведены не будут, а вы не сможете забрать товар, так как его не оплатили.&lt;/p&gt;
  &lt;p id=&quot;4w4Z&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;STG4&quot;&gt;Команда SAVEPOINT в базах данных SQLite (оператор SAVEPOINT в SQLite3)&lt;/h3&gt;
  &lt;p id=&quot;3GP5&quot;&gt;Бывают такие ситуации, когда нужно отменить операции произведенные в транзакции, но не завершать ее и эта запись, как раз таки и покажет вам, как это сделать.&lt;/p&gt;
  &lt;p id=&quot;2Hjf&quot;&gt;В базах данных SQLite для таких целей есть команда SAVEPOINT. Оператор SAVEPOINT является, с одной стороны, псевдонимом команд COMMIT и BEGIN, но в тоже время, использование оператора SAVEPOINT в базах данных SQLite3 позволяет откатить транзакцию на контрольную точку, но не завершать ее, чтобы выполнить операции повторно. В этой статье мы с вами разберем синтаксис команды SAVEPOINT, особенности ее реализации в SQLite и посмотрим несколько примеров использования SAVEPOINT в SQLite3.&lt;/p&gt;
  &lt;p id=&quot;UHe2&quot;&gt;Команда SAVEPOINT в базах данных SQLite – это еще один способ начать транзакцию. Команда SAVEPOINT в SQLite3 может работать, как самостоятельно, так и внутри конструкции BEGIN … COMMIT. По сути, оператор SAVEPOINT в SQLite3 создает транзакцию с именем, имя транзакции может быть не уникальным, а работает транзакция SAVEPOINT в базах данных SQLite3 в режиме DEFERRED, о котором мы говорили, когда рассматривали оператор BEGIN. Давайте рассмотрим синтаксис команды SAVEPOINT в SQLite.&lt;/p&gt;
  &lt;figure id=&quot;TNGS&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/savepoint-rel.gif&quot; width=&quot;440&quot; /&gt;
    &lt;figcaption&gt;Синтаксис команды SAVEPOINT в базах данных SQLite3 при завершении транзакции с подтверждением изменений&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NLcU&quot;&gt;Синтаксис команды SAVEPOINT в SQLite3 при успешном завершении транзакции выглядит следующим образом: начинаем транзакцию командой SAVEPOINT, далее даем имя нашей транзакции, после чего следует набор SQL запросов внутри транзакции, а подтверждение транзакции происходит при помощи команды RELEASE SAVEPOINT и название метки. SQLite3 позволяет SAVEPOINT не писать, когда мы хотим завершить транзакцию. Рассмотрим синтаксис оператора SAVEPOINT в базах данных SQLite3 в том случае, когда нам необходимо отменить изменения.&lt;/p&gt;
  &lt;figure id=&quot;YyQu&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/savepoint-roll.gif&quot; width=&quot;712&quot; /&gt;
    &lt;figcaption&gt;Синтаксис оператора SAVEPOINT в базах данных SQLite с откатом внесенных изменений&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;LeJz&quot;&gt;Если нам необходимо отменить изменения транзакции в SQLite3 предусмотрен второй вариант использования SAVEPOINT: начинаем транзакцию с ключевого слова SAVEPOINT, за которым идет имя транзакции, далее следует набор запросов, после которого для отмены транзакции идет ключевое слово ROLLBACK TRANSACTION TO SAVEPOINT и имя транзакции. SQLite позволяет опускать слово TRANSACTION и в этом случае. Давайте рассмотрим примеры использования команды SAVEPOINT в SQLite3.&lt;/p&gt;
  &lt;p id=&quot;B8cp&quot;&gt;Для примера работы SAVEPOINT в SQLite будем использовать базу данных World.db3 из предыдущих записей. Если вы помните, мы уже удалили первую строку из таблицы City. Совет: если вы самостоятельно будете повторять пример SAVEPOINT в SQLite3, то выполняйте все команды по очереди, а не копируйте весь листинг целиком.&lt;/p&gt;
  &lt;pre id=&quot;d4Kk&quot; data-lang=&quot;sql&quot;&gt;-- Создаем транзакцию с именем при помощи команды SAVEPOINT

SAVEPOINT  transact1;

-- Посмотрим первых 10 записей из таблицы City

SELECT * FROM City LIMIT 10;

-- Удалим запись с id = 2

DELETE FROM city WHERE  id = 2;

-- Посмотрим на первых 10 записей

SELECT * FROM city LIMIT 10;

/*
 * Пока вы не выполните команду RELEASE SAVEPOINT,
 * строка не будет удалена, так
 * как транзакция еще не подтверждена,
 * в этом можно убедиться, подключившись к
 * базе данных World другим клиентом, выполнив SELECT
 */
 
RELEASE transact1;
/*
 * Посмотрим на первых 10 записей после подтверждения транзакции,
 * строки с id = 2 вы не увидите
 */&lt;/pre&gt;
  &lt;p id=&quot;nvhY&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;V3Yi&quot;&gt;В принципе, ничего хитрого внутри транзакции мы не сделали: воспользовавшись &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-1-komanda-select-v-sqlite3-operator-select-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;оператором SELECT&lt;/a&gt; мы посмотрели первых 10 строк из таблицы и удалили строку с id = 2 при помощи &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-4-komanda-delete-v-sqlite3-operator-delete-v-sqlite.html&quot; target=&quot;_blank&quot;&gt;оператора DELETE&lt;/a&gt;. Эти действия можно было бы сделать не используя транзакцию и оператор SAVEPOINT. Убедиться в том, что изменения были подтверждены можно, опять же, воспользовавшись командой SELECT:&lt;/p&gt;
  &lt;pre id=&quot;vi80&quot; data-lang=&quot;sql&quot;&gt;SELECT * FROM city LIMIT 10;&lt;/pre&gt;
  &lt;p id=&quot;gArg&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;coUc&quot;&gt;Так работает &lt;strong&gt;оператор SAVEPOINT в SQLite3&lt;/strong&gt; при успешном завершении транзакции. Давайте теперь посмотрим, как работает SAVEPOINT в SQLite3 в том случае, если транзакцию нужно откатить и завершить, как это было, когда мы рассматривали &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-9-3-komanda-rollback-v-bazax-dannyx-sqlite-operator-rollback-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;команду ROLLBACK TRANSACTION&lt;/a&gt;.&lt;/p&gt;
  &lt;pre id=&quot;wKV9&quot; data-lang=&quot;sql&quot;&gt;--Начинаем транзакцию с именем transact1

SAVEPOINT  transact1;

/*
 * Выберем первых 10 записей из таблицы City
 * (в результате мы получим записи с 3
 * по 12, т.к. ранее мы уже удалили запись с id =2)
 */

SELECT * FROM city LIMIT 10;

-- Удаляем третью строку из таблицы city

DELETE FROM city WHERE  id = 3;

-- Посмотрим на первых 10 записей и увидим, что вывелись записи с 4 по 13

SELECT * FROM city LIMIT 10;

/*
 * Пока вы не выполните команду ROLLBACK,
 * транзакция не будет завершена, а вы
 * будете видеть все изменения
 */
 
ROLLBACK;&lt;/pre&gt;
  &lt;p id=&quot;lFZT&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;SsnR&quot;&gt;А теперь давайте посмотрим, что произошло с нашей базой данных после завершения транзакции:&lt;/p&gt;
  &lt;pre id=&quot;iAPz&quot; data-lang=&quot;sql&quot;&gt;/*
 * Посмотрим на первых 10 записей после подтверждения транзакции,
 * вы увидите записи с 3 по 12
 */
 
SELECT * FROM city LIMIT 10;&lt;/pre&gt;
  &lt;p id=&quot;7aDf&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;U6GN&quot;&gt;Так работает команда SAVEPOINT в базах данных SQLite3 при завершении транзакции с откатом. Давайте теперь посмотрим, как работает оператор SAVEPOINT в SQLite3 в том случае, если транзакцию нужно откатить, но не завершить.&lt;/p&gt;
  &lt;pre id=&quot;p9qK&quot; data-lang=&quot;sql&quot;&gt;--Начинаем транзакцию с именем transact1

SAVEPOINT  transact1;

/*
 * Выберем первых 10 записей из таблицы City
 * (в результате мы получим записи с 3
 * по 12, т.к. ранее мы уже удалили запись с id =2)
 */
 
SELECT * FROM city LIMIT 10;

-- Удаляем третью строку из таблицы city

DELETE FROM city WHERE  id = 3;

-- Посмотрим на первых 10 записей и увидим, что вывелись записи с 4 по 13

SELECT * FROM city LIMIT 10;

/*
 * Пока вы не выполните команду ROLLBACK TRANSACTION TO SAVEPOINT,
 * отката изменений не произойдет, и вы будете видеть все изменения
 */
 
ROLLBACK TRANSACTION TO SAVEPOINT transact1;

/*
 * Посмотрим на первых 10 записей после подтверждения транзакции,
 * вы увидите записи с 3 по 12
 */
 
SELECT * FROM city LIMIT 10;&lt;/pre&gt;
  &lt;p id=&quot;gMve&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;rTYx&quot;&gt;Хочу обратить ваше внимание на то, что последний запрос SELECT будет выполняться в рамках транзакции transact1, так как мы сделали откат до метки transact1, то есть отменили все запросы, начиная с SAVEPOINT transact1, но транзакцию не завершили. Так же хочу обратить ваше внимание на следующий момент, когда я писал о SAVEPOINT я использовал два термина: первый — команда, второй -оператор. Первый термин правильный с формальной точки зрения, второй более популярный среди русскоязычных разработчиков. Про SQL операторы на моем блоге есть отдельная статья.&lt;/p&gt;

</content></entry><entry><id>sqlite:CREATE_TABLE</id><link rel="alternate" type="text/html" href="https://teletype.in/@sqlite/CREATE_TABLE?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=sqlite"></link><title>Часть 10.1: Создание таблиц в базах данных SQLite</title><published>2022-01-03T14:21:13.055Z</published><updated>2022-01-05T04:59:56.185Z</updated><category term="komandy" label="Команды"></category><summary type="html">&lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/create-table-1.gif&quot;&gt;Давайте повторим команду CREATE TABLE и посмотрим, как можно создавать таблицы в базах данных SQLite. Сперва вспомним общий синтаксис создания таблиц в SQLite, он показан на рисунке ниже.</summary><content type="html">
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#aiKT&quot;&gt;Синтаксис создания таблиц в базе данных SQLite3&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#4GfN&quot;&gt;Создания таблицы в базе данных SQLite без описания столбцов&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#tJb9&quot;&gt;Создание таблицы в базе данных SQLite3 с описанием столбцов и ограничениями&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#qrn3&quot;&gt;Создание таблицы в базе данных SQLite с использованием квалификатора&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#IkIT&quot;&gt;Проверить и создать таблицу в базе данных, если она не существует&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#IpLc&quot;&gt;Создание временных таблиц в базе данных SQLite3&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#gMB9&quot;&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#w75B&quot;&gt;Создание таблиц в базе данных SQLIte по запросу SELECT&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;h3 id=&quot;aiKT&quot;&gt;Синтаксис создания таблиц в базе данных SQLite3&lt;/h3&gt;
  &lt;p id=&quot;3XGe&quot;&gt;Давайте повторим &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-6-1-komanda-create-v-sqlite3-ddl-operator-create.html&quot; target=&quot;_blank&quot;&gt;команду CREATE TABLE&lt;/a&gt; и посмотрим, как можно создавать таблицы в базах данных SQLite. Сперва вспомним общий синтаксис создания таблиц в SQLite, он показан на рисунке ниже.&lt;/p&gt;
  &lt;figure id=&quot;9kRk&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/create-table-1.gif&quot; width=&quot;670&quot; /&gt;
    &lt;figcaption&gt;Синтаксис создания таблицы в базе данных SQLite&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NfKu&quot;&gt;Обратите внимание: создавать таблицы в SQLite мы можем р азличным образом, но любое предложение для создания таблицы в SQLite начинается с CREATE TABLE. Если мы хотим создать временную таблицу в базе данных SQLite, то необходимо использовать ключевое слово TEMP или TEMPORARY. Хочу обратить ваше внимание на то, что имена таблиц должны быть уникальны во всей &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/bazy-dannyx-vidy-i-tipy-baz-dannyx-struktura-relyacionnyx-baz-dannyx-proektirovanie-baz-dannyx-setevye-i-ierarxicheskie-bazy-dannyx.html&quot; target=&quot;_blank&quot;&gt;базе данных&lt;/a&gt;, поэтому, если вы создаете таблицу, но у вас есть подозрение, что таблица с таким именем существует, то можете использовать конструкцию IF NOT EXISTS, таким образом SQLite сначала проверит: существует ли таблица с таким именем, а уже затем создаст новую, если таблицы с таким именем нет. В базах данных SQLite вы можете создавать таблицы, используя так называемый квалификатор: полное имя таблицы. Для этого, перед именем таблицы вам следует указать имя базы данных, в которой вы хотите создать таблицу.&lt;/p&gt;
  &lt;p id=&quot;aioc&quot;&gt;Дальше у вас появляется два варианта для создания таблицы: первый вариант создания таблицы в базах данных SQLite заключается в том, чтобы перечислить столбцы, второй вариант создания таблицы заключается в использование ключевого слова AS и команды SELECT. Давайте посмотрим, на общий принцип создания таблиц в SQLite при первом варианте: в круглых скобках, после имени таблицы необходимо указать имена столбцов, &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/tema-5-tipy-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;типы данных для столбцов&lt;/a&gt; (при необходимости, так как SQLite позволяет создавать таблицы, не указывая тип данных столбца) и ограничения для поддержания целостности данных, о которых мы поговорим в следующей теме.&lt;/p&gt;
  &lt;p id=&quot;B02k&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;4GfN&quot;&gt;Создания таблицы в базе данных SQLite без описания столбцов&lt;/h3&gt;
  &lt;p id=&quot;lWa1&quot;&gt;Создание таблицы в базе данных SQLite без указания типа данных (на самом деле &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-1-obshhaya-informaciya-o-tipax-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;в SQLite нет типов данных&lt;/a&gt;, а есть классы данных) для столбца выглядит следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;j7gx&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table1 (a, b, c, d);&lt;/pre&gt;
  &lt;p id=&quot;zD30&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;qQRC&quot;&gt;Как вы видите, в данном случае мы создадим таблицу с именем table1, в которой четыре столбца: a, b, c, d. Для столбцов в данном случае не указан &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-2-klassy-dannyx-vmesto-tipov-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;класс данных&lt;/a&gt;, а так же не указаны ограничения, которые нужны для поддержания целостности данных.&lt;/p&gt;
  &lt;p id=&quot;uXsI&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;tJb9&quot;&gt;Создание таблицы в базе данных SQLite3 с описанием столбцов и ограничениями&lt;/h3&gt;
  &lt;p id=&quot;0KXB&quot;&gt;SQLite3 дает возможность указывать &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-4-affinirovannye-tipy-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;аффинированный тип данных для столбца&lt;/a&gt;, а так же ограничения уровня столбца и уровня таблицы. Давайте рассмотрим несколько примеров &lt;strong&gt;создания таблиц в SQLite&lt;/strong&gt; с явным указанием типов данных и ограничениями.&lt;/p&gt;
  &lt;pre id=&quot;46xe&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table2 (
  a INTEGER PRIMARY KEY NOT NULL,
  b TEXT  UNIQUE NOT NULL,
  c REAL NOT NULL
);&lt;/pre&gt;
  &lt;p id=&quot;Ot73&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;iLn3&quot;&gt;В первом примере мы создали таблицу table2 со столбцами a, b, c. И задали для каждого столбца описание: указали тип данных и ограничения: NOT NULL и PRIMARY KEY. Обратите внимание на терминологию SQLite знать не знает про реляционную базу данных и о том, что такое &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-3-3-klyuchi-i-klyuchevye-atributy-v-bazax-dannyx.html&quot; target=&quot;_blank&quot;&gt;ключ или ключевой атрибут&lt;/a&gt;. Для SQLite первичный ключ – это ограничение, то есть некоторое правило, которое нельзя нарушать. Обратите внимание на то, что параметры столбца разделяются между собой пробелами. А теперь давайте посмотрим второй пример создания таблицы в базе данных SQLite с указанием типов данных и ограничений:&lt;/p&gt;
  &lt;pre id=&quot;fWeX&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table3 (
  a INTEGER NOT NULL,
  b TEXT  UNIQUE NOT NULL,
  c REAL NOT NULL,
  PRIMARY KEY(a)
);&lt;/pre&gt;
  &lt;p id=&quot;jsEb&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;shdf&quot;&gt;В данном случае мы объявили столбец «a» первичным ключом таблицы после описания столбцов, так тоже можно делать. Еще хочу обратить ваше внимание на то, что SQLite при создании таблицы неявно указывает &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-5-sravnenie-dannyx-v-sqlite3-poryadok-sortirovki-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;сравнение данных для столбца&lt;/a&gt;. Если вам нужно явно указать SQLite как нужно сравнивать данные из столбца — используйте ключевое слово COLLATE.&lt;/p&gt;
  &lt;p id=&quot;Aqe1&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;qrn3&quot;&gt;Создание таблицы в базе данных SQLite с использованием квалификатора&lt;/h3&gt;
  &lt;p id=&quot;YLk7&quot;&gt;SQLite дает возможность создавать таблицы, используя квалификаторы: полное имя таблицы. Квалификатор состоит из имени базы данных, в которой таблица будет создана, и имени самой таблица, давайте взглянем на пример:&lt;/p&gt;
  &lt;pre id=&quot;mQGQ&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE world.table4 (
  a INTEGER NOT NULL,
  b TEXT UNIQUE NOT NULL,
  c REAL NOT NULL,
  PRIMARY KEY(a)
);&lt;/pre&gt;
  &lt;p id=&quot;zkwS&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;dF7c&quot;&gt;Синтаксис создания таблицы с использованием квалификатора ничем не отличается от предыдущих примеров, но вместо имени таблицы теперь использован квалификатор: world.table4.&lt;/p&gt;
  &lt;p id=&quot;risq&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;IkIT&quot;&gt;Проверить и создать таблицу в базе данных, если она не существует&lt;/h3&gt;
  &lt;p id=&quot;HNa2&quot;&gt;Когда вы создаете новые таблицы, то не всегда знаете структура базы данных, а, соответственно, не всегда знаете имена уже существующих таблиц, поэтому SQLite позволяет проверять имена таблиц на уникальность перед их созданием, для этого используется конструкция IF NOT EXISTS:&lt;/p&gt;
  &lt;pre id=&quot;PPH0&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE IF NOT EXISTS TABLE table5 (
  a INTEGER NOT NULL,
  b TEXT  UNIQUE NOT NULL,
  c REAL NOT NULL,
  PRIMARY KEY(a)
);&lt;/pre&gt;
  &lt;p id=&quot;Nu4z&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;OIK4&quot;&gt;Если таблицы с именем table5 в базе данных не будет, то SQLite создаст эту таблицу, если таблица table5 будет в базе данных, то таблица создана не будет.&lt;/p&gt;
  &lt;p id=&quot;3umn&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;IpLc&quot;&gt;Создание временных таблиц в базе данных SQLite3&lt;/h3&gt;
  &lt;p id=&quot;lrxx&quot;&gt;Помимо обычных таблиц, &lt;strong&gt;SQLite позволяет создавать в базе данных временные таблицы&lt;/strong&gt;. Временные таблицы в SQLite создаются в оперативной памяти и доступны только для того клиента, который эту таблицу создал, другие пользователи просто не увидят временную таблицу. Временные таблицы очень удобно использовать для сохранения промежуточных результатов, чтобы не писать простыню из SELECT. Давайте посмотрим пример создания временной таблицы в SQLite:&lt;/p&gt;
  &lt;pre id=&quot;I1pr&quot; data-lang=&quot;sql&quot;&gt;CREATE TEMP TABLE table6 (
  a INTEGER NOT NULL,
  b TEXT  UNIQUE NOT NULL,
  c REAL NOT NULL,
  PRIMARY KEY(a)
);&lt;/pre&gt;
  &lt;p id=&quot;i6JH&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;l4wA&quot;&gt;Создание временных таблиц в SQLite ничем не отличается от создания обычных таблиц за исключением ключевого слова TEMP. Обратите внимание: вы легко можете отличить временную таблицу от обычной, воспользовавшись командой SQLite .tables.&lt;/p&gt;
  &lt;pre id=&quot;UywN&quot; data-lang=&quot;sql&quot;&gt;-- Посмотрим временную таблицу

.tables&lt;/pre&gt;
  &lt;p id=&quot;brBA&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;wU47&quot;&gt;Временные таблицы в SQLite имеют пометку temp. Вместо ключевого слова TEMP для создания временной таблицы можно использовать ключевое слово TEMPORARY:&lt;/p&gt;
  &lt;pre id=&quot;dGXR&quot; data-lang=&quot;sql&quot;&gt;CREATE TEMPORARY TABLE table7 (
  a INTEGER NOT NULL,
  b TEXT  UNIQUE NOT NULL,
  c REAL NOT NULL,
  PRIMARY KEY(a)
);&lt;/pre&gt;
  &lt;p id=&quot;IICo&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;AtA9&quot;&gt;И затем проверить, что временная таблица действительно создалась.&lt;/p&gt;
  &lt;pre id=&quot;X70Z&quot; data-lang=&quot;sql&quot;&gt;-- Посмотрим временную таблицу

.tables&lt;/pre&gt;
  &lt;h3 id=&quot;gMB9&quot;&gt;&lt;/h3&gt;
  &lt;h3 id=&quot;w75B&quot;&gt;Создание таблиц в базе данных SQLIte по запросу SELECT&lt;/h3&gt;
  &lt;p id=&quot;Du5O&quot;&gt;Теперь посмотрим на второй вариант создания таблиц в SQLite, который заключается в использование ключевого слова AS и команды SELECT. Всё очень просто: сперва вы пишите CREATE TABLE, затем указываете имя таблицы, вместо имени можно использовать квалификатор, затем идет ключевое слово AS, после которого идет подзапрос SELECT, который, на самом деле, может быть сколь угодно длинным.&lt;/p&gt;
  &lt;pre id=&quot;46nh&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE IF NOT EXISTS table8 AS

SELECT id, name, population FROM city LIMIT 15;&lt;/pre&gt;
  &lt;p id=&quot;tMfw&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;EOgs&quot;&gt;После чего можно проверить, что таблица в базе данных была действительно создана, воспользовавшись командой SELECT.&lt;/p&gt;
  &lt;pre id=&quot;k3Gy&quot; data-lang=&quot;sql&quot;&gt;SELECT * FROM table8;&lt;/pre&gt;
  &lt;p id=&quot;jVki&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;gItm&quot;&gt;А потом попробуйте воспользоваться командой .schema (на моем блоге есть публикация обо всех &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-2-4-drugie-poleznye-komandy-sqlite3-dot-komandy-terminala-sqlite3.html&quot; target=&quot;_blank&quot;&gt;полезных командах шелла SQLite3&lt;/a&gt;), чтобы посмотреть каким запросом была создана таблица в SQLite.&lt;/p&gt;
  &lt;pre id=&quot;zQ1e&quot; data-lang=&quot;sql&quot;&gt;.schema table8&lt;/pre&gt;
  &lt;p id=&quot;DNYB&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;MWMT&quot;&gt;Хочу обратить ваше внимание на то, что ключевое слово AS можно использовать не только для создания таблицы, но и для указания псевдонима имени столбца при создании таблицы, давайте это посмотрим:&lt;/p&gt;
  &lt;pre id=&quot;zUO2&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE IF NOT EXISTS table9 AS

SELECT id AS &amp;#x27;Nomer&amp;#x27;, name AS &amp;#x27;Gorod&amp;#x27;, population
AS &amp;#x27;naselenie&amp;#x27; FROM city LIMIT 15;&lt;/pre&gt;
  &lt;p id=&quot;LviA&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;rbPD&quot;&gt;Затем выполним SELECT, чтобы убедиться в том, что имена столбцов будут отображаться, как Nomer, Gorod и naselenie.&lt;/p&gt;
  &lt;pre id=&quot;gY9m&quot; data-lang=&quot;sql&quot;&gt;SELECT * FROM table9;&lt;/pre&gt;
  &lt;p id=&quot;kwvv&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;de5u&quot;&gt;И посмотрим схему только что созданной таблицы.&lt;/p&gt;
  &lt;pre id=&quot;CKy0&quot; data-lang=&quot;sql&quot;&gt;.schema table9&lt;/pre&gt;
  &lt;p id=&quot;APcZ&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;WH4l&quot;&gt;Мы закончили рассмотрение &lt;strong&gt;создания таблиц в базах данных SQLite&lt;/strong&gt;. Мне остается только добавить, что для некоторых примеров создания таблиц я использовал тестовую базу данных World.&lt;/p&gt;

</content></entry><entry><id>sqlite:PRIMARY_KEY</id><link rel="alternate" type="text/html" href="https://teletype.in/@sqlite/PRIMARY_KEY?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=sqlite"></link><title>Часть 11.3: Первичные ключи в базах данных SQLite: PRIMARY KEY. Ограничение первичного ключа</title><published>2022-01-03T09:26:42.952Z</published><updated>2022-01-05T05:00:07.360Z</updated><summary type="html">В теории баз данных ключ или ключевой атрибут — это столбец, который позволяет однозначно идентифицировать таблицу в базе данных. На практике, ни одна СУБД в мире не знает о таком столбце и не знает теории баз данных. На практике есть первичный ключ, который является правилом, которое SQLite ни когда не нарушит. SQLite будет следить всегда за тем, чтобы в столбце PRIMARY KEY были всегда уникальные и вечные значения.</summary><content type="html">
  &lt;nav&gt;
    &lt;ul&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#L2KP&quot;&gt;Первичный ключ, как ограничение уровня таблицы в базах данных SQLite. PRIMARY KEY в SQLIte3&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#2aJz&quot;&gt;Пример использования первичного ключа в SQLite. Пример PRIMARY KEY в SQLite&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#6k2p&quot;&gt;PRIMARY KEY, как индекс в базах данных&lt;/a&gt;&lt;/li&gt;
      &lt;li class=&quot;m_level_1&quot;&gt;&lt;a href=&quot;#SqVt&quot;&gt;Составной первичный ключ в базах данных SQLite&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/nav&gt;
  &lt;p id=&quot;iguz&quot;&gt;В теории баз данных ключ или ключевой атрибут — это столбец, который позволяет однозначно идентифицировать таблицу в базе данных. На практике, ни одна СУБД в мире не знает о таком столбце и не знает теории баз данных. На практике есть первичный ключ, который является правилом, которое SQLite ни когда не нарушит. SQLite будет следить всегда за тем, чтобы в столбце PRIMARY KEY были всегда уникальные и вечные значения.&lt;/p&gt;
  &lt;p id=&quot;okKc&quot;&gt;В этой записи мы рассмотрим ограничения первичного ключа в базах данных SQLite в теории и на практике, так же узнаем, почему первичный ключ это не только правило базы данных, но еще и индекс, а так же поговорим о том, как реализовать составной первичный ключ для таблицы базы данных SQLite3&lt;/p&gt;
  &lt;p id=&quot;CuP9&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;L2KP&quot;&gt;Первичный ключ, как ограничение уровня таблицы в базах данных SQLite. PRIMARY KEY в SQLIte3&lt;/h3&gt;
  &lt;p id=&quot;LjGM&quot;&gt;Первичный ключ, это не только &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-3-3-klyuchi-i-klyuchevye-atributy-v-bazax-dannyx.html&quot; target=&quot;_blank&quot;&gt;ключевой атрибут&lt;/a&gt;, который идентифицирует таблицу в базе данных и даже не только обязательное условие &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-3-7-vtoraya-normalnaya-forma-2nf.html&quot; target=&quot;_blank&quot;&gt;второй нормальной формы&lt;/a&gt;, а, соответственно, и &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-3-8-tretya-normalnaya-forma-3nf.html&quot; target=&quot;_blank&quot;&gt;третьей нормальной формы&lt;/a&gt;. &lt;strong&gt;Первичный ключ или столбец PRIMARY KEY&lt;/strong&gt; – это &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-11-2-ogranicheniya-urovnya-tablicy-v-bazax-dannyx-sqlite3.html&quot; target=&quot;_blank&quot;&gt;ограничение уровня таблицы&lt;/a&gt; для любой &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/arxitektura-subd-arxitektura-baz-dannyx-logicheskaya-struktura-subd-opisanie-dannyx-v-baze-dannyx-bazy-dannyx-sxema-dannyx.html&quot; target=&quot;_blank&quot;&gt;реляционной СУБД&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;RvKh&quot;&gt;Ограничение уровня таблицы – это правило, которое никогда не должна нарушать ни одна СУБД и не должна никому давать это делать. Первичный ключ или &lt;em&gt;PRIMARY KEY&lt;/em&gt; в базах данных SQLite – это столбец, значения которого должны быть уникальными и вечными, и что бы не произошло, что бы не случилось, SQLite никогда не нарушит правило уникальности и вечности первичного ключа.&lt;/p&gt;
  &lt;p id=&quot;TOFe&quot;&gt;Если мы задали первичный ключ для таблицы при помощи PRIMARY KEY, то, во-первых, мы сами должны заботиться об уникальности и вечности, во-вторых, SQLite будет делать это за нас. Если вы видите, что значения в столбце повторяющиеся и SQLite не дает вам их добавить, то, вероятнее всего, вы ошиблись при &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-3-9-proektirovanie-baz-dannyx-teoriya-kompromissy-logika-zdravyj-smysl-i-predmetnaya-oblast.html&quot; target=&quot;_blank&quot;&gt;проектировании базы данных&lt;/a&gt; и назначили не тот столбец в качестве PRIMARY KEY.&lt;/p&gt;
  &lt;p id=&quot;6Di7&quot;&gt;Когда мы создаем первичный ключ, как ограничение таблицы, то вместо PRIMARY KEY мы вправе использовать конструкцию UNIQUE KEY, SQLite это позволяет и никаких проблем с таким подходом у вас не будет.&lt;/p&gt;
  &lt;p id=&quot;z9Un&quot;&gt;Помимо всего прочего, первичный ключ в базе данных SQLite, вернее столбец, который мы назначили, как PRIMARY KEY, является еще и индексом таблицы. Благодаря индексам таблицы операция выборки данных из базы данных при помощи &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-1-komanda-select-v-sqlite3-operator-select-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;команды SELECT&lt;/a&gt; происходит значительно быстрее, но место на диске &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/bazy-dannyx-vidy-i-tipy-baz-dannyx-struktura-relyacionnyx-baz-dannyx-proektirovanie-baz-dannyx-setevye-i-ierarxicheskie-bazy-dannyx.html&quot; target=&quot;_blank&quot;&gt;база данных&lt;/a&gt; начинает занимать больше&lt;/p&gt;
  &lt;p id=&quot;Prg6&quot;&gt;Вывод: первичный ключ в базах данных SQLite3 или PRIMARY KEY – это правила, которые нельзя нарушать: правила уникальности и вечности значений столбца PRIMARY KEY. Так же первичный ключ является индексом таблицы в базе данных SQLite. Столбец, который объявлен, как PRIMARY KEY – это индекс, которому мы можем даже дать имя.&lt;/p&gt;
  &lt;p id=&quot;O76N&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;2aJz&quot;&gt;Пример использования первичного ключа в SQLite. Пример PRIMARY KEY в SQLite&lt;/h3&gt;
  &lt;p id=&quot;JzSY&quot;&gt;Мы разобрались в теории, что собой представляет первичный ключ в реляционных базах данных, а также выяснили, что для создания первичного ключа необходимо использовать конструкцию PRIMARY KEY, тогда SQLite3 поймет, что данный столбец является первичным ключом, а его значения должны быть уникальными и вечными.&lt;/p&gt;
  &lt;p id=&quot;ZHFY&quot;&gt;Давайте теперь на практике посмотрим, как первичный ключ может &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/tema-11-obespechenie-celostnosti-dannyx-v-bazax-dannyx-sqlite3.html&quot; target=&quot;_blank&quot;&gt;обеспечить целостность данных в базе данных&lt;/a&gt; и посмотрим, как в SQLite можно объявить столбец с ограничением PRIMARY KEY.&lt;/p&gt;
  &lt;p id=&quot;ckf9&quot;&gt;&lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-10-1-sozdanie-tablic-v-bazax-dannyx-sqlite.html&quot; target=&quot;_blank&quot;&gt;Создадим таблицу в базе данных&lt;/a&gt; с именем table1 при помощи &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-6-1-komanda-create-v-sqlite3-ddl-operator-create.html&quot; target=&quot;_blank&quot;&gt;команды CREATE&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;LtNw&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table1 (
 a INTEGER PRIMARY KEY,
 b TEXT NOT NULL,
 c REAL
);&lt;/pre&gt;
  &lt;p id=&quot;o9Cj&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;LHJ6&quot;&gt;Первый столбец мы объявили первичным ключом таблицы table1 при помощи ключевой фразы PRIMARY KEY. Теперь давайте смотреть, как SQLite будет относиться к значениям, которые мы будем добавлять в первый столбец. Чтобы &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-10-4-dobavlenie-dannyx-i-strok-v-tablicy-baz-dannyx-sqlite.html&quot; target=&quot;_blank&quot;&gt;добавить строку в таблицу&lt;/a&gt;, нужно воспользоваться &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-2-komanda-insert-v-sqlite3-operator-insert-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;командой INSERT&lt;/a&gt;.&lt;/p&gt;
  &lt;pre id=&quot;DHiO&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table1 (NULL, &amp;#x27;Hello, World!&amp;#x27;, 0.2);&lt;/pre&gt;
  &lt;p id=&quot;34zt&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;YJHV&quot;&gt;Мы пробуем добавить значение NULL в столбец PRIMARY KEY, и у нас ничего не получается, первичный ключ не может иметь значение NULL, так как значение NULL нельзя ни с чем сравнить однозначно. А ошибку SQLite напишет такую: Error: near «NULL»: syntax error. Давайте теперь попробуем «обмануть» SQLite и добавим две строки:&lt;/p&gt;
  &lt;pre id=&quot;Mcm4&quot; data-lang=&quot;sql&quot;&gt;-- Добавляем две строки в таблицу,
-- не указывая значение для столбца PRIMARY KEY

INSERT INTO table1 (b, c) VALUES (&amp;#x27;какой-то текст&amp;#x27;, 0.5);
INSERT INTO table1 (b, c) VALUES (&amp;#x27;какой-то текст&amp;#x27;, 0.7);&lt;/pre&gt;
  &lt;p id=&quot;CQld&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;7vNT&quot;&gt;SQLite добавляет эти строки в таблицу, хотя мы не указывали значение для первого столбца, давайте посмотрим на результат, сделав выборку данных из базы данных при помощи команды SELECT:&lt;/p&gt;
  &lt;pre id=&quot;PAtU&quot; data-lang=&quot;sql&quot;&gt;-- Делаем выборку из базы данных и смотрим результат

SELECT*FROM table1;

1|какой-то текст|0.5
2|какой-то текст|0.7&lt;/pre&gt;
  &lt;p id=&quot;iUET&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;01wE&quot;&gt;Как видите, в SQLite3 необязательно указывать &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-11-1-ogranicheniya-urovnya-stolbca-v-bazax-dannyx-sqlite.html&quot; target=&quot;_blank&quot;&gt;ограничение уровня столбца AUTOINCREMENT&lt;/a&gt; для столбца с &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-4-affinirovannye-tipy-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;аффинированным типом данных&lt;/a&gt; INTEGER, который объявлен, как первичный ключ (PRIMARY KEY). А теперь попробуем добавить строку со значение a = 2 в таблицу table1 (это значение уже есть в таблице и SQLite не должна нам дать возможность добавить такую строку ).&lt;/p&gt;
  &lt;pre id=&quot;ke3M&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table1 (2, &amp;#x27;Hello, World!&amp;#x27;, 0.2);&lt;/pre&gt;
  &lt;p id=&quot;o0uv&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;doYX&quot;&gt;SQLite заблокировала попытку добавления строки со значение a =2, так как правилом первичного ключа является его уникальность. Давайте подсунем SQLite в столбец «a» строку ‘2’. Тип данных будет другим, но, как мы знаем &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-1-obshhaya-informaciya-o-tipax-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;SQLite – это СУБД с динамической типизацией данных&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;9gZO&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table1 (&amp;#x27;2&amp;#x27;, &amp;#x27;Hello, World!&amp;#x27;, 0.2);&lt;/pre&gt;
  &lt;p id=&quot;ZnQv&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;xaLE&quot;&gt;Да, та же самая ошибка: Error: near «0.2»: syntax error. В данном случае, перед тем, как записать значение в таблицу SQLite его преобразовало в число, так как мы объявили для столбца «а» &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-2-klassy-dannyx-vmesto-tipov-dannyx-v-sqlite3.html&quot; target=&quot;_blank&quot;&gt;класс данных&lt;/a&gt; INTEGER, а затем сравнила значения из таблицы с тем, что мы хотели добавить, после чего заблокировала операцию добавления данных.&lt;/p&gt;
  &lt;p id=&quot;VYDr&quot;&gt;Теперь давайте попробуем изменить значение столбца «а». Для изменения данных в базе данных SQLite есть специальная &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-7-3-komanda-update-v-sqlite3-operator-update-v-sqlite.html&quot; target=&quot;_blank&quot;&gt;команда UPDATE&lt;/a&gt;, воспользуемся ей:&lt;/p&gt;
  &lt;pre id=&quot;sP5t&quot; data-lang=&quot;sql&quot;&gt;UPDATE table1 SET a = 2 WHERE c = 0.5;
UPDATE table1 SET a = 3 WHERE c = 0.7;&lt;/pre&gt;
  &lt;p id=&quot;76iQ&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;2cT4&quot;&gt;Когда мы первый раз используем команду UPDATE, SQLite заблокирует нам эту операцию, так как первичный ключ должен быть уникальным, а значение 2 уже есть в столбце «а». Второй UPDATE будет выполнен, так как наша таблица еще не связана с другими таблицами и здесь не произойдет нарушение правила уникальности. Убедимся в этом при помощи команды SELECT:&lt;/p&gt;
  &lt;pre id=&quot;ChV3&quot; data-lang=&quot;sql&quot;&gt;-- Делаем выборку, чтобы убедиться, что второй UPDATE сработал

SELECT * FROM table1;

1|какой-то текст|0.5
3|какой-то текст|0.7&lt;/pre&gt;
  &lt;p id=&quot;ib1F&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;DySS&quot;&gt;Если интересно, то при выполнении первого UPDATE, SQLite выдала ошибку: Error: UNIQUE constraint failed: table1.a. Но давайте немного изменим пример, пусть первичный ключ нашей таблицы будет с аффинированным типом данных TEXT. Создадим таблицу table2:&lt;/p&gt;
  &lt;pre id=&quot;Z1Zt&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table2 (
  a TEXT PRIMARY KEY,
  b TEXT NOT NULL,
  c REAL
);&lt;/pre&gt;
  &lt;p id=&quot;0wdt&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;FuxD&quot;&gt;Структура таблицы та же, что и в первом случае, но теперь &lt;strong&gt;столбец PRIMARY KEY&lt;/strong&gt; имеет класс данных TEXT. Выполним первый INSERT из примера с типом данных INTEGER:&lt;/p&gt;
  &lt;pre id=&quot;qwHp&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table2 (NULL, &amp;#x27;Hello, World!&amp;#x27;, 0.2);&lt;/pre&gt;
  &lt;p id=&quot;wCeq&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;ifIy&quot;&gt;&lt;strong&gt;Ограничение первичного ключа сработало&lt;/strong&gt;, мы получили ошибку, а это значит, что SQLite не добавила значение NULL в столбец PRIMARY KEY с типом данных TEXT.Выполним второй INSERT, не указав никаких значений для первичного ключа:&lt;/p&gt;
  &lt;pre id=&quot;dK1U&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table2 (b, c) VALUES (&amp;#x27;какой-то текст&amp;#x27;, 0.5);&lt;/pre&gt;
  &lt;p id=&quot;IAk4&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;61vf&quot;&gt;SQLite добавила строку в базу данных, несмотря на то, что мы не указывали никаких значений для столбца PRIMARY KEY, давайте сделаем SELECT:&lt;/p&gt;
  &lt;pre id=&quot;g6vP&quot; data-lang=&quot;sql&quot;&gt;SELECT * FROM table2;

|какой-то текст|0.5

SELECT typeof(a), typeof(b), typeof(c) FROM table2;

null|text|real&lt;/pre&gt;
  &lt;p id=&quot;3nO2&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;GurF&quot;&gt;Будьте аккуратны, если вы объявляете первичным ключом столбец с типом данных TEXT при использовании SQLite3, если вы забудете добавить значение, то автоматически добавится значение NULL, в этом случае нужно пользоваться &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-11-1-ogranicheniya-urovnya-stolbca-v-bazax-dannyx-sqlite.html&quot; target=&quot;_blank&quot;&gt;ограничение уровня столбца NOT NULL&lt;/a&gt;, чтобы избежать таких ошибок.&lt;/p&gt;
  &lt;p id=&quot;39pO&quot;&gt;А теперь в таблицу table2, попробуем добавить две строки:&lt;/p&gt;
  &lt;pre id=&quot;61hc&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table2 (a,b,c) VALUES (5, &amp;#x27;Hello, World!&amp;#x27;, 0.2);
INSERT INTO table2 VALUES (&amp;#x27;5&amp;#x27;, &amp;#x27;Hello, World!&amp;#x27;, 55);&lt;/pre&gt;
  &lt;p id=&quot;yf9R&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;uYcs&quot;&gt;Первая строка будет добавлена, во второй строке мы получим ошибку. Это произошло из-за того, что SQLite перед тем, как добавить первую строку, преобразовал число 5 в строку ‘5’, поэтому на вторую строку было наложено правило уникальности первичного ключа.&lt;/p&gt;
  &lt;p id=&quot;H8qu&quot;&gt;А теперь давайте создадим таблицу table3 с первичным ключом PRIMARY KEY, для которого мы не станем указывать тип данных и попробуем повторить последний эксперимент:&lt;/p&gt;
  &lt;pre id=&quot;XQn9&quot; data-lang=&quot;sql&quot;&gt;-- Создаем таблицу с первичным ключом, но без типов данных

CREATE TABLE table3 (
  a PRIMARY KEY,
  b NOT NULL,
  c
);

-- Добавляем в эту таблицу две строки

INSERT INTO table3 VALUES (&amp;#x27;5&amp;#x27;, &amp;#x27;Hello, World!&amp;#x27;, 55);
INSERT INTO table3 (a,b,c) VALUES (5, &amp;#x27;Hello, World!&amp;#x27;, 0.2);&lt;/pre&gt;
  &lt;p id=&quot;qFuH&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;umSk&quot;&gt;Все команды будут выполнены успешно, так как для столбца, объявленного, как PRIMARY KEY не был указан аффинированный тип данных, а значение 5 и ‘5’ разные значения, так как первое – это число, а второе – строка.&lt;/p&gt;
  &lt;h3 id=&quot;6k2p&quot;&gt;PRIMARY KEY, как индекс в базах данных&lt;/h3&gt;
  &lt;p id=&quot;hpN5&quot;&gt;Мы утверждаем, что &lt;strong&gt;первичный ключ – это ограничение уровня таблицы&lt;/strong&gt;, но столбец PRIMARY KEY мы объявляем, как ограничение уровня столбца, на самом деле, такая форма записи не совсем правильная. Давайте разберемся, почему это так и как нужно делать правильно. Во-первых, стоит сказать, что ограничения уровня таблицы – это такие же объекты баз данных, как и сами таблицы и мы можем им давать имена, которые должны быть уникальны во всей базе данных.&lt;/p&gt;
  &lt;p id=&quot;RHLW&quot;&gt;А теперь давайте объявим столбец PRIMARY KEY, как ограничение уровня таблицы:&lt;/p&gt;
  &lt;pre id=&quot;0JJd&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table4(
  a INTEGER,
  b TEXT NOT NULL,
  c REAL,
  PRIMARY KEY (a)
);&lt;/pre&gt;
  &lt;p id=&quot;zfYB&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;uqAq&quot;&gt;Напишите команду .schema, чтобы увидеть, какой запрос создал данную таблицу. Но, мы утверждали, что первичный ключ – это ни что иное, как индекс таблицы в базе данных SQLite3 и что у столбца PRIMARY KEY может быть имя, давайте этом посмотрим:&lt;/p&gt;
  &lt;pre id=&quot;rHFs&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table5(
  a INTEGER,
  b TEXT NOT NULL,
  c REAL,
  CONSTRAINT ixpk PRIMARY KEY (a)
);&lt;/pre&gt;
  &lt;p id=&quot;4wNo&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;132T&quot;&gt;Теперь мы создали первичный ключ с именем ixpk, этот первичный ключ является индексом таблицы базы данных table5, в этом легко убедиться, воспользуйтесь командой SELECT, которая покажет все индексы в базе данных SQLite:&lt;/p&gt;
  &lt;pre id=&quot;FwQD&quot; data-lang=&quot;sql&quot;&gt;SELECT * FROM sqlite_master WHERE type = &amp;#x27;index&amp;#x27;;&lt;/pre&gt;
  &lt;p id=&quot;NGbp&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;VSXj&quot;&gt;Мы создали первичный ключ, объявив столбец «а», как ограничение уровня таблицы при помощи конструкции &lt;code&gt;CONSTRAINT ixpk PRIMARY KEY (a)&lt;/code&gt; после объявления всех столбцов, но, в то же время, мы создали индекс с именем &lt;code&gt;ixpk&lt;/code&gt; для таблицы &lt;code&gt;table5&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;SxZe&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;SqVt&quot;&gt;Составной первичный ключ в базах данных SQLite&lt;/h3&gt;
  &lt;p id=&quot;QIfA&quot;&gt;Бывают такие ситуации, когда в таблице нет столбца, в котором значения были бы уникальные и при этом нежелательно создавать суррогатный ключ, который бы генерировала СУБД. В этом случае используются &lt;em&gt;составные первичные ключи&lt;/em&gt;. Создать составной первичный ключ в базе данных SQLite очень просто, давайте посмотрим на пример:&lt;/p&gt;
  &lt;pre id=&quot;wBF3&quot; data-lang=&quot;sql&quot;&gt;CREATE TABLE table6(
  a INTEGR NOT NULL,
  b TEXT,
  c REAL,
  CONSTRAINT new_pk PRIMARY KEY (a, b, c)
);&lt;/pre&gt;
  &lt;p id=&quot;k2Kl&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;3QaP&quot;&gt;Мы помним, что первичный ключ должен обладать двумя параметрами: уникальностью и вечностью. По логике вещей, если мы создаем составной первичный ключ, SQLite должна заботиться об уникальности всех трех значений в сумме, а не по отдельности, давайте это проверим:&lt;/p&gt;
  &lt;pre id=&quot;5e5M&quot; data-lang=&quot;sql&quot;&gt;INSERT INTO table6 (a,b,c) VALUES (5, &amp;quot;Hello, World!&amp;quot;, 0.2);
INSERT INTO table6 (a,b,c) VALUES (5, &amp;quot;Hello, World!&amp;quot;, 0.8);
INSERT INTO table6 (a,b,c) VALUES (25, &amp;quot;Hello, World!&amp;quot;, 0.2);
INSERT INTO table6 (a,b,c) VALUES (5, &amp;quot;Hello, World!&amp;quot;, 0.2);&lt;/pre&gt;
  &lt;p id=&quot;fSQt&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;Coiy&quot;&gt;Все команды INSERT, кроме последней, будут выполнены, последний &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-5-sql-zaprosy-klyuchevye-slova-komandy-predlozheniya-i-sintaksis-yazyka-sql.html&quot; target=&quot;_blank&quot;&gt;SQL запрос&lt;/a&gt; INSERT выполнен не будет, так как нарушается правило уникальности, мы же создавали составной первичный ключ, поэтому SQLite проверяет на уникальность все три значения и, если все три значения вместе являются не уникальными, то SQLite не дает добавить такую строку в таблицу.&lt;/p&gt;

</content></entry><entry><id>sqlite:INSERT</id><link rel="alternate" type="text/html" href="https://teletype.in/@sqlite/INSERT?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=sqlite"></link><title>Часть 7.2: Команда INSERT в SQLite3. Оператор INSERT в SQLite3</title><published>2022-01-03T08:55:04.085Z</published><updated>2022-01-05T05:01:19.370Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/70/55/7055b439-a650-4ce7-ab3d-bdccd97c0d8d.jpeg"></media:thumbnail><category term="komandy" label="Команды"></category><summary type="html">&lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/logotypinsert.jpg&quot;&gt;В этой публикации мы посмотрим на синтаксис оператора INSERT в SQLite3 и разберем несколько примеров использования команды INSERT в SQLite3. А для тех, кто еще не знает, скажу, что команда INSERT используется для добавления новых строк в таблицы базы данных.</summary><content type="html">
  &lt;figure id=&quot;w50n&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/logotypinsert.jpg&quot; width=&quot;640&quot; /&gt;
    &lt;figcaption&gt;Команда INSERT в SQLite3. Оператор INSERT в SQLite3&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;VLfy&quot;&gt;В этой публикации мы посмотрим на синтаксис оператора INSERT в SQLite3 и разберем несколько примеров использования команды INSERT в SQLite3. А для тех, кто еще не знает, скажу, что команда INSERT используется для добавления новых строк в таблицы базы данных.&lt;/p&gt;
  &lt;p id=&quot;w655&quot;&gt;&lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/tema-1-biblioteka-sqlite-vstraivaemaya-sistema-upravleniya-bazami-dannyx-sqlite3.html&quot; target=&quot;_blank&quot;&gt;Библиотека SQLite3&lt;/a&gt; позволяет нам добавлять новые строки в таблицы &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/bazy-dannyx-vidy-i-tipy-baz-dannyx-struktura-relyacionnyx-baz-dannyx-proektirovanie-baz-dannyx-setevye-i-ierarxicheskie-bazy-dannyx.html&quot; target=&quot;_blank&quot;&gt;базы данных&lt;/a&gt;. Для добавления новых строк используется команда INSERT, эта команда есть в любой &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/arxitektura-subd-arxitektura-baz-dannyx-logicheskaya-struktura-subd-opisanie-dannyx-v-baze-dannyx-bazy-dannyx-sxema-dannyx.html&quot; target=&quot;_blank&quot;&gt;СУБД&lt;/a&gt;. Добавлять новые &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/chast-3-2-vidy-svyazej-mezhdu-tablicami-v-baze-dannyx-svyazi-v-relyacionnyx-bazax-dannyx-otnosheniya-kortezhi-atributy.html&quot; target=&quot;_blank&quot;&gt;строки&lt;/a&gt; при помощи команды INSERT в SQLite3 можно только в таблицы &lt;a href=&quot;https://zametkinapolyah.ru/zametki-o-mysql/baza-dannyx-wordpress-sajta.html&quot; target=&quot;_blank&quot;&gt;базы данных&lt;/a&gt;. Ниже вы сможете увидеть синтаксис &lt;strong&gt;команды INSERT в SQLite3&lt;/strong&gt;.&lt;/p&gt;
  &lt;figure id=&quot;fOB0&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://zametkinapolyah.ru/wp-content/uploads/2016/06/insert.gif&quot; width=&quot;650&quot; /&gt;
    &lt;figcaption&gt;Синтаксис команды INSERT в SQLite3. Синтаксис оператора INSERT в SQLite3&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;koaS&quot;&gt;Как видите, синтаксис довольно простой: сначала мы говорим СУБД, что хотим добавить строки при помощи ключевого слова INSERT, затем мы указываем в какую таблицу хотим добавить строку при помощи ключевого слова INTO, затем мы указываем имя таблицы и список столбцов, в которые нужно записать новые значения, а затем, при помощи ключевого слова VALUES мы указываем значения через запятую. В принципе, синтаксис оператора &lt;strong&gt;INSERT в SQLite&lt;/strong&gt; не сложный и его легко запомнить.&lt;/p&gt;
  &lt;p id=&quot;ln77&quot;&gt;Примеры использования команды SELECTв SQLite3&lt;br /&gt;Давайте посмотрим несколько примеров использования команды INSERT в SQLite3.&lt;/p&gt;
  &lt;pre id=&quot;x5r0&quot; data-lang=&quot;sql&quot;&gt;-- Создадимпростуютаблицу
CREATETABLEtable1 (a, b,c,d);

-- Добавим несколько значений в таблицу table1 при помощи команды INSERT
INSERT INTO table1  (a, b, c, d)
VALUES (1, &amp;#x27;Петров&amp;#x27;, &amp;#x27;Русский&amp;#x27;, 24);

INSERT INTO table1  (a, b, c, d)
VALUES (2, &amp;#x27;Нурутдинов&amp;#x27;, &amp;#x27;Татарин&amp;#x27;, 28);

INSERT INTO table1  (a, b, c, d)
VALUES (3, &amp;#x27;Иванько&amp;#x27;, &amp;#x27;Украинец&amp;#x27;, 31);

INSERT INTO table1  (a, b, c, d)
VALUES (4, &amp;#x27;Горлукович&amp;#x27;, &amp;#x27;Белорус&amp;#x27;, 18);&lt;/pre&gt;
  &lt;p id=&quot;zs6e&quot;&gt;Результат добавления новых строк в таблицу можно проверить при помощи команды SELECT, давайте сделаем это.&lt;/p&gt;
  &lt;pre id=&quot;Re4p&quot; data-lang=&quot;sql&quot;&gt;-- Выведем таблицу table1 на экран при помощи команды SELECT
SELECT * FROM table1;

В результате мы увидим следующее:

sqlite&amp;gt; SELECT * FROM table1;

a       b               c           d

1       Петров          Русский     24
2       Нурутдинов      Татарин     28
3       Иванько         Украинец    31
4       Горлукович      Белорус     18

sqlite&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;1AX6&quot;&gt;Но при помощи оператора &lt;strong&gt;INSERT в SQLite3&lt;/strong&gt; можно добавлять данные, не указывая столбцы, в которые данные будут добавляться, давайте посмотрим.&lt;/p&gt;
  &lt;pre id=&quot;2ocz&quot; data-lang=&quot;sql&quot;&gt;-- Добавление данных в таблицу при помощи INSERTбез указания столбцов
INSERT INTO table1  VALUES (5, &amp;#x27;Сейтаридис&amp;#x27;, &amp;#x27;Грек&amp;#x27;, 48);

-- Проверим, что строка действительно была добавлена в таблицу
SELECT * FROM table1;&lt;/pre&gt;
  &lt;p id=&quot;8a63&quot;&gt;В результате после добавления новой строки наша таблица будет выглядеть так:&lt;/p&gt;
  &lt;pre id=&quot;548J&quot; data-lang=&quot;sql&quot;&gt;-- Создадим вторую таблицу с такой же структурой, как и у первой
CREATE TABLE table2(c1, с2, c3,с4);

-- Добавим во вторую таблицу данные из первой
-- при помощи команд INSERTи SELECT
INSERT INTO table2 (c1, с2, c3,с4)

SELECT a, b, c, d
FROM table1;

-- Проверим, что данные действительно были добавлены в таблицу
-- при помощи команды SELECT
SELECT * FROM table2;&lt;/pre&gt;
  &lt;p id=&quot;YYFi&quot;&gt;Вторая таблица полностью дублирует первую, так как все данные были добавлены из первой таблицы:&lt;/p&gt;
  &lt;pre id=&quot;hx1V&quot; data-lang=&quot;sql&quot;&gt;sqlite&amp;gt;SELECT * FROMtable2;

c1      с2                 c3                с4

1       Петров           Русский             24
2       Нурутдинов       Татарин             28
3       Иванько          Украинец            31
4       Горлукович       Белорус             18
5       Сейтаридис       Грек                48

sqlite&amp;gt;&lt;/pre&gt;

</content></entry></feed>