Глиф Учебники

Урок 2. Создание таблицы и типы данных

Курс «SQL» · урок 2 из 10 · 4 минуты чтения

В этом уроке появится первая таблица учебного магазина — products, товары. Откройте свою базу: sqlite3 shop.db или файл shop.db в DB Browser for SQLite (как их поставить — в первом уроке).

Команда CREATE TABLE

SQL
CREATE TABLE products (
    id       INTEGER PRIMARY KEY,
    name     TEXT    NOT NULL,
    category TEXT,
    price    INTEGER NOT NULL CHECK (price >= 0),
    qty      INTEGER NOT NULL DEFAULT 0
);

После CREATE TABLE — имя таблицы, в скобках через запятую — столбцы. У каждого столбца имя, тип и, если нужно, ограничения — правила, которые СУБД проверяет при каждой записи:

Запятая ставится между столбцами, после последнего её нет. Лишняя запятая перед ) — частая причина ошибки syntax error.

имя тип ограничения CREATE TABLE products ( ← имя таблицы id INTEGER PRIMARY KEY, name TEXT NOT NULL, category TEXT, price INTEGER NOT NULL CHECK (price >= 0), qty INTEGER NOT NULL DEFAULT 0 ); , — между столбцами после последнего запятой нет лишняя даст syntax error
В CREATE TABLE у каждого столбца сначала имя, затем тип и ограничения; столбцы разделяются запятыми, а после последнего запятой нет.

Типы данных

В SQLite всего пять видов значений: INTEGER (целое), REAL (дробное), TEXT (текст), BLOB (байты, например картинка) и NULL (пусто). Серверные СУБД различают типы строже и подробнее:

Что хранитьSQLiteMySQL / MariaDBPostgreSQL
Целое числоINTEGERINT, BIGINTinteger, bigint
Дробное числоREALDOUBLEdouble precision
Деньги без ошибок округленияINTEGER (в копейках)DECIMAL(10,2)numeric(10,2)
Строка с пределом длиныTEXTVARCHAR(100)varchar(100)
Длинный текстTEXTTEXTtext
ДатаTEXT вида 2026-09-01DATEdate
Дата и времяTEXT вида 2026-09-01 14:30:00DATETIMEtimestamp
Да или нетINTEGER (0 и 1)BOOLEANboolean
Файл, байтыBLOBBLOBbytea

DECIMAL(10,2) — точное число: всего 10 цифр, из них 2 после запятой. Для денег берут его, а не DOUBLE: дробные типы хранят числа приближённо, и 0.1 + 0.2 у них не равно точно 0.3.

VARCHAR(100) — строка не длиннее 100 знаков. В MySQL у текстового столбца почти всегда указывают длину, в PostgreSQL можно писать просто text.

Типы в SQLite гибкие

SQLite принимает и чужие имена типов — VARCHAR(100), DATE, DECIMAL(10,2) — и сводит их к своим. Более того, обычная таблица SQLite позволяет записать текст в столбец INTEGER: тип там — пожелание, а не запрет. Строгую проверку включает слово STRICT после скобок (SQLite 3.37 и новее):

SQL
CREATE TABLE prices (
    product TEXT NOT NULL,
    price   INTEGER NOT NULL
) STRICT;

В такой таблице допустимы только типы INTEGER, INT, REAL, TEXT, BLOB и ANY, а попытка записать 'abc' в price закончится ошибкой. Как это выглядит — в следующем уроке.

Ограничения

ОграничениеЧто делает
NOT NULLЗначение обязательно
DEFAULT 0Значение, если его не указали при добавлении строки
CHECK (price >= 0)Условие, которое должно выполняться
UNIQUEДва одинаковых значения в столбце запрещены
PRIMARY KEYКлюч строки: уникальный и обязательный

Ограничения — защита от ошибок в данных: товар без названия или с ценой −5 просто не попадёт в таблицу. Подробно о ключах — в уроке Ключи, связи и индексы.

