Spec-Zone.ru › MySQL 8.4

15.1.20.8 CREATE TABLE и сгенерированные столбцы

CREATE TABLE поддерживает указание сгенерированных столбцов. Значения сгенерированного столбца вычисляются по выражению, включенному в определение столбца.

Сгенерированные столбцы также поддерживаются NDB движком хранения.

Следующий простой пример показывает таблицу, которая хранит длины сторон прямоугольных треугольников в столбцах sidea и sideb, и вычисляет длину гипотенузы в sidec (квадратный корень из суммы квадратов других сторон):

CREATE TABLE triangle (
  sidea DOUBLE,
  sideb DOUBLE,
  sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb))
);
INSERT INTO triangle (sidea, sideb) VALUES(1,1),(3,4),(6,8);

Выборка из таблицы дает такой результат:

mysql> SELECT * FROM triangle;
+-------+-------+--------------------+
| sidea | sideb | sidec              |
+-------+-------+--------------------+
|     1 |     1 | 1.4142135623730951 |
|     3 |     4 |                  5 |
|     6 |     8 |                 10 |
+-------+-------+--------------------+

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

Определения сгенерированных столбцов имеют такой синтаксис:

col_name data_type [GENERATED ALWAYS] AS (expr)
  [VIRTUAL | STORED] [NOT NULL | NULL]
  [UNIQUE [KEY]] [[PRIMARY] KEY]
  [COMMENT 'string']

AS (expr) указывает, что столбец сгенерирован, и определяет выражение, используемое для вычисления значений столбца. AS может быть предшествовано GENERATED ALWAYS, чтобы сделать природу сгенерированного столбца более явной. Конструкции, которые разрешены или запрещены в выражении, обсуждаются позже.

Ключевые слова VIRTUAL или STORED указывают, как хранятся значения столбца, что имеет последствия для использования столбца:

  • VIRTUAL: Значения столбца не хранятся, а вычисляются при чтении строк, сразу после любых BEFORE триггеров. Виртуальный столбец не занимает места в хранилище.

    InnoDB поддерживает вторичные индексы на виртуальных столбцах. См. Раздел 15.1.20.9, «Вторичные индексы и сгенерированные столбцы».

  • STORED: Значения столбца вычисляются и хранятся при вставке или обновлении строк. Хранящийся столбец требует места в хранилище и может быть индексирован.

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

Разрешается смешивать VIRTUAL и STORED столбцы в одной таблице.

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

Выражения сгенерированных столбцов должны соблюдать следующие правила. Возникает ошибка, если выражение содержит запрещенные конструкции.

  • Разрешены литералы, детерминированные встроенные функции и операторы. Функция является детерминированной, если при одинаковых данных в таблицах многократные вызовы производят один и тот же результат, независимо от подключенного пользователя. Примеры функций, которые не являются детерминированными и не удовлетворяют этому определению: CONNECTION_ID(), CURRENT_USER(), NOW().

  • Хранящиеся функции и загружаемые функции не разрешены.

  • Параметры хранимых процедур и функций не разрешены.

  • Переменные (системные переменные, переменные пользователя и локальные переменные хранимых программ) не разрешены.

  • Подзапросы не разрешены.

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

  • Атрибут AUTO_INCREMENT не может использоваться в определении сгенерированного столбца.

  • AUTO_INCREMENT столбец не может использоваться в качестве базового столбца в определении сгенерированного столбца.

  • Если вычисление выражения приводит к усечению или обеспечивает некорректный ввод для функции, операция CREATE TABLE завершается с ошибкой, и операция DDL отклоняется.

Если выражение вычисляет тип данных, отличающийся от объявленного типа столбца, происходит неявное приведение к объявленному типу в соответствии с обычными правилами преобразования типов MySQL. См. Раздел 14.3, «Преобразование типов в вычислении выражений».

Если сгенерированный столбец использует тип данных TIMESTAMP, значение explicit_defaults_for_timestamp игнорируется. В таких случаях, если эта переменная отключена, NULL не преобразуется в CURRENT_TIMESTAMP. Если столбец также объявлен как NOT NULL, попытка вставить NULL явно отклоняется.

Примечание

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

Для CREATE TABLE ... LIKE целевая таблица сохраняет информацию о сгенерированных столбцах из исходной таблицы.

Для CREATE TABLE ... SELECT целевая таблица не сохраняет информацию о том, являются ли столбцы в выбранной таблице сгенерированными столбцами. Часть SELECT оператора не может назначать значения сгенерированным столбцам в целевой таблице.

Разбиение по сгенерированным столбцам разрешено. См. Разбиение таблиц.

Ограничение внешнего ключа на хранящемся сгенерированном столбце не может использовать CASCADE, SET NULL или SET DEFAULT в качестве ON UPDATE действий ссылок, а также не может использовать SET NULL или SET DEFAULT в качестве ON DELETE действий ссылок.

Ограничение внешнего ключа на базовом столбце хранящегося сгенерированного столбца не может использовать CASCADE, SET NULL или SET DEFAULT в качестве ON UPDATE или ON DELETE действий ссылок.

Ограничение внешнего ключа не может ссылаться на виртуальный сгенерированный столбец.

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

Для INSERT, REPLACE и UPDATE, если сгенерированный столбец вставляется, заменяется или обновляется явно, единственное разрешенное значение равно DEFAULT.

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

Сгенерированные столбцы имеют несколько вариантов использования, такие как:

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

  • Хранящиеся сгенерированные столбцы могут использоваться в качестве кеша для сложных условий, которые дорогостоящие для вычисления на лету.

  • Сгенерированные столбцы могут имитировать функциональные индексы: используйте сгенерированный столбец для определения функционального выражения и индексируйте его. Это может быть полезно при работе со столбцами типов, которые нельзя индексировать напрямую, например, столбцами JSON; см. Индексирование сгенерированного столбца для предоставления индекса столбца JSON для подробного примера.

    Для хранящихся сгенерированных столбцов недостатком этого подхода является то, что значения хранятся дважды; один раз как значение сгенерированного столбца и один раз в индексе.

  • Если сгенерированный столбец индексируется, оптимизатор распознает выражения запроса, которые соответствуют определению столбца, и использует индексы из столбца при выполнении запроса, даже если запрос не ссылается на столбец напрямую по имени. Подробности см. в разделе 10.3.11, «Использование оптимизатором индексов сгенерированных столбцов».

Пример:

Предположим, что таблица t1 содержит столбцы first_name и last_name, и приложения часто строят полное имя, используя выражение вроде этого:

SELECT CONCAT(first_name,' ',last_name) AS full_name FROM t1;

Один способ избежать записи выражения — создать представление v1 на t1, которое упрощает приложения, позволяя им выбирать full_name напрямую без использования выражения:

CREATE VIEW v1 AS
SELECT *, CONCAT(first_name,' ',last_name) AS full_name FROM t1;

SELECT full_name FROM v1;

Сгенерированный столбец также позволяет приложениям выбирать full_name напрямую, без необходимости определять представление:

CREATE TABLE t1 (
  first_name VARCHAR(10),
  last_name VARCHAR(10),
  full_name VARCHAR(255) AS (CONCAT(first_name,' ',last_name))
);

SELECT full_name FROM t1;

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/create-table-generated-columns.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API