CREATE в MySQL — 100 жизненных приёмов и кейсов из практики

100 практических примеров MySQL CREATE: базы, таблицы, индексы, представления, процедуры, триггеры, события, пользователи и роли.

🟢 CREATE в MySQL. Введение

CREATE в MySQL — оператор определения объектов: позволяет создавать базы данных, таблицы, индексы, представления, ограничения, хранимые процедуры и функции, триггеры, события планировщика, роли и пользователей. Поддерживает тонкую настройку типов, кодировок, партиционирования, виртуальных столбцов, JSON и полнотекстовых/спatial индексов.

Ниже — краткий синтаксис и затем 100 уникальных практических примеров из реальных задач.

Синтаксис

CREATE DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE tbl (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  col VARCHAR(255) NOT NULL
) ENGINE=InnoDB;
CREATE INDEX idx_col ON tbl(col);
CREATE VIEW v AS SELECT ... FROM ...;
CREATE PROCEDURE proc(...) BEGIN ... END;
CREATE TRIGGER tr AFTER INSERT ON tbl FOR EACH ROW BEGIN ... END;
CREATE EVENT ev ON SCHEDULE EVERY 1 DAY DO BEGIN ... END;

Типовая конструкция

CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT, email VARCHAR(255) 
UNIQUE, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB;

100 примеров

1. Новая база с UTF‑8 и collation

CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

2. База только если её нет

CREATE DATABASE IF NOT EXISTS logsdb;

3. База с дефолтным временем в UTC

CREATE DATABASE analytics;

4. Таблица пользователей с UNIQUE на email

CREATE TABLE users 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, email VARCHAR(255) NOT NULL UNIQUE, 
name VARCHAR(120), 
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB;

5. Таблица заказов с FOREIGN KEY

CREATE TABLE orders 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, total DECIMAL(12,2) NOT NULL, 
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, 
CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users(id) 
ON DELETE CASCADE) ENGINE=InnoDB;

6. Таблица позиций заказа с составным ключом

CREATE TABLE order_items 
(order_id BIGINT, line_no INT, sku VARCHAR(64), qty INT, price DECIMAL(10,2), 
PRIMARY KEY(order_id,line_no), 
CONSTRAINT fk_items_order FOREIGN KEY(order_id) REFERENCES orders(id)) ENGINE=InnoDB;

7. Таблица с GENERATED столбцом (стоимость)

CREATE TABLE cart 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, qty INT, price DECIMAL(10,2), 
total DECIMAL(12,2) AS (qty*price) STORED) ENGINE=InnoDB;

8. Таблица с VIRTUAL JSON полем и CHECK

CREATE TABLE meta 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, body JSON, valid TINYINT AS (JSON_VALID(body)) VIRTUAL, 
CHECK (valid IN (0,1))) ENGINE=InnoDB;

9. Аудит-таблица с дефолтными значениями

CREATE TABLE audit 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
event VARCHAR(64) NOT NULL, 
details JSON, 
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP) 
ENGINE=InnoDB;

10. Справочник валют с натуральным ключом

CREATE TABLE currencies 
(code CHAR(3) PRIMARY KEY, 
name VARCHAR(64) NOT NULL, 
digits TINYINT NOT NULL DEFAULT 2) ENGINE=InnoDB;

11. BTREE INDEX для поиска по дате

CREATE INDEX idx_orders_created_at ON orders(created_at);

12. UNIQUE INDEX на домен email

CREATE UNIQUE INDEX ux_users_email ON users(email);

13. FULLTEXT индекс по названию и описанию

CREATE FULLTEXT INDEX ft_products ON products(name, description);

14. SPATIAL индекс на геометках

CREATE SPATIAL INDEX sp_places ON places(geom);

15. Составной индекс по user_id и дате

CREATE INDEX ix_login_user_date ON logins(user_id, login_time);

16. VIEW с агрегатами по пользователю

CREATE VIEW v_user_spend AS SELECT u.id user_id, SUM(o.total) spent FROM users u 
JOIN orders o ON o.user_id=u.id GROUP BY u.id;

