Spec-Zone.ru › MySQL 9.2

15.1.21.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.21.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 в качестве действий по ссылке, а также не может использовать SET NULL или SET DEFAULT в качестве действий по ссылке.

Ограничение внешнего ключа на базовом столбце хранящегося сгенерированного столбца не может использовать CASCADE, SET NULL или SET DEFAULT в качестве действий по ссылке или 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-9.2-en/create-table-generated-columns.html

Spec-Zone.ru

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