查看MySQL 5.7 内部文档存储

MySQL5.7.12是一个重要的新版本,因为它包含相当多的新特性:

  1. 文档存储和“MongoDB”像NoSQL界面连接到JSON存储
  2. Protocol X/X插件,它可用于异步查询
  3. New MySQL shell

旧的MySQL 5.7版本已经有一个JSON数据类型,和一个能够创建虚拟列的索引。新文档存储的功能是基于JSON数据类型的。那么,什么是文档存储呢?它是一个附加在MySQL表上的JSON字段。接下来,让我们深入了解它,看看它是如何工作的。

首先,使用X插件并安装MySQL;
其次,登录shell:

mysqlsh--uri root@localhost

然后,运行命令(在JavaScript模式中,可以切换到SQL或Python):

mysqlsh--uri root@localhost

Creating anXSession toroot@localhost:33060

Enter password:

No defaultschema selected.

Welcome toMySQL Shell1.0.3Development Preview

Copyright(c)2016,Oracle and/orits affiliates.All rights reserved.

Oracle isaregistered trademark of Oracle Corporation and/orits

affiliates.Other names may be trademarks of their respective

owners.

Type'help','h'or'?'forhelp.

Currently inJavaScript mode.Usesql toswitchtoSQL mode andexecute queries.

mysql-js>db=session.getSchema('world_x')<Schema:world_x>

mysql-js>db.getCollections()

"CountryInfo":<Collection:CountryInfo>

现在,如何要使文档存储的集合不同于一个正常的表?为了找到答案,我们连接到了一个正常的MySQL:

mysqlworld_x

Readingtableinformationforcompletionoftableandcolumnnames

Youcanturnoffthisfeaturetogetaquickerstartupwith-A

WelcometotheMySQLmonitor.Commandsendwith;org.

YourMySQLconnectionidis2396

Serverversion:5.7.12MySQLCommunityServer(GPL)

Copyright(c)2000,2016,Oracleand/oritsaffiliates.Allrightsreserved.

OracleisaregisteredtrademarkofOracleCorporationand/orits

affiliates.Othernamesmaybetrademarksoftheirrespective

owners.

Type'help;'or'h'forhelp.Type'c'toclearthecurrentinputstatement.

mysql>showcreatetableCountryInfo

***************************1.row***************************

Table:CountryInfo

CreateTable:CREATETABLE`CountryInfo`(

`doc`jsonDEFAULTNULL,

`_id`varchar(32)GENERATEDALWAYSAS(json_unquote(json_extract(`doc`,'$._id')))STOREDNOT NULL,

PRIMARY KEY(`_id`)

)ENGINE=InnoDBDEFAULTCHARSET=utf8

1rowinset(0.00sec)

mysql>showtables;

+-------------------+

|Tables_in_world_x|

+-------------------+

|City|

|Country|

|CountryInfo|

|CountryLanguage|

+-------------------+

4rowsinset(0.00sec)

所以文档存储实际上是一个InnoDB表与一个字段:doc json+主键,这是一个生成的列。

我们也可以看到,在world_x数据库中有四个表,但db.getCollections()只显示了一个。MySQL是如何区分一个“正常”表和“文档存储”表?为了找到答案,我们可以启用通用查询日志,看到正在执行的查询 ︰

$mysql-e'set global general_log=1'

$tail/var/log/general.log

2016-05-17T20:53:12.772114Z186Query  SELECT table_name,COUNT(table_name)cFROM information_schema.columnsWHERE((column_name='doc'anddata_type='json')OR(column_name='_id'andgeneration_expression='json_unquote(json_extract(`doc`,''$._id''))'))ANDtable_schema='world_x'GROUP BY table_name HAVINGc=2

2016-05-17T20:53:12.773834Z186Query  SHOW FULL TABLES FROM`world_x

正如你所看到的,每个表都有一个特定的结构(doc JSON或者特定generation_expression)。它被认为是一个JSON存储。现在,MySQL是如何转化成.find 或 .add来构造实际的MySQL查询?让我们运行一个示例查询:

mysql-js>db.getCollection("CountryInfo").find('Name= "United States"').limit(1)

"GNP":8510700,

"IndepYear":1776,

"Name":"United States",

"_id":"USA",

"demographics":{

"LifeExpectancy":77.0999984741211,

"Population":278357000

"geography":{

"Continent":"North America",

"Region":"North America",

"SurfaceArea":9363520

"government":{

"GovernmentForm":"Federal Republic",

"HeadOfState":"George W. Bush",

"HeadOfState_title":"President"

1documentinset(0.02sec)

现在,再看看慢速查询日志:

2016-05-17T21:02:21.213899Z186Query  SELECT doc FROM`world_x`.`CountryInfo`WHERE(JSON_EXTRACT(doc,'$.Name')='United States')LIMIT1

我们可以验证 MySQL 转换到 SQL 的所有文档存储命令。这也意味着它是现有 MySQL 存储级别在与其他存储引擎工作时100%透明。让我们确认,只是为了好玩而已︰

mysql>alter table CountryInfo engine=MyISAM;

Query OK,239rows affected(0.06sec)

Records:239Duplicates:0Warnings:0

mysql-js>db.getCollection("CountryInfo").find('Name= "United States"').limit(1)

"GNP":8510700,

"IndepYear":1776,

"Name":"United States",

"_id":"USA",

"demographics":{

"LifeExpectancy":77.0999984741211,

"Population":278357000

"geography":{

"Continent":"North America",

"Region":"North America",

"SurfaceArea":9363520

"government":{

"GovernmentForm":"Federal Republic",

"HeadOfState":"George W. Bush",

"HeadOfState_title":"President"

1document inset(0.00sec)

2016-05-17T21:09:21.074726Z2399Query  alter table CountryInfo engine=MyISAM

2016-05-17T21:09:41.037575Z2399Quit

2016-05-17T21:09:43.014209Z186Query  SELECT doc FROM`world_x`.`CountryInfo`WHERE(JSON_EXTRACT(doc,'$.Name')='United States')LIMIT1

现在,性能如何?我们可以通过简单地将SQL查询和运行得到解释:

mysql>explain SELECT doc FROM`world_x`.`CountryInfo`WHERE(JSON_EXTRACT(doc,'$.Name')='United States')LIMIT1

***************************1.row***************************

id:1

select_type:SIMPLE

table:CountryInfo

partitions:NULL

type:ALL

possible_keys:NULL

key:NULL

key_len:NULL

ref:NULL

rows:239

filtered:100.00

Extra:Using where

1row inset,1warning(0.00sec)

这看起来它好像没有使用索引。这是因为它没有索引名称。我们可以添加一个吗?当然,我们可以添加一个虚拟列,然后来索引它:

mysql>altertableCountryInfoaddcolumnNamevarchar(255)

->GENERATEDALWAYSAS(json_unquote(json_extract(`doc`,'$.Name')))VIRTUAL;

QueryOK,0rowsaffected(0.12sec)

Records:0Duplicates:0Warnings:0

mysql>altertableCountryInfoaddkey(Name);

QueryOK,0rowsaffected(0.02sec)

Records:0Duplicates:0Warnings:0

mysql>explainSELECTdocFROM`world_x`.`CountryInfo`WHERE(JSON_EXTRACT(doc,'$.Name')='United States')LIMIT1

***************************1.row***************************

id:1

select_type:SIMPLE

table:CountryInfo

partitions:NULL

type:ref

possible_keys:name

key:name

key_len:768

ref:const

rows:1

filtered:100.00

Extra:NULL

1rowinset,1warning(0.00sec)

真的很酷!我们添加了一个索引,现在我们就开始使用它。注意,我们不必参考新领域,放心,MySQL的优化器是足够聪明的(JSON_EXTRACT(DOC,’$.Name’)=’ 美国 ’ 在虚拟列索引扫描。

但是请注意:JSON属性是需要区分大小写的。如果你要使用(doc,’$.name') ,而不是(doc,'$.Name’),它是不会产生错误,但只会打破搜索和查询寻找“名称”,它将返回到0行。

最后,如果你仔细观察db.getCollection的输出(“CountryInfo”).find(‘Name = “美国”’).limit(1),你得注意到数据库已经过时的信息:

"government":{

"GovernmentForm":"Federal Republic",

"HeadOfState":"George W. Bush",

"HeadOfState_title":"President"

让我们把”乔治•布什”更改为“奥巴马”,将用.modify 子句 ︰

mysql-js>db.CountryInfo.modify("Name = 'United States'").set("government.HeadOfState","Barack Obama");

Query OK,1item affected(0.02sec)

mysql-js>db.CountryInfo.find('Name= "United States"')

"GNP":8510700,

"IndepYear":1776,

"Name":"United States",

"_id":"USA",

"demographics":{

"LifeExpectancy":77.0999984741211,

"Population":278357000

"geography":{

"Continent":"North America",

"Region":"North America",

"SurfaceArea":9363520

"government":{

"GovernmentForm":"Federal Republic",

"HeadOfState":"Barack Obama",

"HeadOfState_title":"President"

1documentinset(0.00sec)

总结

文件存储是一个有趣的概念,也是目前较好的MySQL JSON功能插件。在某些情况下,使用新的.find/.add/.modify 方法可方便的代替原始的SQL语句。

有些人可能会问,“为什么你要在数据库内部使用JSON来进行文档存储和存储信息?“在 JSON 中存储的数据,在某些特定的情况下是非常有用的,例如 ︰

  1. 你已经有一个JSON,并且需要存储。那么,使用JSON数据类型将更方便、更有效。
  2. 你有一个灵活的架构,以典型的互联网为例,一些传感器可能只发送温度数据,有些可能还会发送温度、湿度、光等(但光信息只记录在一天)。如果一个新的传感器开始发送新的数据类型时,它会以JSON格式存储,这样可以更加方便的让你无需提前声明,也不必运行“alter table”。

原文:Looking Inside the MySQL 5.7 Document Store

一. 概述 5 二. 卸载MySQL数据库 6 2.1 备份数据库 6 2.2 卸载MySQL数据库 6 2.2.1 检查MySQL服务并关闭服务进程 6 2.2.2 查找MySQL的安装目录并彻底删除 6 2.2.3 删除MySQL配置文件 7 2.2.4 删除MySQL用户以及用户组 7 三. 安装MySQL数据库 9 3.1 安装MySQL数据库 9 3.1.1 下载MySQL安装包 9 3.1.2 上传并解压MySQL安装包 9 3.1.3 添加系统MySQL组和MySQL用户 10 3.1.4 安装MySQL数据库 10 3.1.5 启动MySQL服务和添加开机启动MySQL服务 11 3.1.6 修改MySQL的root用户密码 13 3.1.7 把MySQL客户端放到默认路径。 13 3.2 配置MySQL数据库远程访问权限 13 3.2.1 进入 mysql 14 3.2.2 使用mysql数据库 14 3.2.3 查看用户表 14 3.2.4 创建远程登录用户并授权 15 3.2.5 强制刷新权限 15 3.3 恢复备份的数据库 15 四. MySQL数据库数据迁移 16 4.1 迁移前准备 16 4.1.1 停止MySQL数据库服务 16 4.1.2 创建数据库迁移目录 16 4.2 数据迁移 17 4.2.1 复制数据库数据到迁移目录 17 4.2.2 修改配置并启动服务 17 五. Mysql 数据目录存放位置更改 19 六. MySQL主从配置 20 6.1 基本条件 20 6.2 安装MySQL数据库 20 6.3 主机配置 20 6.3.1 修改my.cnf配置文件 20 6.3.2 初始化bin-log日志 21 6.4 从机配置 21 6.4.1 修改my.cnf配置文件 21 6.4.2 添加同步主机配置 22 七. MySQL互为主从配置 24 7.1 基本条件 24 7.2 安装MySQL数据库 24 7.3 主机A配置 24 7.3.1 修改my.cnf配置文件 24 7.3.2 给主机B赋予mysql权限 25 7.3.3 初始化bin-log日志 26 7.4 主机B配置 27 7.4.1 修改my.cnf配置文件 27 7.4.2 给主机A赋予mysql权限 28 7.4.3 初始化bin-log日志 29 7.5 同步配置 30 7.5.1 主机A设置同步 30 7.5.2 主机B设置同步 31 八. my.cnf配置样例 34 8.1 my.cnf推荐配置 34 8.2 my.cnf主从推荐配置 35 8.2.1 主机my.cnf推荐配置 35 8.2.2 从机my.cnf推荐配置 35 8.3 my.cnf互为主从推荐配置 36 8.3.1 主机A my.cnf推荐配置 36 8.3.2 主机B my.cnf推荐配置 37 8.3.3 鄙人的my.cnf简单配置 38 九. Mysql根据ibd文件恢复数据 40 9.1 创建新数据表,和源数据表一致 40 9.2 删除新数据表的表空间 40 9.3 将待恢复的<table_name>.ibd文件copy到目标数据库文件夹下,并修改文件权限 40 9.4 导入表空间 41 十. 根据frm文件恢复表结构 42 10.1 新建同名的表 42 10.1.1 建立新的表结构 42 10.1.2 修改新建的数据表结构为17个字段 43
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值