17. VIEW активных подписок

CREATE VIEW v_active_subs AS SELECT s.* FROM subscriptions s WHERE s.active=1;

18. VIEW для витрины «последние заказы»

CREATE VIEW v_last_orders AS SELECT o.* FROM orders o ORDER BY o.created_at DESC LIMIT 100;

19. VIEW с денормализацией профиля

CREATE VIEW v_profile AS SELECT u.id, u.email, p.country, p.city FROM users u 
LEFT JOIN profiles p ON p.user_id=u.id;

20. Временная таблица для импорта

CREATE TEMPORARY TABLE staging_users LIKE users;

Еще 20 примеров

21. Временная таблица с дополнительным полем

CREATE TEMPORARY TABLE stage_orders (id BIGINT, raw JSON);

22. Копия структуры таблицы

CREATE TABLE products_copy LIKE products;

23. Таблица из SELECT (CTAS)

CREATE TABLE hot_customers AS SELECT user_id, SUM(total) AS spent FROM orders 
GROUP BY user_id HAVING SUM(total)>=10000;

24. Партицирование по RANGE месяцев

CREATE TABLE sales 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, created_at DATE, total DECIMAL(10,2)) 
PARTITION BY RANGE (YEAR(created_at)*100+MONTH(created_at)) 
(PARTITION p202501 VALUES LESS THAN (202502), PARTITION pmax VALUES LESS THAN MAXVALUE);

25. HASH‑партицирование по user_id

CREATE TABLE events 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, at DATETIME) 
PARTITION BY HASH(user_id) PARTITIONS 8;

26. LIST‑партицирование по стране

CREATE TABLE geo_data 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, country CHAR(2), payload JSON) 
PARTITION BY LIST COLUMNS(country) (PARTITION eu VALUES IN ('NL','DE','FR'), 
PARTITION other VALUES IN (DEFAULT));

27. MyISAM таблица для статического контента

CREATE TABLE static_pages 
(slug VARCHAR(120) PRIMARY KEY, body MEDIUMTEXT) ENGINE=MyISAM;

28. InnoDB с ROW_FORMAT=DYNAMIC

CREATE TABLE big_rows (id BIGINT PRIMARY KEY, j JSON) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

29. Архивная таблица для логов

CREATE TABLE logs_archive 
(id BIGINT PRIMARY KEY, body JSON, created_at DATETIME) ENGINE=InnoDB;

30. Таблица с ZEROFILL и UNSIGNED

CREATE TABLE counters 
(id INT UNSIGNED ZEROFILL PRIMARY KEY, val BIGINT UNSIGNED NOT NULL DEFAULT 0) ENGINE=InnoDB;

31. CHECK для цены > 0

CREATE TABLE prices 
(sku VARCHAR(64) PRIMARY KEY, price DECIMAL(10,2), CHECK (price>0));

32. FOREIGN KEY каскадное удаление

CREATE TABLE photos 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
album_id BIGINT, url VARCHAR(255), 
CONSTRAINT fk_photos_album FOREIGN KEY(album_id) REFERENCES albums(id) 
ON DELETE CASCADE) ENGINE=InnoDB;

33. UNIQUE на две колонки

CREATE TABLE follows 
(who BIGINT, whom BIGINT, created_at DATETIME, UNIQUE KEY uq_follow (who,whom));

34. DEFERRABLE имитация (через логику)

CREATE TABLE staged_refs 
(id BIGINT PRIMARY KEY, ref BIGINT, note VARCHAR(120));

35. JSON колонка с схемой по CHECK

CREATE TABLE cfg 
(name VARCHAR(64) PRIMARY KEY, body JSON, CHECK (JSON_VALID(body)));

36. Индекс по JSON‑атрибуту (generated)

CREATE TABLE json_idx 
(id BIGINT PRIMARY KEY, meta JSON, lang VARCHAR(8) 
AS (JSON_UNQUOTE(JSON_EXTRACT(meta,'$.lang'))) STORED, INDEX ix_lang (lang));

