Spec-Zone.ru › MySQL 5.7

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

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

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

Следующий простой пример демонстрирует таблицу, хранящую длины сторон прямоугольных треугольников в столбцах 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 поддерживает вторичные индексы на виртуальных столбцах. См. Раздел 13.1.18.8, «Вторичные индексы и сгенерированные столбцы».

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

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

Допускается смешивание столбцов VIRTUAL и STORED в одной таблице.

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

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

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

  • Хранящиеся функции и загружаемые функции не допускаются.

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

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

  • Подзапросы не допускаются.

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Пример:

Предположим, что таблица 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-5.7-en/create-table-generated-columns.html

Spec-Zone.ru

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