当前位置: 首页 > news >正文

mysql 虚拟列,可以简化 SQL 逻辑、提升查询效率

image
MySQL 5.7 及以上版本支持 生成列(Generated Columns),也称为 “虚拟列”。虚拟列的值不是手动插入的,而是由表中其他列的值通过表达式计算得出,类似于 “自动计算的字段”。
虚拟列的两种类型
虚拟生成列(Virtual Generated Columns)
不实际存储在磁盘上,每次查询时动态计算
不占用存储空间,但查询时会消耗计算资源
存储生成列(Stored Generated Columns)
计算结果会存储在磁盘上,与普通列一样占用空间
查询时无需重新计算,性能更好,但更新依赖列时会额外消耗资源
基本语法
创建表时定义虚拟列:

sql
CREATE TABLE 表名 (
普通列定义,
虚拟列名 数据类型 GENERATED ALWAYS AS (表达式) [VIRTUAL|STORED]
);

GENERATED ALWAYS AS (表达式):定义计算规则
VIRTUAL:虚拟类型(默认,可省略)
STORED:存储类型,需显式指定
示例

  1. 基础用法(计算商品总价)
    sql
    CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    price DECIMAL(10,2) NOT NULL, -- 单价
    quantity INT NOT NULL, -- 数量
    total DECIMAL(12,2) GENERATED ALWAYS AS (price * quantity) STORED -- 总价(存储型)
    );

插入数据时,无需指定虚拟列的值:

sql
INSERT INTO products (price, quantity) VALUES (99.99, 2); -- 自动计算 total = 99.99*2 = 199.98

查询结果:

sql
SELECT * FROM products;
-- 结果:id=1, price=99.99, quantity=2, total=199.98
2. 虚拟列结合字符串函数(提取邮箱域名)
sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(100) NOT NULL,
email_domain VARCHAR(50) GENERATED ALWAYS AS (
SUBSTRING_INDEX(email, '@', -1) -- 从@后截取域名
) VIRTUAL -- 虚拟类型,不存储
);

查询时自动提取域名:

sql
INSERT INTO users (email) VALUES ('user@example.com'), ('admin@gmail.com');

SELECT email, email_domain FROM users;
-- 结果:
-- email | email_domain
-- user@example.com | example.com
-- admin@gmail.com | gmail.com
3. 修改表添加虚拟列
sql
-- 给已存在的表添加虚拟列
ALTER TABLE orders
ADD COLUMN tax DECIMAL(10,2) GENERATED ALWAYS AS (total * 0.1) STORED; -- 计算税费(10%)
虚拟列的使用场景
简化查询:将复杂计算逻辑固化在表结构中,避免每次查询重复写表达式
创建索引:虚拟列支持创建索引(尤其是存储型),可加速基于计算结果的查询
sql
-- 给邮箱域名虚拟列创建索引
CREATE INDEX idx_email_domain ON users(email_domain);

数据校验:结合约束实现复杂验证(如 CHECK 约束)
sql
CREATE TABLE temperatures (
id INT PRIMARY KEY,
celsius DECIMAL(5,2) NOT NULL,
fahrenheit DECIMAL(5,2) GENERATED ALWAYS AS (celsius * 9/5 + 32) VIRTUAL,
CHECK (celsius BETWEEN -273.15 AND 1000) -- 校验摄氏度范围
);

注意事项
虚拟列的表达式只能依赖本表的其他列,不能使用其他表的列或函数(如 NOW()、RAND() 等)
虚拟列的值会随依赖列的更新自动更新,无需手动维护
存储型虚拟列会增加写入和更新的开销,需平衡存储空间和查询性能
虚拟列不能作为 AUTO_INCREMENT 列,也不能设置默认值(值由表达式决定)

以上就是关于mysql 虚拟列的介绍。还有一款非常便捷的MYSQL导出、导入备份工具也运用的很不错,“80KM-mysql备份工具”。 可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。

3

合理使用虚拟列可以简化 SQL 逻辑、提升查询效率,但需根据实际场景选择虚拟型或存储型。

http://www.hskmm.com/?act=detail&tid=9727

相关文章:

  • Flash Attention算法动画
  • PointNetwork-求解TSP-05 - jack
  • 多站点的TSP问题求解-06 - jack
  • Windows 11如何进入安全模式
  • C# CAN通信上位机系统设计与实现
  • 进程池VS线程池
  • 聊聊昨天CodeBuddy Meetup的一些收获与思考
  • 框架的诞生,本就是人类文明共同涌现的结晶,绝不是某个人的独自觉悟
  • python+Django开发笔记(结合禅道开发测试报告)
  • MVC分层设计模式 2章
  • Questions about learning Symfony
  • 【Python】cx_Freeze模块_打包exe
  • ctfshow web22(子域名爆破)
  • PLC中的运动控制 - (一)轴
  • 墨者学院 某防火墙默认口令
  • IOC控制反转的解耦(相比于直接new对象的正向控制)
  • 墨者学院 浏览器信息伪造
  • AT_arc156_c [ARC156C] Tree and LCS
  • 完整教程:ARM指令集总结
  • 封神台 第二章:遇到阻难!绕过WAF过滤
  • 封神台 第三章:为了更多的权限!留言板!
  • 第一篇
  • C#开发ONVIF客户端与RTSP播放库指南
  • 一行命令查看docker所有网络 + 子网
  • ECT-OS-JiuHuaShan框架元推理,是马克思主义与我思故我在的完美统一,是超越自我
  • vulnhub Beelzebub
  • Salesforce 管理员:是终点,还是跳板?
  • 记一次内务培训
  • CH584 CH585 复位状态寄存器
  • 2025CCPC邀请赛(南昌)VP(A,B,C,D,G,H,K,L)