mysql中生成列与JSON类型的索引
MySQL中支持生成列,生成列的值是根据列定义中包含的表达式计算的。
一个简单的例子来认识生成列!
CREATE TABLE triangle(
sidea DOUBLE,
sideb DOUBLE,
sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb))
); INSERT INTO triangle(sidea, sideb) VALUES(3,4),(6,8),(5,12); mysql> select * from triangle; #插入数值的时候并没有插入c的值,但是查询的时候,还是有了c值
+-------+-------+-------+
| sidea | sideb | sidec |
+-------+-------+-------+
| 3 | 4 | 5 |
| 6 | 8 | 10 |
| 5 | 12 | 13 |
+-------+-------+-------+
3 rows in set (0.00 sec) mysql>
生成列中的值,是根据生成列的定义计算出来的!
生成列的定义如下:
col_name data_type [GENERATED ALWAYS] AS (expression)
[VIRTUAL | STORED] [NOT NULL | NULL]
[UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
#AS表达式表示生成列并用于计算生成列的表达式。As之前的GENERATED ALWAYS可以让生成列的性质更明确(应该没什么作用,反正是可以省略的)!
#VIRTUAL | STORED 关键字表示列值的存储方式
VIRTUAL: 不存储列值,但在读取值之前立即计算此列的数值,虚拟列不占存储空间,innodb支持虚拟列上的二级索引。为默认的存储方式。
- STORED:插入或更新时,将计算存储列的值,并且占用存储空间。
生成列的表达式必须遵循以下的规则,否则会报错:
- 允许使用字符串,运算符和确定性内置函数。对于给定的相同的数据库,不同连接的用户调用会产生相同的结果,则这个函数时确定的。now()函数就不是确定性函数。
- 不允许使用子查询,参数,变量,存储函数(stored functions)和用户自定义的函数。
- 生成的列定义可以引用其他生成的列,但只能引用表定义中较早出现的列。生成的列定义可以引用表中的任何基本(非生成)列,无论其定义是早期还是稍后发生。
- auto_increment属性不能再生成列的定义中使用。
- 一个
AUTO_INCREMENT列不能用作在生成的列定义的基柱(AnAUTO_INCREMENTcolumn cannot be used as a base column in a generated column definition.) - 从MySQL 5.7.10开始,如果表达式求值导致截断或向函数提供不正确的输入,则
CREATE TABLE语句将以错误终止并拒绝DDL操作
生成列的作用(可能不太准确):
- 虚拟生成的列可用作简化和统一查询的方法。可以将复杂条件定义为生成列,并从表上的多个查询引用,以确保他们全部使用完全相同的条件。
- 存储生成的列可以用作物化缓存,用于复杂的条件,这些条件在运行中计算成本很高。
- 生成列可以模拟功能索引,利用生成列定义功能表达式对其进行索引。例如对JSON数据类型。对于存储的生成列,这种方法缺点是存储两次,一次是生成列的值,另一次是索引。
- 如果生成的列已编制索引,则优化程序将识别与列定义匹配的查询表达式,并在查询执行期间根据需要使用列中的索引,即使查询未按名称直接引用该列也是如此。
如下一个含有json类型字段的表:
CREATE TABLE json_test (
id INT auto_increment PRIMARY KEY,
userinfo json
); #插入数据 INSERT INTO json_test(userinfo) VALUES('{"name":"libai","address":"china","email":"libai@163.com"}');
INSERT INTO json_test(userinfo) VALUES('{"name":"obama","address":"miguo","email":"libai@gmail.com"}');
INSERT INTO json_test(userinfo) VALUES('{"name":"putin","address":"russia","email":"putin@gmail.com"}'); #
给表中添加生成列
alter table json_test add column user_name varchar(40) generated always as (userinfo->"$.name") virtual; #查看表中的数据
mysql> select * from json_test;
+----+--------------------------------------------------------------------+-----------+
| id | userinfo | user_name |
+----+--------------------------------------------------------------------+-----------+
| 1 | {"name": "libai", "email": "libai@163.com", "address": "china"} | "libai" |
| 2 | {"name": "obama", "email": "libai@gmail.com", "address": "miguo"} | "obama" |
| 3 | {"name": "putin", "email": "putin@gmail.com", "address": "russia"} | "putin" |
+----+--------------------------------------------------------------------+-----------+
3 rows in set (0.00 sec) #在表中插入数据user_name列的数值会自动计算,这时候,我们就可以对user_name列添加索引!
mysql中生成列与JSON类型的索引的更多相关文章
- MySQL 5.7 使用原生JSON类型
首先回顾一下JSON的语法规则: 数据在键值对中, 数据由逗号分隔, 花括号保存对象, 方括号保存数组. 按照最简单的形式,可以用下面的JSON表示: {"NAME": " ...
- MySQL中TEXT与BLOB字段类型的区别
这篇文章主要介绍了MySQL中TEXT与BLOB字段类型的区别,本文总结了6大区别,需要的朋友可以参考下 在MySQL中有两个字段类型容易让人感觉混淆,那就是TEXT与BLOB,特别是自己写博客程 ...
- 转:JS中生成和解析JSON
原文地址:JS中生成和解析JSON 1.JS中生成JSON对象的方法: var json = []; var row1 = {}; row1.id= "1"; row1.name ...
- [置顶] mysql中的set和enum类型的用法和区别
mysql中的enum和set其实都是string类型的而且只能在指定的集合里取值, 不同的是set可以取多个值,enum只能取一个值. CREATE TABLE `20121101_t` ( ...
- 使用PowerDesigner创建物理模型并生成SQL语句在MySQL中生成表
我使用的PowerDesigner的版本为16.5,创建物理模型后,使用PowerDesigner生成的SQL语句,在MySQL中创建表. 1. 打开Power Designer软件,在弹出的欢迎对话 ...
- mysql中别名(列别名和表别名)
1.介绍 使用MySQL别名来提高查询的可读性.MySQL支持两种别名,称为列别名和表别名. 有时,列的名称是一些表达式,使查询的输出很难理解.要给列一个描述性名称,可以使用列别名.用法: SELEC ...
- 关于MySQL中的三种日期类型
Mysql中我们经常用来存储日期的数据类型有三种:Date.Datetime.Timestamp. Date数据类型用来存储没有时间的日期.Mysql获取和显示这个类型的格式为"YYYY-M ...
- mysql中几个日期时间类型之间的区别和使用
MySQL中有如下几个时间类型:date.time.datetime.timestamp.year MySQL数据类型 含义 date 只存 ...
- MySQL 中NULL和空值的区别,索引列可以有空值或者null吗?
空值跟null的区别.mysql官方: “NULL columns require additional space in the row to record whether their values ...
随机推荐
- Windows下重置Mysql密码
1.首先停止正在运行的MySQL进程 >net stop mysql 如未加载为服务,可直接在进程管理器或者服务中进行关闭. 2.以安全模式启动MySQL进入mysql目录在命令行下运行 > ...
- Effective C++ —— 继承与面向对象设计(六)
条款32 : 确定你的public继承塑模出is-a关系 以C++进行面向对象编程,最重要的一个规则是:public inheritance(公开继承)意味“is-a”(是一种)的关系.请务必牢记.当 ...
- ASP.NET 4.0尚未在Web服务器注册 解决
http://www.cnblogs.com/lvxiouzi/p/3511446.html 安装asp.net 4.0.30319.0版本 命令: %windir%\Microsoft.NET\Fr ...
- ajax 跨域访问 :Access-Control-Allow-Origin
一说到ajax跨域.首先想到的就是jsonp . JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全. 即使使用jQuery的jsonp方法,type设为POST,也 ...
- Day04_数据类型占位符使用及进制转换
2013年10月09日 星期三 10时03分51秒 回顾: 1.变量 2.scanf标准函数 字符类型是一种数据类型 在C语言程序中字符类型用char表示 字符类型中包含了256个不同的字符,例如 ...
- SPOJ - DQUERY
题目链接:传送门 题目大意:一个容量 n 的数组, m次询问,每次询问 [x,y]内不同数的个数 题目思路:主席树(注意不是权值线段树而是位置线段树) 也就是按一般线段树的逻辑来写只是用主席树实现而已 ...
- log4j和commons- logging(好文整理转载)
一 :为什么同时使用commons-logging和Log4j?为什么不仅使用其中之一? Commons-loggin的目的是为 “所有的Java日志实现”提供一个统一的接口,它自身的日志功能平常弱( ...
- sencha touch 入门系列 (八)sencha touch类系统讲解(下)
接着上一讲,我们通过一组代码来讲解一下st的类的一些属性: Ext.define("MyConfig",{ config:{ website:"http://127.0. ...
- 如何获取e.printStackTrace()的内容
e.printStackTrace()通常是打印在控制台的,但是,有时候程序上线了需要看这个堆栈的内容就不容易了,一来生产环境打印的东西很多或者很少,二来有时候无法直接查看到,这个时候就需要把这些内容 ...
- CH1301 邻值查找【set应用】
1301 邻值查找 0x10「基本数据结构」例题 描述 给定一个长度为 n 的序列 A,A 中的数各不相同.对于 A 中的每一个数 A_i,求:min(1≤j<i) |A_i-A_j|以及令上 ...