name price qty правило таблицы Ручка 2 150 правила соблюдены записана NULL 3 300 NOT NULL не записана Пенал −5 40 CHECK (price >= 0) не записана Глобус 45 — DEFAULT 0 записана, qty = 0
Ограничения проверяются при каждой записи: строка без названия не проходит NOT NULL, строка с ценой −5 не проходит CHECK, а пропущенный остаток DEFAULT заменяет нулём.

MySQL проверяет CHECK начиная с версии 8.0.16. Более старые версии принимают такое условие, но молча его пропускают.

Та же таблица в MySQL и PostgreSQL

MySQL и MariaDB:

SQL
CREATE TABLE products (
    id       INT AUTO_INCREMENT PRIMARY KEY,
    name     VARCHAR(100) NOT NULL,
    category VARCHAR(50),
    price    DECIMAL(10,2) NOT NULL CHECK (price >= 0),
    qty      INT NOT NULL DEFAULT 0
);

PostgreSQL:

SQL
CREATE TABLE products (
    id       integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name     varchar(100) NOT NULL,
    category varchar(50),
    price    numeric(10,2) NOT NULL CHECK (price >= 0),
    qty      integer NOT NULL DEFAULT 0
);

Главное отличие — автоматический номер: в SQLite его даёт INTEGER PRIMARY KEY, в MySQL — AUTO_INCREMENT, в PostgreSQL — GENERATED … AS IDENTITY или старый тип serial. Подробнее — в справке Автоинкремент в SQLite, MySQL и PostgreSQL.

Имена таблиц и столбцов

Пишите имена латиницей, строчными буквами, слова — через подчёркивание: products, order_date, customer_id. Пробелы и русские буквы технически возможны, но такие имена придётся всё время брать в кавычки.

Нельзя без кавычек называть таблицу или столбец служебным словом SQL: order, group, select, table, а в PostgreSQL ещё и user. Запрос CREATE TABLE order (…) закончится ошибкой syntax error. Поэтому заказы в курсе — orders. Если имя уже занято таким словом, его берут в кавычки: в SQLite и PostgreSQL — в двойные, в MySQL — в обратные (знак на клавише с буквой Ё):

SQL
SELECT * FROM "order";   -- SQLite, PostgreSQL
SELECT * FROM `order`;   -- MySQL, MariaDB

Посмотреть, что получилось

ЧтоSQLite (sqlite3)MySQLPostgreSQL (psql)
Список таблиц.tablesSHOW TABLES;\dt
Устройство таблицы.schema productsDESCRIBE products;\d products

В DB Browser for SQLite таблицы видны на вкладке «Database Structure». Есть и запрос SQL, который работает в любой программе для SQLite:

SQL
PRAGMA table_info(products);
cidnametypenotnulldflt_valuepk
0idINTEGER0NULL1
1nameTEXT1NULL0
2categoryTEXT0NULL0
3priceINTEGER1NULL0
4qtyINTEGER100

Если таблица уже есть

Повторный CREATE TABLE products выдаст ошибку table products already exists. Чтобы создать таблицу только тогда, когда её нет, добавьте IF NOT EXISTS:

SQL
CREATE TABLE IF NOT EXISTS products (
    id   INTEGER PRIMARY KEY,
    name TEXT NOT NULL
);

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

Удалить таблицу

SQL
DROP TABLE IF EXISTS products;

DROP TABLE удаляет таблицу вместе со всеми строками, без вопроса «вы уверены?». Вернуть её можно только из резервной копии. Перед удалением на рабочей базе сделайте копию — как, рассказано в справке Резервная копия базы данных.

Если вы удалили products, создайте её снова первым запросом урока: она понадобится дальше.

Коротко

Проверьте себя

1. Что сделает DEFAULT 0 у столбца qty?
2. Какой тип лучше для цены в MySQL?
3. Почему запрос CREATE TABLE order (id INTEGER); не выполняется?
4. Что произойдёт после DROP TABLE products;?