Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Virtual Columns in MySQL and MariaDB

DZone's Guide to

Virtual Columns in MySQL and MariaDB

While at first sight MariaDB 10 and MySQL 5.7 offer very similar features with virtual columns, the reality is quite different: for virtual columns in MySQL and MariaDB the syntax is not exactly the same, adding a virtual column is not done the same way and indexing sets different constraints.

· Database Zone
Free Resource

Whether you work in SQL Server Management Studio or Visual Studio, Redgate tools integrate with your existing infrastructure, enabling you to align DevOps for your applications with DevOps for your SQL Server databases. Discover true Database DevOps, brought to you in partnership with Redgate.

In this blog post, we’ll compare virtual columns in MySQL and MariaDB.

Virtual columns are one of my top features in MySQL 5.7: they can store a value that is derived from one or several other fields in the same table in a new field. It’s a very good way to build a functional index. This feature has been available in MariaDB for some time, so let’s compare the two and see if they are equivalent. We’ll look at different aspects.

Documentation

The MariaDB documentation is very easy to find.

Finding the documentation for virtual columns in 5.7 is a bit more challenging. Here is the best link I’ve found.

The MariaDB documentation isn’t clear when you should use a persistent column rather than a virtual one. If you read carefully, you’ll see that indexes are only supported on persistent columns, but the pros and cons of both options could have been better presented.

For MySQL, there is one interesting paragraph listing the potential use cases for stored columns and virtual columns. This paragraph is not super visible, but the gist of it is to always use a virtual column except if the value is too expensive to evaluate on the fly. Note that you don’t need to use a stored column to index it in 5.7.

Syntax

Creating a virtual column is very similar in both systems:

ALTER TABLE sbtest1 ADD reverse_pad char(60)GENERATED ALWAYS AS(reverse(pad))VIRTUAL;

Note that NOT NULL is not supported with MariaDB while it’s allowed in 5.7:


# MariaDB 10.0

MariaDB[db1]>ALTER TABLE sbtest1 ADD reverse_pad char(60)GENERATED ALWAYS AS(reverse(pad))VIRTUAL NOTNULL;

ERROR1064(42000):You have an error inyour SQL syntax;check the manual that corresponds toyour MariaDB server version forthe right syntax tousenear'NOT NULL'atline1

# 5.7

mysql>ALTER TABLE sbtest1 ADD reverse_pad char(60)GENERATED ALWAYS AS(reverse(pad))VIRTUAL NOTNULL;

Query OK,0rows affected(0.07sec)

Records:0Duplicates:0Warnings:0

When creating a materialized virtual column, the syntax is unfortunately not identical: MariaDB has PERSISTENT columns while 5.7 has STORED columns. It doesn’t look like a big deal, but it’s another item to add to a check list before a migration.

Adding a Virtual Column

# 5.7

ALTER TABLE sbtest1 ADD reverse_pad char(60)GENERATED ALWAYS AS(reverse(pad))VIRTUAL NOTNULL;

Query OK,0rows affected(0.03sec)

Great! Creating the column is only a metadata change, so it runs nearly instantly whatever the size of the table is.

With MariaDB, it’s quite different:

# MariaDB 10.0

ALTER TABLE sbtest1 ADD reverse_pad char(60)GENERATED ALWAYS AS(reverse(pad))VIRTUAL;

Query OK,0rows affected(7min8.50sec)

Yes, a full table rebuild was needed. And, if we are running some sysbench insert workload, we can easily see that this is not an online rebuild–for around 1/3 of the schema change, writes were stalled:

Image title


Indexing

That’s probably one of the most striking differences: with MariaDB, a column must be PERSISTENT for it to be indexed. This is not necessary with MySQL 5.7. The only situation when an indexed column in 5.7 must be STORED is when it’s a primary key.

When it comes to adding an index on several columns, some being regular columns and some being virtual columns, both versions allow this action:

# 5.7

mysql>ALTER TABLE sbtest1 ADD INDEX k_rev(k,reverse_pad);

Query OK,0rows affected(2min38.14sec)

# MariaDB 10.0

MariaDB[db1]>ALTER TABLE sbtest1 ADD INDEX k_rev(k,reverse_pad);

Query OK,10187085rows affected(4min43.76sec)

The big difference though is that adding the index is performed online in 5.7 while it’s a blocking operation in MariaDB 10.

Conclusion

While at first sight MariaDB 10 and MySQL 5.7 offer very similar features with virtual columns, the reality is quite different: for virtual columns in MySQL and MariaDB the syntax is not exactly the same, adding a virtual column is not done the same way and indexing sets different constraints. The MySQL 5.7 implementation seems more polished for a production usage with large tables and/or heavy traffic.

It’s easier than you think to extend DevOps practices to SQL Server with Redgate tools. Discover how to introduce true Database DevOps, brought to you in partnership with Redgate

Topics:
database ,sql ,mysql ,percona

Published at DZone with permission of Stephane Combaudon, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}