Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
A generated column is a column whose value is derived from an expression rather than stored by the application. MySQL computes it automatically — you define the formula once in the schema, and MySQL keeps it consistent.

Syntax

VIRTUAL vs STORED

Use STORED when the computation is expensive and you read the column far more than you write it. Use VIRTUAL (the default) when storage is a concern or writes happen frequently.

Expressions

Generated column expressions can reference other columns in the same row. They cannot reference other generated columns or call non-deterministic functions.
Functions allowed in generated columns must be deterministic — same inputs always produce the same output. Disallowed: NOW(), RAND(), UUID(), subqueries, stored functions. Extracting fields from JSON is a common use case:

Indexing Generated Columns

You can add an index on a generated column. For VIRTUAL columns, MySQL materializes the computed value into the index.
This is also how to build a functional index — an index on a function of a column rather than the raw column value. MySQL 8.0.13+ supports functional indexes directly (INDEX (LOWER(email))), which internally creates a hidden generated column:

Inserting and Updating

You cannot assign a value to a generated column in an INSERT or UPDATE. The column value is always derived from the expression. You can write DEFAULT explicitly, but that’s all:

ALTER TABLE

Add a generated column to an existing table:
Change a generated column’s expression:

Frequently Asked Questions

Can I use a generated column in a WHERE clause?

Yes. For VIRTUAL columns without an index, MySQL computes the expression during the scan. For STORED columns or indexed VIRTUAL columns, the value is already materialized. Use EXPLAIN to verify whether the index is being used.

Does a generated column update automatically when the source columns change?

Yes. MySQL recomputes VIRTUAL generated columns on every read. STORED generated columns are recomputed and written on every INSERT or UPDATE that affects the columns in the expression.

Can I use a generated column as a partition key?

Yes, for STORED generated columns. VIRTUAL columns cannot be used as partition keys.

Troubleshooting

See also