37. Массив тегов и FULLTEXT

CREATE TABLE posts 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
title VARCHAR(255), 
body LONGTEXT, 
tags JSON, 
FULLTEXT KEY ft_title_body (title, body));

38. Журнал событий с JSON payload

CREATE TABLE evlog 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
type VARCHAR(32), 
payload JSON, 
at DATETIME DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB;

39. SPATIAL таблица точек

CREATE TABLE geo_points 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
geom POINT NOT NULL, SPATIAL INDEX (geom)) ENGINE=InnoDB;

40. SPATIAL полигоны зон доставки

CREATE TABLE delivery_zones 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
area POLYGON NOT NULL, SPATIAL INDEX(area)) ENGINE=InnoDB;

Еще 20 примеров

41. Линии маршрутов

CREATE TABLE routes 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, path LINESTRING, name VARCHAR(120)) ENGINE=InnoDB;

42. Пользователь с доступом только к чтению

CREATE USER 'report'@'%' IDENTIFIED BY '***'; 
GRANT SELECT ON appdb.* TO 'report'@'%';

43. Роль «аналитик» и выдача прав

CREATE ROLE 'analyst'; 
GRANT SELECT, SHOW VIEW ON appdb.* TO 'analyst'; 
GRANT 'analyst' TO 'report'@'%';

44. Пользователь для ETL с ограниченными правами

CREATE USER 'etl'@'%' IDENTIFIED BY '***'; 
GRANT INSERT, UPDATE, DELETE ON appdb.* TO 'etl'@'%';

45. Stored PROCEDURE: пересчёт сумм

CREATE PROCEDURE recalc_totals(IN p_user BIGINT) 
BEGIN UPDATE orders SET total=(SELECT SUM(qty*price) FROM order_items WHERE order_id=orders.id) 
WHERE user_id=p_user; END;

46. Stored FUNCTION: очистка пробелов

CREATE FUNCTION trim_all(s VARCHAR(255)) 
RETURNS VARCHAR(255) DETERMINISTIC RETURN REGEXP_REPLACE(s,'\s+',' ');

47. PROCEDURE: массовая архивация

CREATE PROCEDURE archive_old_orders(IN cutoff DATE) 
BEGIN INSERT INTO orders_archive SELECT * FROM orders 
WHERE created_at<cutoff; 
DELETE FROM orders WHERE created_at<cutoff; END;

48. FUNCTION: безопасный JSON‑получатель

CREATE FUNCTION json_get
(j JSON, path VARCHAR(128)) RETURNS VARCHAR(255) 
DETERMINISTIC RETURN JSON_UNQUOTE(JSON_EXTRACT(j, path));

49. TRIGGER: автозаполнение created_at

CREATE TRIGGER bi_users BEFORE INSERT ON users 
FOR EACH ROW BEGIN IF NEW.
created_at IS NULL THEN SET NEW.created_at=NOW(); END IF; END;

50. TRIGGER: аудит DELETE

CREATE TRIGGER ad_orders AFTER DELETE 
ON orders FOR EACH ROW 
BEGIN 
INSERT INTO audit(event,details,created_at) 
VALUES('order_deleted', JSON_OBJECT('id',OLD.id), NOW()); 
END;

51. TRIGGER: поддержание суммы заказа

CREATE TRIGGER ai_items AFTER INSERT 
ON order_items FOR EACH ROW 
BEGIN 
UPDATE orders SET total=COALESCE(total,0)+NEW.qty*NEW.price 
WHERE id=NEW.order_id; 
END;

52. TRIGGER: нормализация email

CREATE TRIGGER bu_users BEFORE UPDATE 
ON users FOR EACH ROW 
BEGIN 
SET NEW.email=LOWER(TRIM(NEW.email)); 
END;

53. EVENT: ежедневная чистка сессий

CREATE EVENT ev_cleanup_sessions ON SCHEDULE EVERY 1 DAY DO DELETE FROM sessions 
WHERE expires_at<NOW();

54. EVENT: ежечасный рефреш витрины

CREATE EVENT ev_refresh_mart ON SCHEDULE EVERY 1 HOUR DO REPLACE 
INTO mart_daily (d,orders,sum_total) 
SELECT CURDATE(), COUNT(*), SUM(total) FROM orders WHERE created_at>=CURDATE();

55. EVENT: автоархивация логов

CREATE EVENT ev_logs_archive ON SCHEDULE EVERY 1 WEEK DO INSERT INTO logs_archive 
SELECT * FROM logs WHERE created_at<CURDATE()-INTERVAL 30 DAY;

56. EVENT: TTL для одноразовых токенов

CREATE EVENT ev_tokens_ttl ON SCHEDULE EVERY 10 MINUTE DO DELETE 
FROM auth_tokens WHERE expires_at<NOW();

57. Таблица с COMMENT и AUTO_INCREMENT

CREATE TABLE seq 
(id BIGINT PRIMARY KEY AUTO_INCREMENT) AUTO_INCREMENT=1000 COMMENT='sequence table';

58. Таблица с дефолтным CURRENT_TIMESTAMP(3)

CREATE TABLE ticks 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3));

59. Таблица с ENUM/SET

CREATE TABLE statuses 
(id INT PRIMARY KEY, status ENUM('new','in_progress','done') NOT NULL, 
flags SET('a','b','c'));

60. Таблица с CHARSET и COLLATE

CREATE TABLE notes 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, body TEXT) CHARACTER 
SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

Еще 20 примеров

61. Таблица с ROW_FORMAT=COMPRESSED

CREATE TABLE blobs 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, bin LONGBLOB) ROW_FORMAT=COMPRESSED;

62. Таблица LIKE + перенос данных позже

CREATE TABLE orders_tmp LIKE orders;

63. Создание индекса вон из таблицы

CREATE INDEX ix_orders_total ON orders(total);

64. Ускорение поиска по префиксу

CREATE INDEX ix_users_email_prefix ON users(email(20));

65. Индекс по выражению (generated + index)

CREATE TABLE emails_norm 
(id BIGINT PRIMARY KEY, 

email VARCHAR(255), 
dom VARCHAR(255) AS (SUBSTRING_INDEX(email,'@',-1)) STORED, 
INDEX ix_dom(dom));

66. Материализованная витрина (CTAS)

CREATE TABLE mart_top AS 
SELECT product_id, SUM(qty) qty FROM order_items 
GROUP BY product_id ORDER BY qty DESC LIMIT 1000;

67. Роль только на INSERT/UPDATE

CREATE ROLE 'editor'; GRANT INSERT, UPDATE ON appdb.* TO 'editor';

68. Пользователь‑интеграция только на одну таблицу

CREATE USER 'bot'@'%' IDENTIFIED BY '***';
 GRANT SELECT, INSERT ON appdb.orders TO 'bot'@'%';

69. Роль «readonly» + выдача пользователю

CREATE ROLE 'readonly'; 
GRANT SELECT ON appdb.* TO 'readonly'; GRANT 'readonly' TO 'bob'@'%';

70. Отзыв прав у роли

CREATE ROLE 'temp_role'; REVOKE INSERT, 
UPDATE ON appdb.* FROM 'temp_role';

71. Временная песочница для теста

CREATE TEMPORARY TABLE sandbox (k VARCHAR(64), v VARCHAR(64));

72. Генератор последовательностей через таблицу

CREATE TABLE seq_gen (id BIGINT PRIMARY KEY AUTO_INCREMENT, stub TINYINT) ENGINE=InnoDB;

73. Фикстуры пользователей (CTAS)

CREATE TABLE users_fixture AS SELECT * FROM users WHERE id<0;

74. Отладочная таблица с UUID

CREATE TABLE debug 
(id CHAR(36) PRIMARY KEY, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);

75. Мини‑журнал для юнит‑тестов

CREATE TABLE tlog 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, m VARCHAR(120), at DATETIME DEFAULT CURRENT_TIMESTAMP);

76. Справочник стран по ISO

CREATE TABLE countries (code CHAR(2) PRIMARY KEY, name VARCHAR(80) NOT NULL UNIQUE);

77. Нормализованная таблица телефонов

CREATE TABLE phones 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, 
user_id BIGINT, 
e164 VARCHAR(32), 
CONSTRAINT fk_phone_user FOREIGN KEY(user_id) REFERENCES users(id)) ENGINE=InnoDB;

78. Таблица доменов email

CREATE TABLE email_domains (dom VARCHAR(255) PRIMARY KEY, cnt INT DEFAULT 0);

79. Таблица правил валидации

CREATE TABLE validators 
(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64) UNIQUE, pattern VARCHAR(255));

80. Таблица для дедупликации логов (хеш)

CREATE TABLE log_hash (hash CHAR(64) PRIMARY KEY, 
created_at DATETIME DEFAULT CURRENT_TIMESTAMP);

Еще 20 примеров

81. Таблица для батч‑загрузки (minimal indexes)

CREATE TABLE import_buffer 
(id BIGINT PRIMARY KEY AUTO_INCREMENT, payload JSON) ENGINE=InnoDB;

82. Индекс только для ORDER BY дате

CREATE INDEX ix_events_at ON events(at);

83. Покрывающий индекс по (user_id, at)

CREATE INDEX ix_events_user_at ON events(user_id, at);

84. FULLTEXT для поиска по постам

CREATE FULLTEXT INDEX ft_posts ON posts(title, body);

85. SPATIAL индекс для nearest‑search

CREATE SPATIAL INDEX sp_idx ON geo_points(geom);

86. Журнал версий схемы

CREATE TABLE schema_version 
(name VARCHAR(64) PRIMARY KEY, ver INT NOT NULL, applied_at DATETIME NOT NULL);

87. Регистр миграций

CREATE TABLE migrations 
(id INT PRIMARY KEY AUTO_INCREMENT, 
name VARCHAR(255) UNIQUE, 
applied_at DATETIME NOT NULL);

88. Каталог источников данных

CREATE TABLE data_sources 
(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(120) UNIQUE, url VARCHAR(255));

89. Каталог задач ETL

CREATE TABLE etl_jobs 
(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(120) UNIQUE, schedule VARCHAR(120));

90. Каталог словарей с JSON‑схемой

CREATE TABLE dictionaries (name VARCHAR(64) PRIMARY KEY, schema_json JSON);

91. VIEW как интерфейс безопасности

CREATE VIEW v_orders_public AS SELECT id, total FROM orders;

92. VIEW с WITH CHECK OPTION

CREATE VIEW v_eu_users AS SELECT * 
FROM users 
WHERE email LIKE '%.eu' WITH CHECK OPTION;

93. Индекс на префиксе JSON‑ключа (через generated)

CREATE TABLE jprefix (id BIGINT PRIMARY KEY, meta JSON, p VARCHAR(16) AS (JSON_UNQUOTE(JSON_EXTRACT(meta,'$.p'))) STORED, INDEX ix_p(p));

94. TRIGGER: генерация домена email

CREATE TRIGGER bi_email_domain BEFORE INSERT ON users FOR EACH ROW BEGIN SET NEW.email=LOWER(NEW.email); END;

95. EVENT: дневной отчёт по продажам

CREATE EVENT ev_sales_daily 
ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP DO INSERT INTO sales_daily SELECT CURDATE(),
 SUM(total) 
FROM orders;

Заключение

CREATE в MySQL — фундаментальный оператор DDL. С его помощью определяются структуры данных (таблицы, индексы, представления), программные объекты (процедуры, функции, триггеры, события), а также безопасность (пользователи, роли). Практика 100 примеров выше помогает выбирать правильные конструкции и настройки под задачу.

Смотрите также официальную документацию: MySQL Docs.

Понравилась статья? Поделиться с друзьями: