Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке згенеровані колонки в MySQL і як їх індексувати?

Згенерована колонка обчислюється з інших колонок того самого рядка за виразом.

CREATE TABLE order_items (
    price DECIMAL(10, 2) NOT NULL,
    quantity INT NOT NULL,
    total DECIMAL(12, 2) AS (price * quantity) STORED
);

ALTER TABLE users
    ADD COLUMN email_domain VARCHAR(255) AS (SUBSTRING_INDEX(email, '@', -1)) VIRTUAL,
    ADD INDEX users_email_domain_idx (email_domain);

Два види:

  • VIRTUAL (за замовчуванням у MySQL) - не зберігається, обчислюється при читанні.
  • STORED - обчислюється при записі й зберігається, як звичайна колонка.

Головна особливість MySQL - індекс на віртуальній колонці. InnoDB дозволяє вторинний індекс на VIRTUAL-колонці: значення обчислюються й зберігаються в індексі, але не в самій таблиці. Так індексують те, що інакше не проіндексувати:

Поле JSON:

ALTER TABLE products
    ADD COLUMN brand VARCHAR(100) AS (attributes ->> '$.brand') VIRTUAL,
    ADD INDEX products_brand_idx (brand);

SELECT * FROM products WHERE brand = 'Bosch';   -- використовує індекс

Вираз для пошуку без урахування регістру, дату з часу, нормалізоване значення.

Обмеження:

  • Вираз - детермінований: без NOW(), RAND(), змінних, підзапитів і посилань на інші таблиці.
  • Не можна записати значення напряму.
  • Первинний ключ - лише на STORED.
  • Зміна виразу STORED-колонки - перебудова таблиці.

Функціональні індекси (MySQL 8.0.13+) - коротший запис того самого: індекс за виразом без явної колонки.

CREATE INDEX users_lower_email_idx ON users ((LOWER(email)));

Під капотом MySQL створює приховану віртуальну колонку. Щоб індекс спрацював, вираз у запиті має збігатися з виразом в індексі.

У Laravel-міграціях: $table->string('brand')->virtualAs("attributes->>'$.brand'") і ->storedAs(...).

Докладніше в документації: Згенеровані колонки

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання