第20章将MySQL用作文档存储

目录

20.1 MySQL文档存储的接口
20.2文档存储概念
20.3 JavaScript快速入门指南:用于文档存储的MySQL Shell
20.3.1导入数据库示例
20.3.2 MySQL Shell
20.3.3文件和收藏
20.3.4关系表
20.3.5表格中的文件
20.4 Python快速入门指南:用于文档存储的MySQL Shell
20.4.1导入数据库示例
20.4.2 MySQL Shell
20.4.3文件和收藏
20.4.4关系表
20.4.5表格中的文件
20.5 X插件
20.5.1检查X插件安装
20.5.2禁用X插件
20.5.3使用带X插件的安全连接
20.5.4将X插件与缓存SHA-2身份验证插件一起使用
20.5.5 X插件选项和变量
20.5.6监控X插件

本章介绍了使用MySQL作为文档存储的另一种方法,有时也称为使用NoSQL如果您打算以传统(SQL)方式使用MySQL,那么本章可能与您无关。

传统上,诸如MySQL之类的关系数据库通常需要在存储文档之前定义模式。本节中描述的功能使您可以将MySQL用作文档存储,这是一种无模式,因此模式灵活的文档存储系统。例如,在创建描述产品的文档时,在存储和操作文档之前,您无需了解和定义任何产品的所有可能属性。这与使用关系数据库并将产品存储在表中不同,此时必须知道并定义表的所有列,然后才能将任何产品添加到数据库中。通过本章介绍的功能,您可以选择仅使用文档存储模型配置MySQL的方式,

要将MySQL用作文档存储,请使用以下服务器功能:

20.1 MySQL文档存储的接口

要使用MySQL作为文档存储,您可以使用专用组件和一组支持与MySQL服务器通信的客户端来开发基于文档的应用程序。

20.2文档存储概念

本节介绍将MySQL用作文档存储的过程中引入的概念。

JSON文档

JSON文档是由键值对组成的数据结构,是使用MySQL作为文档存储的基本结构。例如,world_x架构(在本章后面安装)包含此文档:

{
    “GNP”:。6,
    “IndepYear”:1967年,
    “名字”:“西兰”,
    “_id”:“SEA”,
    “人口统计资料”:{
        “LifeExpectancy”:79,
        “人口”:27
    },
    “地理”:{
        “大陆”:“欧洲”,
        “地区”:“英属群岛”,
        “SurfaceArea”:193
    },
    “政府”: {
        “政府形式”:“君主制”,
        “HeadOfState”:“Michael Bates”
    }
}

该文档显示键的值可以是简单的数据类型,例如整数或字符串,但也可以包含其他文档,数组和文档列表。例如, geography键的值由多个键值对组成。使用MySQL二进制JSON对象,通过JSONMySQL数据类型在内部表示JSON文档

文档与传统关系数据库中已知的表之间最重要的区别在于,文档的结构不必事先定义,并且集合可以包含具有不同结构的多个文档。另一方面,关系表要求定义其结构,并且表中的所有行必须包含相同的列。

采集

集合是用于在MySQL数据库中存储JSON文档的容器。应用程序通常针对一组文档运行操作,例如查找特定文档。

CRUD操作

可以针对集合发出的四个基本操作是创建,读取,更新和删除(CRUD)。就MySQL而言,这意味着:

  • 创建新文档(插入或添加)

  • 阅读一个或多个文档(查询)

  • 更新一个或多个文档

  • 删除一个或多个文档

20.3 JavaScript快速入门指南:用于文档存储的MySQL Shell

本快速入门指南提供了使用MySQL Shell以交互方式开始构建文档存储应用程序原型的说明。该指南包括以下主题:

  • MySQL功能,MySQL Shell和 world_x数据库示例简介。

  • 管理集合和文档的操作。

  • 管理关系表的操作。

  • 适用于表中文档的操作。

相关信息

20.3.1导入数据库示例

world_x数据库样本包含一个JSON收集和一组三个关系表:

  • 采集

    • countryinfo:有关世界各国的信息。

    • country:关于世界各国的最少信息。

    • city:有关这些国家/地区的部分城市的信息。

    • countrylanguage:每个国家/地区使用的语言。

要求

要遵循这个快速入门指南,您需要一个安装了X插件的MySQL服务器,8.0中的默认设置和用作客户端的MySQL Shell。请参阅 安装MySQL Shell在加载world_x本指南的示例数据库之前启动MySQL

下载并导入world_x数据库

要准备world_x数据库示例,请按照下列步骤操作:

  1. 下载 world_x-db.zip

  2. 将安装存档解压缩到临时位置,例如/tmp/解压缩归档会产生一个名为的文件 world_x.sql

  3. world_x.sql文件导入数据库。你可以:

    • 在SQL模式下启动MySQL Shell并通过发出以下命令导入文件:

      mysqlsh -u root --sql --file /tmp/world_x-db/world_x.sql
      输入密码: ****
      
    • 在MySQL Shell运行时将MySQL Shell设置为SQL模式,并在MySQL Shell运行时通过发出以下命令来获取模式文件:

      \source /tmp/world_x-db/world_x.sql
      切换到SQL模式...命令以;结尾;
      \source /tmp/world_x-db/world_x.sql
      

    替换/tmp/world_x.sql系统上文件的路径 出现提示时输入密码。只要帐户具有创建新数据库的权限,就可以使用非root帐户。

相关信息

20.3.2 MySQL Shell

MySQL Shell是MySQL Server的统一脚本接口。它支持JavaScript和Python中的脚本。JavaScript是默认的处理模式。在大多数情况下,您需要一个帐户才能连接到MySQL服务器实例。

启动MySQL Shell

安装并启动MySQL服务器后,将MySQL Shell连接到服务器实例。默认情况下,MySQL Shell使用X协议进行连接。您需要知道您计划连接的MySQL服务器实例的地址。

如果MySQL Shell尚未运行,请打开终端窗口并发出:

mysqlsh name@host/world_x

或者,如果MySQL Shell已经运行,请使用以下 \connect命令:

\connect name@host/world_x

您需要指定要将MySQL Shell连接到的MySQL服务器实例的地址。例如,在前面的示例中:

  • name 代表您的MySQL帐户的用户名。

  • MySQL Shell会提示您输入密码。

  • 此会话的默认架构是 world_x数据库。有关设置world_x数据库示例的说明,请参见 第20.3.1节“导入数据库示例”

MySQL Shell打开后,mysql-js> 提示符表明此会话的活动语言是JavaScript。

MySQL的-JS>

当您在没有host参数的情况下运行mysqlsh时,MySQL Shell会尝试连接到端口33060上localhost接口上运行的服务器实例。有关更多信息,请参阅MySQL Shell连接

MySQL Shell支持输入行编辑,如下所示:

  • 箭头右箭头键在当前输入行内水平移动。

  • 向上箭头向下箭头键在上一组输入的行中上下移动。

  • 退格键删除光标前的字符,键入新字符将在光标位置输入。

  • Enter将当前输入行发送到服务器。

获取MySQL Shell的帮助

在命令解释程序的提示符下 键入mysqlsh --help以获取命令行选项列表。

mysqlsh --help

键入\help在MySQL的壳牌提示可用的命令及其说明的列表。

MySQL的-JS> \help

键入\help后跟命令名称,以获取有关单个MySQL Shell命令的详细帮助。例如,要查看\connect 命令的帮助,请键入:

MySQL的-JS> \help \connect

退出MySQL Shell

要退出MySQL Shell,请键入以下命令:

MySQL的-JS> \quit

相关信息

20.3.3文件和收藏

在MySQL中,集合包含可以添加,查找,更新和删除的JSON文档。集合是可以创建,列出和删除的模式中的容器。

本节中的示例使用world_x数据库中的countryinfo集合 有关设置world_x数据库示例的说明,请参见 第20.3.1节“导入数据库示例”

文件

在MySQL中,文档表示为JSON对象。在内部,它们以高效的二进制格式存储,可以快速查找和更新。

  • JavaScript的简单文档格式:

    {field1:“value”,field2:10,“field 3”:null}
    

一组文档由一组用逗号分隔并包含在字符[]文字中的文档组成

  • JavaScript的简单文档数组:

    [{姓名:“Aruba”,_id:“ABW”},{姓名:“安哥拉”,_id:“AGO”}]
    

MySQL支持JSON文档中的以下JavaScript值类型:

  • 数字(整数和浮点数)

  • 字符串

  • 布尔值(False和True)

  • 空值

  • 更多JSON值的数组

  • 嵌套(或嵌入)更多JSON值的对象

集合

集合是用于共享目的并且可能共享一个或多个索引的文档的容器。每个集合都有一个唯一的名称,并存在于单个模式中。

术语模式等同于数据库,这意味着一组数据库对象(与用于强制数据结构和约束的关系模式相对)。架构不强制对集合中的文档进行一致性。

在本快速入门指南中:

  • 基本对象包括:

    对象形式 描述
    db db是分配给当前活动模式的全局变量。如果要对架构运行操作(例如,要检索集合),可以使用可用于该db 变量的方法
    db.getCollections() db.getCollections() 包含模式中的集合列表。使用列表获取对集合对象的引用,迭代它们,等等。
  • 集合的基本操作包括:

    运作形式 描述
    db.name.add() 的add() 方法插入一个文档或文档放到指定的集合列表。
    db.name.find() 发现() 方法返回指定的集合中的部分或全部文件。
    db.name.modify() 修改() 指定的收集方法的更新文件。
    db.name.remove() 删除() 方法删除一个文件或从指定收集的文件清单。

相关信息

20.3.3.1创建,列出和删除集合

在MySQL Shell中,您可以创建新集合,获取模式中现有集合的列表,以及从模式中删除现有集合。集合名称区分大小写,每个集合名称必须唯一。

确认架构

要显示分配给模式变量的值,请发出:

MySQL的-JS> db

如果架构值不是Schema:world_x,则db通过发出以下命令设置变量:

MySQL的-JS> \use world_x
创建一个集合

要在现有模式中创建新集合,请使用该 db对象的 createCollection()方法。以下示例创建flagsworld_x数据库中调用的集合

MySQL的-JS> db.createCollection("flags")

该方法返回一个集合对象。

<收集:标志>
列表集合

要显示world_x 数据库中的所有集合,请使用db对象的 getCollections()方法。您当前连接的服务器返回的集合显示在括号中。

MySQL的-JS> db.getCollections()
[
    <收集:countryinfo>
    <收集:标志>
]
删除一个集合

要从数据库中删除现有集合,请使用该 db对象的 dropCollection()方法。例如,要从world_x 数据库中删除flags集合,请键入:

MySQL的-JS> db.dropCollection("flags")

dropCollection()方法还在MySQL Shell中用于从数据库中删除关系表。

相关信息

20.3.3.2添加文档

使用该add()方法使用MySQL Shell将一个文档或文档列表插入到现有集合中。本节中的所有示例都使用world_x 架构中提供的countryinfo集合

添加文档

将以下文档插入countryinfo集合中。由于这是多行内容,请按 两次Enter键以插入文档。

MySQL的-JS> db.countryinfo.add(
 {
    GNP: .6,
    IndepYear: 1967,
    Name: "Sealand",
    demographics: {
        LifeExpectancy: 79,
        Population: 27
    },
    geography: {
        Continent: "Europe",
        Region: "British Islands",
        SurfaceArea: 193
    },
    government: {
        GovernmentForm: "Monarchy",
        HeadOfState: "Michael Bates"
    }
  }
)

该方法返回操作的状态。

每个文件需要所谓的标识符字段 _id_id字段的值 在同一集合中的所有文档中必须是唯一的。在MySQL 8.0.11及更高版本中,文档ID由服务器而不是客户端生成,因此MySQL Shell不会自动设置 _id值。_id如果文档不包含该_id字段,则8.0.11或更高版本的MySQL服务器会设置一个在早期8.0版本或5.7版本的MySQL服务器_id在这种情况下不设置 值,因此您必须明确指定它。如果不这样做,MySQL Shell将返回错误5115 Document缺少必填字段

相关信息

20.3.3.3查找文件

您可以使用该find()方法从数据库中的集合中查询和返回文档。MySQL Shell提供了与方法一起使用的其他方法,用于 find()过滤和排序返回的文档。

MySQL提供以下操作符来指定搜索条件:OR||), ( AND),&&, , XORISNOTBETWEENINLIKE!=<>>>=<<=&|<<>>+- */~%

查找集合中的所有文档

要返回集合中的所有文档,请使用该 find()方法而不指定搜索条件。例如,以下操作将返回countryinfo集合中的所有文档。

MySQL的-JS> db.countryinfo.find()
[
     {
          “GNP”:828,
          “IndepYear”:null,
          “名称”:“阿鲁巴”,
          “_id”:“ABW”,
          “人口统计资料”:{
              “LifeExpectancy”:78.4000015258789,
              “人口”:103000
          },
          “地理”:{
              “大陆”:“北美”,
              “地区”:“加勒比”,
              “SurfaceArea”:193
          },
          “政府”: {
              “政府表格”:“荷兰非都会领土”,
              “HeadOfState”:“Beatrix”
          }
          ...
      }
 ]
240套文件(0.00秒)

除了集合中的所有文档之外,该方法还生成包含操作信息的结果。

空集(无匹配文档)返回以下信息:

空集(0.00秒) 
过滤搜索

您可以使用该find()方法包含搜索条件 形成搜索条件的表达式的语法与传统MySQL 第12章,函数和运算符的语法相同您必须将所有表达式括在引号中。

本节中的所有示例都使用world_x数据库中的countryinfo集合为简洁起见,一些示例不显示输出。

简单的搜索条件可以包括 Name字段和我们知道的文档中的值。以下示例返回单个文档:

MySQL的-JS> db.countryinfo.find("Name = 'Australia'")
[
    {
        “GNP”:351182,
        “IndepYear”:1901年,
        “名称”:“澳大利亚”,
        “_id”:“AUS”,
        “人口统计资料”:{
            “LifeExpectancy”:79.80000305175781,
            “人口”:18886000
        },
        “地理”:{
            “大陆”:“大洋洲”,
            “地区”:“澳大利亚和新西兰”,
            “SurfaceArea”:7741220
        },
        “政府”: {
            “政府形式”:“君主立宪制,联邦”,
            “HeadOfState”:“伊丽莎白二世”
        }
    }
]

以下示例搜索GNP高于5000亿美元的所有国家/地区。countryinfo集合以百万为单位测量GNP。

mysql-js> db.countryinfo.find("GNP > 500000")
... [ 输出已删除 ]
10套文件(0.00秒)

以下查询中的“人口”字段嵌入在人口统计信息对象中。要访问嵌入字段,请使用人口统计信息和人口统计之间的时间段来确定关系。文档和字段名称区分大小写。

mysql-js> db.countryinfo.find("GNP > 500000 and demographics.Population < 100000000")
... [ 输出已删除 ]
6套文件(0.00秒)

以下表达式中的算术运算符用于查询人均GNP高于$ 30000的国家/地区。搜索条件可以包括算术运算符和大多数MySQL函数。

注意

countryinfo集合中的七个文档的人口值为零。警告消息显示在输出的末尾。

mysql-js> db.countryinfo.find("GNP*1000000/demographics.Population > 30000")
... [ 输出已删除 ]
9套文件,7条警告(0.00秒)
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0

您可以使用该bind()方法将值与搜索条件分开例如,不是将硬编码的国家/地区名称指定为条件,而是替换命名的占位符,该占位符由冒号后跟以字母开头的名称组成,例如 country然后使用 如下方法: bind(placeholder, value)

MySQL的-JS> db.countryinfo.find("Name = :country").bind("country", "Italy")
[
    {
        “GNP”:1161755,
        “IndepYear”:1861年,
        “名称”:“意大利”,
        “_id”:“ITA”,
        “人口统计资料”:{
            “LifeExpectancy”:79,
            “人口”:57680000
        },
        “地理”:{
            “大陆”:“欧洲”,
            “地区”:“南欧”,
            “SurfaceArea”:301316
        },
        “政府”: {
            “政府表格”:“共和国”,
            “HeadOfState”:“Carlo Azeglio Ciampi”
        }
    }
]
1套文件(0.01秒)
小费

在程序中,绑定使您可以在表达式中指定占位符,这些占位符在执行之前用值填充,并且可以根据需要从自动转义中受益。

始终使用绑定来清理输入。避免在使用字符串连接的查询中引入值,这会产生无效输入,并且在某些情况下会导致安全问题。

您可以使用占位符和bind() 方法创建已保存的搜索,然后可以使用不同的值调用这些搜索。例如,为国家/地区创建已保存的搜索:

mysql-js> var myFind = db.countryinfo.find("Name = :country")
mysql-js>myFind.bind('country', 'France')
[
    {
        “GNP”:1424285,
        “IndepYear”:843,
        “名字”:“法国”,
        “_id”:“FRA”,
        “人口统计资料”:{
            “LifeExpectancy”:78.80000305175781,
            “人口”:59225700
        },
        “地理”:{
            “大陆”:“欧洲”,
            “地区”:“西欧”,
            “SurfaceArea”:551500
        },
        “政府”: {
            “政府表格”:“共和国”,
            “HeadOfState”:“Jacques Chirac”
        }
    }
]
1套文件(0.0028秒)

MySQL的-JS> myFind.bind('country', 'Germany')
[
    {
        “GNP”:2133367, 
        “IndepYear”:1955年, 
        “名字”:“德国”, 
        “_id”:“DEU”, 
        “人口统计资料”:{
            “LifeExpectancy”:77.4000015258789, 
            “人口”:82164700
        }, 
        “地理”:{
            “大陆”:“欧洲”, 
            “地区”:“西欧”, 
            “SurfaceArea”:357022
        }, 
        “政府”: {
            “政府表格”:“联邦共和国”, 
            “HeadOfState”:“Johannes Rau”
        }
    }
]
1套文件(0.0026秒)
项目结果

您可以返回文档的特定字段,而不是返回所有字段。以下示例返回countryinfo集合中与搜索条件匹配的所有文档的GNP和Name字段。

使用该fields()方法传递要返回的字段列表。

MySQL的-JS> db.countryinfo.find("GNP > 5000000").fields(["GNP", "Name"])
[
    {
        “GNP”:8510700,
        “名字”:“美国”
    }
]
1套文件(0.00秒)
 

此外,您可以使用描述要返回的文档的表达式更改返回的文档 - 添加,重命名,嵌套甚至计算新字段值。例如,使用以下表达式更改字段的名称以仅返回两个文档。

MySQL的-JS> db.countryinfo.find().
fields(mysqlx.expr('{"Name": upper(Name), "GNPPerCapita": GNP*1000000/demographics.Population}')).
limit(2)
[
    {
        “GNPPerCapita”:8038.834951456311,
        “名字”:“ARUBA”
    },
    {
        “GNPPerCapita”:263.0281690140845,
        “名字”:“阿富汗”
    }
]
2套文件(0.00秒)
限制,排序和跳过结果

您可以应用limit()sort()skip() 方法来管理由返回文档的数量和顺序find()的方法。

要指定结果集中包含的文档数,请将limit()方法附加值附加find()方法中。以下查询返回countryinfo集合中的前五个文档。

mysql-js> db.countryinfo.find().limit(5)
... [ 输出已删除 ]
5套文件(0.00秒)

要指定结果的顺序,请将sort()方法附加 find()方法。sort()一个或多个字段的列表传递给方法,以便根据 需要进行排序,并可选择地使用descending(desc)或ascending(asc)属性。升序是默认订单类型。

例如,以下查询按IndepYear字段对所有文档进行排序,然后按降序返回前八个文档。

mysql-js> db.countryinfo.find().sort(["IndepYear desc"]).limit(8)
... [ 输出已删除 ]
8套文件(0.00秒)

默认情况下,该limit()方法从集合中的第一个文档开始。您可以使用该 skip()方法更改起始文档。例如,要忽略第一个文档并返回与条件匹配的下八个文档,请将skip()传递给 方法1。

mysql-js> db.countryinfo.find().sort(["IndepYear desc"]).limit(8).skip(1)
... [ 输出已删除 ]
8套文件(0.00秒)
相关信息

20.3.3.4修改文件

您可以使用该modify()方法更新集合中的一个或多个文档。X DevAPI提供了与该modify() 方法一起使用的其他方法:

  • 设置和取消设置文档中的字段。

  • 追加,插入和删除数组。

  • 绑定,限制和排序要修改的文档。

设置和取消设置字段

modify()方法通过过滤集合以仅包括要修改的文档,然后将您指定的操作应用于这些文档来工作。

在以下示例中,该modify() 方法使用搜索条件来标识要更改的文档,然后该set()方法替换嵌套的人口统计信息对象中的两个值。

MySQL的-JS> db.countryinfo.modify("_id = 'SEA'").\
set("demographics", {LifeExpectancy: 78, Population: 28})
查询OK,1项受影响(0.04秒)

修改文档后,使用该find() 方法验证更改。

要从文档中删除内容,请使用 modify()unset() 方法。例如,以下查询从与搜索条件匹配的文档中删除GNP。

MySQL的-JS> db.countryinfo.modify("Name = 'Sealand'").unset("GNP")
查询OK,1项受影响(0.01秒)   

使用该find()方法验证更改。

MySQL的-JS> db.countryinfo.find("Name = 'Sealand'")
[
    {
        “IndepYear”:1967年,
        “名字”:“西兰”,
        “_id”:“SEA”,
        “人口统计资料”:{
            “LifeExpectancy”:78,
            “人口”:28
        },
        “地理”:{
            “大陆”:“欧洲”,
            “地区”:“英属群岛”,
            “SurfaceArea”:193
        },
        “政府”: {
            “政府形式”:“君主制”,
            “HeadOfState”:“Michael Bates”
        }
    }
]
1套文件(0.00秒)
追加,插入和删除数组

在数组中的元素附加到阵列字段,或插入,或删除单元,使用 arrayAppend()arrayInsert()arrayDelete()方法。以下示例修改countryinfo集合以启用对国际机场的跟踪。

第一个示例使用modify()set()方法在所有文档中创建新的Airports字段。

警告

修改文档时请小心,而不指定搜索条件。此操作将修改集合中的所有文档。

MySQL的-JS> db.countryinfo.modify("true").set("Airports", [])
查询OK,受影响的240件(0.07秒)

添加机场字段后,下一个示例使用该 arrayAppend()方法将新机场添加到其中一个文档。以下示例中的$ .Airports表示当前文档的Airports字段。

MySQL的-JS> db.countryinfo.modify("Name = 'France'").arrayAppend("$.Airports", "ORY")
查询OK,1项受影响(0.02秒)

使用db.countryinfo.find("Name = 'France'")查看更改。

要在数组中的不同位置插入元素,请使用该arrayInsert()方法指定要在路径表达式中插入的索引。在这种情况下,索引是0,或者是数组中的第一个元素。

MySQL的-JS> db.countryinfo.modify("Name = 'France'").arrayInsert("$.Airports[0]", "CDG")
查询OK,1项受影响(0.04秒)

要从数组中删除元素,必须将要删除的元素arrayDelete()的索引传递给 方法。

MySQL的-JS> db.countryinfo.modify("Name = 'France'").arrayDelete("$.Airports[1]")
查询OK,1项受影响(0.03秒)
相关信息

20.3.3.5删除文件

您可以使用该remove()方法从数据库中的集合中删除部分或全部文档。X DevAPI提供了与方法一起使用的其他方法,用于 remove()过滤和排序要删除的文档。

使用条件删除文档

下面的示例将搜索条件传递给 remove()方法。符合条件的所有文档都将从countryinfo集合中删除。在此示例中,一个文档与条件匹配。

MySQL的-JS> db.countryinfo.remove("_id = 'SEA'")
查询OK,1项受影响(0.02秒)
删除第一个文档

要删除countryinfo集合中的第一个文档,请使用limit()值为1 方法。

MySQL的-JS> db.countryinfo.remove("true").limit(1)
查询OK,1项受影响(0.03秒)
删除订单中的最后一个文档

以下示例按国家/地区名称删除countryinfo集合中的最后一个文档。

MySQL的-JS> db.countryinfo.remove("true").sort(["Name desc"]).limit(1)
查询OK,1项受影响(0.02秒)
删除集合中的所有文档

您可以删除集合中的所有文档。为此,请使用该remove("true")方法而不指定任何搜索条件。

警告

在不指定搜索条件的情况下删除文档时请小心。此操作将删除集合中的所有文档。

相关信息

20.3.3.6创建和删除索引

索引用于快速查找具有特定字段值的文档。如果没有索引,MySQL必须从第一个文档开始,然后读取整个集合以查找相关字段。收集越大,成本越高。如果集合很大并且特定字段上的查询很常见,那么请考虑在文档内的特定字段上创建索引。

例如,以下查询将使用索引执行得更好:

mysql-js> db.countryinfo.find("demographics.Population < 100")
... [ 输出已删除 ]
8套文件(0.00秒)

createIndex()方法创建一个可以定义为非唯一或唯一的索引。使用该 field()方法链接应编制索引的字段。execute()创建或删除索引需要方法。

在MySQL中,该_id字段默认等效于主键。

添加非唯一索引

要创建非唯一索引,请将createIndex()方法名称传递给 方法。禁止复制索引名称。

在以下示例中,方法的第一个参数 field()指定人口统计信息对象内的人口字段,下一个参数指示该字段应编入索引为整数数值。最后一个参数指示字段是否应该要求NOT NULL约束。如果值为 false,则该字段可以包含 NULL值。

MySQL的-JS> db.countryinfo.createIndex("pop").
field("demographics.Population", "INTEGER", false).execute()
查询正常(0.04秒)
添加唯一索引

要创建唯一索引,请将createIndex()方法名称和mysqlx.IndexType.UNIQUE类型传递给 方法 Country "Name"是countryinfo集合中索引的另一个常见字段。在以下示例中, "Text(40)"表示要索引的字符数,并true指示该字段不能包含任何NULL值。

MySQL的-JS> db.countryinfo.createIndex("name", mysqlx.IndexType.UNIQUE).
field("Name", "TEXT(40)", true).execute()
查询正常(0.04秒)
删除索引

要删除索引,请将要删除的索引dropIndex() 的名称传递给方法。例如,您可以删除pop索引,如下所示:

MySQL的-JS> db.countryinfo.dropIndex("pop").execute()
查询正常(0.58秒)
相关信息

20.3.4关系表

您可以使用MySQL Shell不仅可以操作JSON文档,还可以操作关系表。

在MySQL中,每个关系表都与特定的存储引擎相关联。本节中的示例使用 数据库中的InnoDBworld_x

确认架构

要显示分配给模式变量的值,请键入 db

MySQL的-JS> db

如果架构值不是Schema:world_xdb则按如下方式设置变量:

MySQL的-JS> \use world_x

显示所有表格

要显示world_x 数据库中的所有关系表,请使用getTables()架构对象上的方法。

MySQL的-JS> db.getTables()
{
    “城市”:<表:城市>,
    “country”:<表:国家>,
    “countrylanguage”:<表:countrylanguage>
}

基本表操作

表格规定的基本操作包括:

运作形式 描述
db.name.insert() 所述 插入件() 方法插入一个或多个记录到指定的表。
db.name.select() 选择() 方法返回的指定表中的部分或全部记录。
db.name.update() 更新() 方法的更新记录的指定表中。
db.name.delete() 删除() 方法删除指定表中的一个或多个记录。

相关信息

20.3.4.1将记录插入表中

您可以将该insert()方法与该 values()方法一起使用,以将记录插入现有的关系表中。insert() 方法接受表中的各列或所有列。使用一种或多种values()方法指定要插入的值。

插入完整记录

要插入完整记录,请将insert()表中的所有列传递给 方法。然后将values()表中每列的一个值传递给方法。例如,要将新记录添加到world_x数据库中的城市表,请插入以下记录并按 两次Enter键

MySQL的-JS> db.city.insert("ID", "Name", "CountryCode", "District", "Info").
values(null, "Olympia", "USA", "Washington", '{"Population": 5000}')
查询OK,1项受影响(0.01秒)

city表有五列:ID,Name,CountryCode,District和Info。每个值必须与其表示的列的数据类型匹配。

插入部分记录

以下示例将值插入到city表的ID,Name和CountryCode列中。

MySQL的-JS> db.city.insert("ID", "Name", "CountryCode").
values(null, "Little Falls", "USA").values(null, "Happy Valley", "USA")
查询OK,2项受影响(0.03秒)

使用该insert() 方法指定列时,值的数量必须与列数匹配。在上一个示例中,您必须提供三个值以匹配指定的三个列。

相关信息

20.3.4.2选择表格

您可以使用该select()方法从数据库中的表中查询和返回记录。X DevAPI提供了与方法一起使用的其他方法,用于 select()过滤和排序返回的记录。

MySQL提供以下操作符来指定搜索条件:OR||), ( AND),&&, , XORISNOTBETWEENINLIKE!=<>>>=<<=&|<<>>+- */~%

选择所有记录

要发出返回现有表中所有记录的查询,请使用该select()方法而不指定搜索条件。以下示例选择world_x数据库中city表中的所有记录

注意

将空select() 方法的使用限制为交互式语句。始终在应用程序代码中使用显式列名选择。

MySQL的-JS> db.city.select()
+ ------ + ------------ + ------------- + ------------ +  - ----------------------- +
| ID | 名称| CountryCode | 区| 信息|
+ ------ + ------------ + ------------- + ------------ +  - ----------------------- +
| 1 | 喀布尔| AFG | Kabol | {“人口”:1780000} |
| 2 | 坎大哈| AFG | 坎大哈| {“人口”:237500} |
| 3 | 赫拉特| AFG | 赫拉特| {“人口”:186800} |
...... ...... ......
| 4079 | 拉法| PSE | 拉法| {“人口”:92020} |
+ ------ + ------- ---- + ------------- + ------------ + --- ---------------------- +
4082行(0.01秒)

空集(无匹配记录)返回以下信息:

空集(0.00秒)
过滤搜索

要发出返回一组表列的查询,请使用该 select()方法并指定要在方括号之间返回的列。此查询返回city表中的Name和CountryCode列。

MySQL的-JS> db.city.select(["Name", "CountryCode"])
+ ------------------- + ------------- +
| 名称| CountryCode |
+ ------------------- + ------------- +
| 喀布尔| AFG |
| 坎大哈| AFG |
| 赫拉特| AFG |
| Mazar-e-Sharif | AFG |
| Amsterdam | NLD |
......
| 拉法| PSE |
| 奥林匹亚| 美国|
| 小瀑布| 美国|
| 欢乐谷| 美国|
+ ------------------- + ------------- +
4082行(0.00秒)

要发出返回与特定搜索条件匹配的行的查询,请使用该where()方法包含这些条件。例如,以下示例返回以字母Z开头的城市的名称和国家/地区代码。

MySQL的-JS> db.city.select(["Name", "CountryCode"]).where("Name like 'Z%'")
+ ------------------- + ------------- +
| 名称| CountryCode |
+ ------------------- + ------------- +
| 赞斯塔德| NLD |
| Zoetermeer | NLD |
| 兹沃勒| NLD |
| Zenica | BIH |
| Zagazig | EGY |
| 萨拉戈萨| ESP |
| 三宝颜| PHL |
| Zahedan | IRN |
| 赞詹| IRN |
| Zabol | IRN |
| Zama | JPN |
| Zhezqazghan | KAZ |
| 郑州| CHN |
......
| Zeleznogorsk | RUS |
+ ------------------- + ------------- +
59行(0.00秒)

您可以使用该bind()方法将值与搜索条件分开例如,不是使用“Name ='Z%'”作为条件,而是替换一个命名的占位符,该占位符由冒号后跟一个以字母开头的名称组成,例如name然后在bind()方法中包含占位符和值, 如下所示:

MySQL的-JS> db.city.select(["Name", "CountryCode"]).
              where("Name like :name").bind("name", "Z%")
小费

在程序中,绑定使您可以在表达式中指定占位符,这些占位符在执行之前用值填充,并且可以根据需要从自动转义中受益。

始终使用绑定来清理输入。避免在使用字符串连接的查询中引入值,这会产生无效输入,并且在某些情况下会导致安全问题。

项目结果

要使用AND 运算符发出查询,请在where()方法中的搜索条件之间添加运算符

MySQL的-JS> db.city.select(["Name", "CountryCode"]).
               where("Name like 'Z%' and CountryCode = 'CHN'")
+ ---------------- + ------------- +
| 名称| CountryCode |
+ ---------------- + ------------- +
| 郑州| CHN |
| 淄博| CHN |
| 张家口| CHN |
| 株洲| CHN |
| 张江| CHN |
| 自贡| CHN |
| 枣庄| CHN |
......
| 张家港| CHN |
+ ---------------- + ------------- +
22行(0.01秒)

要指定多个条件运算符,可以将搜索条件括在括号中以更改运算符优先级。下面的示例演示的布局ANDOR运营商。

MySQL的-JS> db.city.select(["Name", "CountryCode"]).
where("Name like 'Z%' and (CountryCode = 'CHN' or CountryCode = 'RUS')")
+ ------------------- + ------------- +
| 名称| CountryCode |
+ ------------------- + ------------- +
| 郑州| CHN |
| 淄博| CHN |
| 张家口| CHN |
| 株洲| CHN |
......
| Zeleznogorsk | RUS |
+ ------------------- + ------------- +
29行(0.01秒)
限价,订单和抵消结果

您可以应用limit()orderBy()offSet() 方法来管理由返回的记录的数量和顺序select()的方法。

要指定结果集中包含的记录数,请将limit()方法附加值附加select()方法中。例如,以下查询返回国家/地区表中的前五个记录。

MySQL的-JS> db.country.select(["Code", "Name"]).limit(5)
+ ------ + ------------- +
| 代码| 名称|
+ ------ + ------------- +
| ABW | 阿鲁巴|
| AFG | 阿富汗|
| AGO | 安哥拉|
| 友邦保险| 安圭拉|
| ALB | 阿尔巴尼亚|
+ ------ + ------------- +
5行(0.00秒)

要指定结果的顺序,请将orderBy()方法附加 select()方法。orderBy()一个或多个列的列表传递给方法以进行排序,并根据需要将descending(desc)或ascending(asc)属性(可选传递给它 升序是默认订单类型。

例如,以下查询按名称列对所有记录进行排序,然后按降序返回前三个记录。

MySQL的-JS> db.country.select(["Code", "Name"]).orderBy(["Name desc"]).limit(3)
+ ------ + ------------ +
| 代码| 名称|
+ ------ + ------------ +
| ZWE | 津巴布韦|
| ZMB | 赞比亚|
| YUG | 南斯拉夫|
+ ------ + ------------ +
3组(0.00秒)

默认情况下,该limit()方法从表中的第一个记录开始。您可以使用该 offset()方法更改起始记录。例如,要忽略第一个记录并返回与条件匹配的下三个记录,请将offset()传递给 方法1。

MySQL的-JS> db.country.select(["Code", "Name"]).orderBy(["Name desc"]).limit(3).offset(1)
+ ------ + ------------ +
| 代码| 名称|
+ ------ + ------------ +
| ZMB | 赞比亚|
| YUG | 南斯拉夫|
| YEM | 也门|
+ ------ + ------------ +
3组(0.00秒)
相关信息

20.3.4.3更新表

您可以使用该update()方法修改表中的一个或多个记录。update() 方法通过过滤查询以仅包括要更新的记录,然后将您指定的操作应用于这些记录来工作。

要替换城市表中的城市名称,set()请将新城市名称传递给 方法。然后,传递给where()城市名称定位和替换的方法。以下示例将北京城市替换为北京。

MySQL的-JS> db.city.update().set("Name", "Beijing").where("Name = 'Peking'")
查询OK,1项受影响(0.04秒)

使用该select()方法验证更改。

MySQL的-JS> db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).where("Name = 'Beijing'")
+ ------ + ----------- ------------- + + ---------- + ----- ------------------------ +
| ID | 名称| CountryCode | 区| 信息|
+ ------ + ----------- ------------- + + ---------- + ----- ------------------------ +
| 1891年| 北京| CHN | 北京| {“人口”:7472000} |
+ ------ + ----------- ------------- + + ---------- + ----- ------------------------ +
1排(0.00秒)
相关信息

20.3.4.4删除表

您可以使用该delete()方法从数据库中的表中删除部分或全部记录。X DevAPI提供了与方法一起使用的其他方法,用于 delete()过滤和排序要删除的记录。

使用条件删除记录

下面的示例将搜索条件传递给 delete()方法。符合条件的所有记录都将从city表中删除。在此示例中,一条记录与条件匹配。

MySQL的-JS> db.city.delete().where("Name = 'Olympia'")
查询OK,1项受影响(0.01秒)
删除第一条记录

要删除city表中的第一条记录,请使用limit()值为1 方法。

MySQL的-JS> db.city.delete().limit(1)
查询OK,1项受影响(0.02秒)
删除表中的所有记录

您可以删除表中的所有记录。为此,请在delete()不指定搜索条件的情况下使用该 方法。

警告

删除记录时请小心,而不指定搜索条件。此操作将删除表中的所有记录。

放一张桌子

dropCollection()方法还在MySQL Shell中用于从数据库中删除关系表。例如,要从world_x数据库中删除citytest表 ,请键入:

MySQL的-JS> session.dropCollection("world_x", "citytest")
查询正常(0.04秒)
相关信息

20.3.5表格中的文件

在MySQL中,表可能包含传统的关系数据,JSON值或两者。您可以将文档存储在具有本机JSON数据类型的列中,从而将传统数据与JSON文档相结合

本节中的示例使用world_x数据库中的city表

城市表描述

城市表有五列(或字段)。

+ --------------- + ------------ + ------- ------- + ---- + ----- + ------------------ +
| 领域| 输入| 空| 钥匙| 默认| 额外的|
+ --------------- + ------------ + ------- ------- + ---- + ----- + ------------------ +
| ID | int(11)| 没有| PRI | null | auto_increment |
| 名称| char(35)| 没有| | | |
| CountryCode | char(3)| 没有| | | |
| 区| char(20)| 没有| | | |
| 信息| json | 是的| | null | |
+ --------------- + ------------ + ------- ------- + ---- + ----- + ------------------ +

插入记录

要将文档插入表的列,请传递给 values()按正确的顺序方法格式良好的JSON文档。在以下示例中,将文档作为要插入Info列的最终值传递。

MySQL的-JS> db.city.insert().
values(null, "San Francisco", "USA", "California", '{"Population":830000}')
查询OK,1项受影响(0.01秒)

选择一个记录

您可以使用搜索条件发出查询,该搜索条件评估表达式中的文档值。

MySQL的-JS> db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).
  where("CountryCode = :country and Info->'$.Population' > 1000000").
  bind('country', 'USA')
+ ------ + ---------------- + ------------- ----------- + ----- + ----------------------------- +
| ID | 名称| CountryCode | 区| 信息|
+ ------ + ---------------- + ------------- ----------- + ----- + ----------------------------- +
| 3793 | 纽约| 美国| 纽约| {“人口”:8008278} |
| 3794 | 洛杉矶| 美国| 加州| {“人口”:3694820} |
| 3795 | 芝加哥| 美国| 伊利诺伊州 {“人口”:2896016} |
| 3796 | 休斯顿| 美国| 德克萨斯州 {“人口”:1953631} |
| 3797 | 费城| 美国| 宾州| {“人口”:1517550} |
| 3798 | 凤凰城| 美国| Arizona | {“人口”:1321045} |
| 3799 | 圣地亚哥| 美国| 加州| {“人口”:1223400} |
| 3800 | 达拉斯| 美国| 德克萨斯州 {“人口”:1188580} |
| 3801 | 圣安东尼奥| 美国| 德克萨斯州 {“人口”:1144646} |
+ ------ + ---------------- + ------------- ----------- + ----- + ----------------------------- +
9行(0.01秒)

相关信息

20.4 Python快速入门指南:用于文档存储的MySQL Shell

本快速入门指南提供了使用MySQL Shell以交互方式开始构建文档存储应用程序原型的说明。该指南包括以下主题:

  • MySQL功能,MySQL Shell和 world_x数据库示例简介。

  • 管理集合和文档的操作。

  • 管理关系表的操作。

  • 适用于表中文档的操作。

相关信息

20.4.1导入数据库示例

world_x数据库样本包含一个JSON收集和一组三个关系表:

  • 采集

    • countryinfo:有关世界各国的信息。

    • country:关于世界各国的最少信息。

    • city:有关这些国家/地区的部分城市的信息。

    • countrylanguage:每个国家/地区使用的语言。

要求

要遵循这个快速入门指南,您需要一个安装了X插件的MySQL服务器,8.0中的默认设置和用作客户端的MySQL Shell。请参阅 安装MySQL Shell在加载world_x本指南的示例数据库之前启动MySQL

下载并导入world_x数据库

要准备world_x数据库示例,请按照下列步骤操作:

  1. 下载 world_x-db.zip

  2. 将安装存档解压缩到临时位置,例如/tmp/解压缩归档会产生一个名为的文件 world_x.sql

  3. world_x.sql文件导入数据库。你可以:

    • 在SQL模式下启动MySQL Shell并通过发出以下命令导入文件:

      mysqlsh -u root --sql --file /tmp/world_x-db/world_x.sql
      输入密码: ****
      
    • 在MySQL Shell运行时将MySQL Shell设置为SQL模式,并在MySQL Shell运行时通过发出以下命令来获取模式文件:

      \source /tmp/world_x-db/world_x.sql
      切换到SQL模式...命令以;结尾;
      \source /tmp/world_x-db/world_x.sql
      

    替换/tmp/world_x.sql系统上文件的路径 出现提示时输入密码。只要帐户具有创建新数据库的权限,就可以使用非root帐户。

相关信息

20.4.2 MySQL Shell

MySQL Shell是MySQL Server的统一脚本接口。它支持JavaScript和Python中的脚本。JavaScript是默认的处理模式。在大多数情况下,您需要一个帐户才能连接到MySQL服务器实例。

启动MySQL Shell

安装并启动MySQL服务器后,将MySQL Shell连接到服务器实例。默认情况下,MySQL Shell使用X协议进行连接。您需要知道您计划连接的MySQL服务器实例的地址。

如果MySQL Shell尚未运行,请打开终端窗口并发出:

mysqlsh name@localhost/world_x --py

或者,如果MySQL Shell已经运行,请使用以下 \connect命令:

\connect name@host/world_x

您需要指定要将MySQL Shell连接到的MySQL服务器实例的地址。例如,在前面的示例中:

  • name 代表您的MySQL帐户的用户名。

  • MySQL Shell会提示您输入密码。

  • --py选项以Python模式启动MySQL Shell。如果省略--py,MySQL Shell将以JavaScript模式启动。

  • 此会话的默认架构是 world_x数据库。有关设置world_x数据库示例的说明,请参见第20.4.1节“导入数据库示例”

MySQL Shell打开后,mysql-py> 提示符表明此会话的活动语言是Python。

MySQL的-PY>

当您在没有host参数的情况下运行mysqlsh时,MySQL Shell会尝试连接到端口33060上localhost接口上运行的服务器实例。有关更多信息,请参阅MySQL Shell连接

MySQL Shell支持输入行编辑,如下所示:

  • 箭头右箭头键在当前输入行内水平移动。

  • 向上箭头向下箭头键在上一组输入的行中上下移动。

  • 退格键删除光标前的字符,键入新字符将在光标位置输入。

  • Enter将当前输入行发送到服务器。

获取MySQL Shell的帮助

在命令解释程序的提示符下 键入mysqlsh --help以获取命令行选项列表。

mysqlsh --help

键入\help在MySQL的壳牌提示可用的命令及其说明的列表。

MySQL的-PY> \help

键入\help后跟命令名称,以获取有关单个MySQL Shell命令的详细帮助。例如,要查看\connect 命令的帮助,请键入:

MySQL的-PY> \help \connect

退出MySQL Shell

要退出MySQL Shell,请键入以下命令:

MySQL的-PY> \quit

相关信息

20.4.3文件和收藏

在MySQL中,集合包含可以添加,查找,更新和删除的JSON文档。集合是可以创建,列出和删除的模式中的容器。

本节中的示例使用world_x数据库中的countryinfo集合 有关设置world_x数据库示例的说明,请参见 第20.4.1节“导入数据库示例”

文件

在MySQL中,文档表示为JSON对象。在内部,它们以高效的二进制格式存储,可以快速查找和更新。

  • Python的简单文档格式:

    {“field1”:“value”,“field2”:10,“field 3”:null}
    

一组文档由一组用逗号分隔并包含在字符[]文字中的文档组成

  • Python的简单文档数组:

    [{“姓名”:“Aruba”,“_ id”:“ABW”},{“姓名”:“安哥拉”,“_ id”:“AGO”}]
    

MySQL支持JSON文档中的以下Python值类型:

  • 数字(整数和浮点数)

  • 字符串

  • 布尔值(False和True)

  • 没有

  • 更多JSON值的数组

  • 嵌套(或嵌入)更多JSON值的对象

集合

集合是用于共享目的并且可能共享一个或多个索引的文档的容器。每个集合都有一个唯一的名称,并存在于单个模式中。

术语模式等同于数据库,这意味着一组数据库对象(与用于强制数据结构和约束的关系模式相对)。架构不强制对集合中的文档进行一致性。

在本快速入门指南中:

  • 基本对象包括:

    对象形式 描述
    db db是分配给当前活动模式的全局变量。如果要对架构运行操作(例如,要检索集合),可以使用可用于该db 变量的方法
    db.get_collections() db.get_collections() 包含模式中的集合列表。使用列表获取对集合对象的引用,迭代它们,等等。
  • 集合的基本操作包括:

    运作形式 描述
    db.name.add() 的add() 方法插入一个文档或文档放到指定的集合列表。
    db.name.find() 发现() 方法返回指定的集合中的部分或全部文件。
    db.name.modify() 修改() 指定的收集方法的更新文件。
    db.name.remove() 删除() 方法删除一个文件或从指定收集的文件清单。

相关信息

20.4.3.1创建,列出和删除集合

在MySQL Shell中,您可以创建新集合,获取模式中现有集合的列表,以及从模式中删除现有集合。集合名称区分大小写,每个集合名称必须唯一。

确认架构

要显示分配给模式变量的值,请发出:

MySQL的-PY> db

如果架构值不是Schema:world_x,则设置db通过发出以下命令变量:

MySQL的-PY> \use world_x
创建一个集合

要在现有模式中创建新集合,请使用该 db对象的 createCollection()方法。以下示例创建flagsworld_x数据库中调用的集合

MySQL的-PY> db.create_collection("flags")

该方法返回一个集合对象。

<收集:标志>
列表集合

要显示world_x 数据库中的所有集合,请使用db对象的 get_collections()方法。您当前连接的服务器返回的集合显示在括号中。

MySQL的-PY> db.get_collections()
[
    <Collection:countryinfo>,
    <Collection:flags>
]
删除一个集合

要从数据库中删除现有集合,请使用该 db对象的 drop_collection()方法。例如,要从world_x 数据库中删除flags集合,请键入:

MySQL的-PY> session.drop_collection("world_x", "flags")

drop_collection()方法还在MySQL Shell中用于从数据库中删除关系表。

相关信息

20.4.3.2添加文档

使用该add()方法使用MySQL Shell将一个文档或文档列表插入到现有集合中。本节中的所有示例都使用world_x 架构中提供的countryinfo集合

添加文档

将以下文档插入countryinfo集合中。由于这是多行内容,请按 两次Enter键以插入文档。

MySQL的-PY> db.countryinfo.add(
 {
    GNP: .6,
    IndepYear: 1967,
    Name: "Sealand",
    demographics: {
        LifeExpectancy: 79,
        Population: 27
    },
    geography: {
        Continent: "Europe",
        Region: "British Islands",
        SurfaceArea: 193
    },
    government: {
        GovernmentForm: "Monarchy",
        HeadOfState: "Michael Bates"
    }
  }
)

该方法返回操作的状态。

每个文件需要所谓的标识符字段 _id_id字段的值 在同一集合中的所有文档中必须是唯一的。在MySQL 8.0.11及更高版本中,文档ID由服务器而不是客户端生成,因此MySQL Shell不会自动设置 _id值。_id如果文档不包含该_id字段,则8.0.11或更高版本的MySQL服务器会设置一个在早期8.0版本或5.7版本的MySQL服务器_id在这种情况下不设置 值,因此您必须明确指定它。如果不这样做,MySQL Shell将返回错误5115 Document缺少必填字段

相关信息

20.4.3.3查找文档

您可以使用该find()方法从数据库中的集合中查询和返回文档。MySQL Shell提供了与方法一起使用的其他方法,用于 find()过滤和排序返回的文档。

MySQL提供以下操作符来指定搜索条件:OR||), ( AND),&&, , XORISNOTBETWEENINLIKE!=<>>>=<<=&|<<>>+- */~%

查找集合中的所有文档

要返回集合中的所有文档,请使用该 find()方法而不指定搜索条件。例如,以下操作将返回countryinfo集合中的所有文档。

MySQL的-PY> db.countryinfo.find()
[
     {
          “GNP”:828,
          “IndepYear”:null,
          “名称”:“阿鲁巴”,
          “_id”:“ABW”,
          “人口统计资料”:{
              “LifeExpectancy”:78.4000015258789,
              “人口”:103000
          },
          “地理”:{
              “大陆”:“北美”,
              “地区”:“加勒比”,
              “SurfaceArea”:193
          },
          “政府”: {
              “政府表格”:“荷兰非都会领土”,
              “HeadOfState”:“Beatrix”
          }
          ...
      }
 ]
240套文件(0.00秒)

除了集合中的所有文档之外,该方法还生成包含操作信息的结果。

空集(无匹配文档)返回以下信息:

空集(0.00秒) 
过滤搜索

您可以使用该find()方法包含搜索条件 形成搜索条件的表达式的语法与传统MySQL 第12章,函数和运算符的语法相同您必须将所有表达式括在引号中。

本节中的所有示例都使用world_x数据库中的countryinfo集合为简洁起见,一些示例不显示输出。

简单的搜索条件可以包括 Name字段和我们知道的文档中的值。以下示例返回单个文档:

MySQL的-PY> db.countryinfo.find("Name = 'Australia'")
[
    {
        “GNP”:351182,
        “IndepYear”:1901年,
        “名称”:“澳大利亚”,
        “_id”:“AUS”,
        “人口统计资料”:{
            “LifeExpectancy”:79.80000305175781,
            “人口”:18886000
        },
        “地理”:{
            “大陆”:“大洋洲”,
            “地区”:“澳大利亚和新西兰”,
            “SurfaceArea”:7741220
        },
        “政府”: {
            “政府形式”:“君主立宪制,联邦”,
            “HeadOfState”:“伊丽莎白二世”
        }
    }
]

以下示例搜索GNP高于5000亿美元的所有国家/地区。countryinfo集合以百万为单位测量GNP。

mysql-py> db.countryinfo.find("GNP > 500000")
... [ 输出已删除 ]
10套文件(0.00秒)

以下查询中的“人口”字段嵌入在人口统计信息对象中。要访问嵌入字段,请使用人口统计信息和人口统计之间的时间段来确定关系。文档和字段名称区分大小写。

mysql-py> db.countryinfo.find("GNP > 500000 and demographics.Population < 100000000")
... [ 输出已删除 ]
6套文件(0.00秒)

以下表达式中的算术运算符用于查询人均GNP高于$ 30000的国家/地区。搜索条件可以包括算术运算符和大多数MySQL函数。

注意

countryinfo集合中的七个文档的人口值为零。警告消息显示在输出的末尾。

mysql-py> db.countryinfo.find("GNP*1000000/demographics.Population > 30000")
... [ 输出已删除 ]
9套文件,7条警告(0.00秒)
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0
警告(代码1365):除以0

您可以使用该bind()方法将值与搜索条件分开例如,不是将硬编码的国家/地区名称指定为条件,而是替换命名的占位符,该占位符由冒号后跟以字母开头的名称组成,例如 country然后使用 如下方法: bind(placeholder, value)

MySQL的-PY> db.countryinfo.find("Name = :country").bind("country", "Italy")
[
    {
        “GNP”:1161755,
        “IndepYear”:1861年,
        “名称”:“意大利”,
        “_id”:“ITA”,
        “人口统计资料”:{
            “LifeExpectancy”:79,
            “人口”:57680000
        },
        “地理”:{
            “大陆”:“欧洲”,
            “地区”:“南欧”,
            “SurfaceArea”:301316
        },
        “政府”: {
            “政府表格”:“共和国”,
            “HeadOfState”:“Carlo Azeglio Ciampi”
        }
    }
]
1套文件(0.01秒)
小费

在程序中,绑定使您可以在表达式中指定占位符,这些占位符在执行之前用值填充,并且可以根据需要从自动转义中受益。

始终使用绑定来清理输入。避免在使用字符串连接的查询中引入值,这会产生无效输入,并且在某些情况下会导致安全问题。

您可以使用占位符和bind() 方法创建已保存的搜索,然后可以使用不同的值调用这些搜索。例如,为国家/地区创建已保存的搜索:

mysql-py> myFind = db.countryinfo.find("Name = :country")
mysql-py>myFind.bind('country', 'France')
[
    {
        “GNP”:1424285,
        “IndepYear”:843,
        “名字”:“法国”,
        “_id”:“FRA”,
        “人口统计资料”:{
            “LifeExpectancy”:78.80000305175781,
            “人口”:59225700
        },
        “地理”:{
            “大陆”:“欧洲”,
            “地区”:“西欧”,
            “SurfaceArea”:551500
        },
        “政府”: {
            “政府表格”:“共和国”,
            “HeadOfState”:“Jacques Chirac”
        }
    }
]
1套文件(0.0028秒)

MySQL的-PY> myFind.bind('country', 'Germany')
[
    {
        “GNP”:2133367, 
        “IndepYear”:1955年, 
        “名字”:“德国”, 
        “_id”:“DEU”, 
        “人口统计资料”:{
            “LifeExpectancy”:77.4000015258789, 
            “人口”:82164700
        }, 
        “地理”:{
            “大陆”:“欧洲”, 
            “地区”:“西欧”, 
            “SurfaceArea”:357022
        }, 
        “政府”: {
            “政府表格”:“联邦共和国”, 
            “HeadOfState”:“Johannes Rau”
        }
    }
]
1套文件(0.0026秒)
项目结果

您可以返回文档的特定字段,而不是返回所有字段。以下示例返回countryinfo集合中与搜索条件匹配的所有文档的GNP和Name字段。

使用该fields()方法传递要返回的字段列表。

MySQL的-PY> db.countryinfo.find("GNP > 5000000").fields(["GNP", "Name"])
[
    {
        “GNP”:8510700,
        “名字”:“美国”
    }
]
1套文件(0.00秒)
 

此外,您可以使用描述要返回的文档的表达式更改返回的文档 - 添加,重命名,嵌套甚至计算新字段值。例如,使用以下表达式更改字段的名称以仅返回两个文档。

MySQL的-PY> db.countryinfo.find().\
fields(mysqlx.expr('{"Name": upper(Name), "GNPPerCapita": GNP*1000000/demographics.Population}')).\
limit(2)
[
    {
        “GNPPerCapita”:8038.834951456311,
        “名字”:“ARUBA”
    },
    {
        “GNPPerCapita”:263.0281690140845,
        “名字”:“阿富汗”
    }
]
2套文件(0.00秒)
限制,排序和跳过结果

您可以应用limit()sort()skip() 方法来管理由返回文档的数量和顺序find()的方法。

要指定结果集中包含的文档数,请将limit()方法附加值附加find()方法中。以下查询返回countryinfo集合中的前五个文档。

mysql-py> db.countryinfo.find().limit(5)
... [ 输出已删除 ]
5套文件(0.00秒)

要指定结果的顺序,请将sort()方法附加 find()方法。sort()一个或多个字段的列表传递给方法,以便根据 需要进行排序,并可选择地使用descending(desc)或ascending(asc)属性。升序是默认订单类型。

例如,以下查询按IndepYear字段对所有文档进行排序,然后按降序返回前八个文档。

mysql-py> db.countryinfo.find().sort(["IndepYear desc"]).limit(8)
... [ 输出已删除 ]
8套文件(0.00秒)

默认情况下,该limit()方法从集合中的第一个文档开始。您可以使用该 skip()方法更改起始文档。例如,要忽略第一个文档并返回与条件匹配的下八个文档,请将skip()传递给 方法1。

mysql-py> db.countryinfo.find().sort(["IndepYear desc"]).limit(8).skip(1)
... [ 输出已删除 ]
8套文件(0.00秒)
相关信息

20.4.3.4修改文件

您可以使用该modify()方法更新集合中的一个或多个文档。X DevAPI提供了与该modify() 方法一起使用的其他方法:

  • 设置和取消设置文档中的字段。

  • 追加,插入和删除数组。

  • 绑定,限制和排序要修改的文档。

设置和取消设置字段

modify()方法通过过滤集合以仅包括要修改的文档,然后将您指定的操作应用于这些文档来工作。

在以下示例中,该modify() 方法使用搜索条件来标识要更改的文档,然后该set()方法替换嵌套的人口统计信息对象中的两个值。

MySQL的-PY> db.countryinfo.modify("_id = 'SEA'").\
set("demographics", {"LifeExpectancy": 78, "Population": 28})
查询OK,1项受影响(0.04秒)

修改文档后,使用该find() 方法验证更改。

要从文档中删除内容,请使用 modify()unset() 方法。例如,以下查询从与搜索条件匹配的文档中删除GNP。

MySQL的-PY> db.countryinfo.modify("Name = 'Sealand'").unset("GNP")
查询OK,1项受影响(0.01秒)   

使用该find()方法验证更改。

MySQL的-PY> db.countryinfo.find("Name = 'Sealand'")
[
    {
        “IndepYear”:1967年,
        “名字”:“西兰”,
        “_id”:“SEA”,
        “人口统计资料”:{
            “LifeExpectancy”:78,
            “人口”:28
        },
        “地理”:{
            “大陆”:“欧洲”,
            “地区”:“英属群岛”,
            “SurfaceArea”:193
        },
        “政府”: {
            “政府形式”:“君主制”,
            “HeadOfState”:“Michael Bates”
        }
    }
]
1套文件(0.00秒)
追加,插入和删除数组

在数组中的元素附加到阵列字段,或插入,或删除单元,使用 array_append()array_insert()array_delete()方法。以下示例修改countryinfo集合以启用对国际机场的跟踪。

第一个示例使用modify()set()方法在所有文档中创建新的Airports字段。

警告

修改文档时请小心,而不指定搜索条件。此操作将修改集合中的所有文档。

MySQL的-PY> db.countryinfo.modify(True).set("Airports", [])
查询OK,受影响的240件(0.07秒)

添加机场字段后,下一个示例使用该 array_append()方法将新机场添加到其中一个文档。以下示例中的$ .Airports表示当前文档的Airports字段。

MySQL的-PY> db.countryinfo.modify("Name = 'France'").array_append("$.Airports", "ORY")
查询OK,1项受影响(0.02秒)

使用db.countryinfo.find("Name = 'France'")查看更改。

要在数组中的不同位置插入元素,请使用该array_insert()方法指定要在路径表达式中插入的索引。在这种情况下,索引是0,或者是数组中的第一个元素。

MySQL的-PY> db.countryinfo.modify("Name = 'France'").array_insert("$.Airports[0]", "CDG")
查询OK,1项受影响(0.04秒)

要从数组中删除元素,必须将要删除的元素array_delete()的索引传递给 方法。

MySQL的-PY> db.countryinfo.modify("Name = 'France'").array_delete("$.Airports[1]")
查询OK,1项受影响(0.03秒)
相关信息

20.4.3.5删除文件

您可以使用该remove()方法从数据库中的集合中删除部分或全部文档。X DevAPI提供了与方法一起使用的其他方法,用于 remove()过滤和排序要删除的文档。

使用条件删除文档

下面的示例将搜索条件传递给 remove()方法。符合条件的所有文档都将从countryinfo集合中删除。在此示例中,一个文档与条件匹配。

MySQL的-PY> db.countryinfo.remove("_id = 'SEA'")
查询OK,1项受影响(0.02秒)
删除第一个文档

要删除countryinfo集合中的第一个文档,请使用limit()值为1 方法。

MySQL的-PY> db.countryinfo.remove(True).limit(1)
查询OK,1项受影响(0.03秒)
删除订单中的最后一个文档

以下示例按国家/地区名称删除countryinfo集合中的最后一个文档。

MySQL的-PY> db.countryinfo.remove(True).sort(["Name desc"]).limit(1)
查询OK,1项受影响(0.02秒)
删除集合中的所有文档

您可以删除集合中的所有文档。为此,请在remove(True)不指定搜索条件的情况下使用该方法。

警告

在不指定搜索条件的情况下删除文档时请小心。此操作将删除集合中的所有文档。

相关信息

20.4.3.6创建和删除索引

索引用于快速查找具有特定字段值的文档。如果没有索引,MySQL必须从第一个文档开始,然后读取整个集合以查找相关字段。收集越大,成本越高。如果集合很大并且特定字段上的查询很常见,那么请考虑在文档内的特定字段上创建索引。

例如,以下查询将使用索引执行得更好:

mysql-js> db.countryinfo.find("demographics.Population < 100")
... [ 输出已删除 ]
8套文件(0.00秒)

create_index()方法创建一个可以定义为非唯一或唯一的索引。使用该 field()方法链接应编制索引的字段。execute()创建或删除索引需要方法。

在MySQL中,该_id字段默认等效于主键。

添加非唯一索引

要创建非唯一索引,请将create_index()方法名称传递给 方法。禁止复制索引名称。

在以下示例中,方法的第一个参数 field()指定人口统计信息对象内的人口字段,下一个参数指示该字段应编入索引为整数数值。最后一个参数指示字段是否应该要求NOT NULL约束。如果值为 False,则该字段可以包含 NULL值。

MySQL的-JS> db.countryinfo.create_index("pop").\
field("demographics.Population", "INTEGER", False).execute()
查询正常(0.04秒)
添加唯一索引

要创建唯一索引,请将create_index()方法名称和mysqlx.IndexType.UNIQUE类型传递给 方法 Country "Name"是countryinfo集合中索引的另一个常见字段。在以下示例中, "Text(40)"表示要索引的字符数,并True指示该字段不能包含任何NULL值。

MySQL的-JS> db.countryinfo.create_index("name", mysqlx.IndexType.UNIQUE).\
field("Name", "TEXT(40)", True).execute()
查询正常(0.04秒)
删除索引

要删除索引,请将要删除的索引drop_index() 的名称传递给方法。例如,您可以删除pop索引,如下所示:

MySQL的-JS> db.countryinfo.drop_index("pop").execute()
查询正常(0.58秒)
相关信息

20.4.4关系表

您可以使用MySQL Shell不仅可以操作JSON文档,还可以操作关系表。

在MySQL中,每个关系表都与特定的存储引擎相关联。本节中的示例使用 数据库中的InnoDBworld_x

确认架构

要显示分配给模式变量的值,请键入 db

MySQL的-PY> db
<架构:world_x>

如果架构值不是Schema:world_x 数据库,db则按如下方式设置变量:

MySQL的-PY> \use world_x
可通过db访问的架构`world_x`。

显示所有表格

要显示world_x 数据库中的所有关系表,请使用get_tables()架构对象上的方法。

MySQL的-PY> db.get_tables()
{
    “城市”:<表:城市>,
    “country”:<表:国家>,
    “countrylanguage”:<表:countrylanguage>
}

基本表操作

表格规定的基本操作包括:

运作形式 描述
db.name.insert() 所述 插入件() 方法插入一个或多个记录到指定的表。
db.name.select() 选择() 方法返回的指定表中的部分或全部记录。
db.name.update() 更新() 方法的更新记录的指定表中。
db.name.delete() 删除() 方法删除指定表中的一个或多个记录。

相关信息

20.4.4.1将记录插入表中

您可以将该insert()方法与该 values()方法一起使用,以将记录插入现有的关系表中。insert() 方法接受表中的各列或所有列。使用一种或多种values()方法指定要插入的值。

插入完整记录

要插入完整记录,请将insert()表中的所有列传递给 方法。然后将values()每列方法传递给方法一个值。例如,要将新记录添加到world_x数据库中的城市表,请插入以下记录并按两次Enter键

MySQL的-PY> db.city.insert("ID", "Name", "CountryCode", "District", "Info").\
values(None, "Olympia", "USA", "Washington", '{"Population": 5000}')
查询OK,1项受影响(0.01秒)

city表有五列:ID,Name,CountryCode,District和Info。每个值必须与其表示的列的数据类型匹配。

插入部分记录

以下示例将值插入到city表的ID,Name和CountryCode列中。

MySQL的-PY> db.city.insert("ID", "Name", "CountryCode").\
values(None, "Little Falls", "USA").values(None, "Happy Valley", "USA")
查询OK,2项受影响(0.03秒)

使用该insert() 方法指定列时,值的数量必须与列数匹配。在上一个示例中,您必须提供三个值以匹配指定的三个列。

相关信息

20.4.4.2选择表

您可以使用该select()方法从数据库中的表中查询和返回记录。X DevAPI提供了与其一起使用的其他方法 select()过滤和排序返回的记录。

MySQL提供以下操作符来指定搜索条件:OR||), ( AND),&&, , XORISNOTBETWEENINLIKE!=<>>>=<<=&|<<>>+- */~%

选择所有记录

要发出返回现有表中所有记录的查询,请使用该select()方法而不指定搜索条件。以下示例选择world_x数据库中city表中的所有记录

注意

将空select() 方法的使用限制为交互式语句。始终在应用程序代码中使用显式列名选择。

MySQL的-PY> db.city.select()
+ ------ + ------------ + ------------- + ------------ +  - ----------------------- +
| ID | 名称| CountryCode | 区| 信息|
+ ------ + ------------ + ------------- + ------------ +  - ----------------------- +
| 1 | 喀布尔| AFG | Kabol | {“人口”:1780000} |
| 2 | 坎大哈| AFG | 坎大哈| {“人口”:237500} |
| 3 | 赫拉特| AFG | 赫拉特| {“人口”:186800} |
...... ...... ......
| 4079 | 拉法| PSE | 拉法| {“人口”:92020} |
+ ------ + ------- ---- + ------------- + ------------ + --- ---------------------- +
4082行(0.01秒)

空集(无匹配记录)返回以下信息:

空集(0.00秒)
过滤搜索

要发出返回一组表列的查询,请使用该 select()方法并指定要在方括号之间返回的列。此查询返回city表中的Name和CountryCode列。

MySQL的-PY> db.city.select(["Name", "CountryCode"])
+ ------------------- + ------------- +
| 名称| CountryCode |
+ ------------------- + ------------- +
| 喀布尔| AFG |
| 坎大哈| AFG |
| 赫拉特| AFG |
| Mazar-e-Sharif | AFG |
| Amsterdam | NLD |
......
| 拉法| PSE |
| 奥林匹亚| 美国|
| 小瀑布| 美国|
| 欢乐谷| 美国|
+ ------------------- + ------------- +
4082行(0.00秒)

要发出返回与特定搜索条件匹配的行的查询,请使用该where()方法包含这些条件。例如,以下示例返回以字母Z开头的城市的名称和国家/地区代码。

MySQL的-PY> db.city.select(["Name", "CountryCode"]).where("Name like 'Z%'")
+ ------------------- + ------------- +
| 名称| CountryCode |
+ ------------------- + ------------- +
| 赞斯塔德| NLD |
| Zoetermeer | NLD |
| 兹沃勒| NLD |
| Zenica | BIH |
| Zagazig | EGY |
| 萨拉戈萨| ESP |
| 三宝颜| PHL |
| Zahedan | IRN |
| 赞詹| IRN |
| Zabol | IRN |
| Zama | JPN |
| Zhezqazghan | KAZ |
| 郑州| CHN |
......
| Zeleznogorsk | RUS |
+ ------------------- + ------------- +
59行(0.00秒)

您可以使用该bind()方法将值与搜索条件分开例如,不是使用“Name ='Z%'”作为条件,而是替换一个命名的占位符,该占位符由冒号后跟一个以字母开头的名称组成,例如name然后在中包含占位符和值 bind()方法中如下所示:

MySQL的-PY> db.city.select(["Name", "CountryCode"]).\
              where("Name like :name").bind("name", "Z%")
小费

在程序中,绑定使您可以在表达式中指定占位符,这些占位符在执行之前用值填充,并且可以根据需要从自动转义中受益。

始终使用绑定来清理输入。避免在使用字符串连接的查询中引入值,这会产生无效输入,并且在某些情况下会导致安全问题。

项目结果

要使用AND 运算符发出查询,请在where()方法中的搜索条件之间添加运算符

MySQL的-PY> db.city.select(["Name", "CountryCode"]).\
               where("Name like 'Z%' and CountryCode = 'CHN'")
+ ---------------- + ------------- +
| 名称| CountryCode |
+ ---------------- + ------------- +
| 郑州| CHN |
| 淄博| CHN |
| 张家口| CHN |
| 株洲| CHN |
| 张江| CHN |
| 自贡| CHN |
| 枣庄| CHN |
......
| 张家港| CHN |
+ ---------------- + ------------- +
22行(0.01秒)

要指定多个条件运算符,可以将搜索条件括在括号中以更改运算符优先级。下面的示例演示的布局ANDOR运营商。

MySQL的-PY> db.city.select(["Name", "CountryCode"]).\
where("Name like 'Z%' and (CountryCode = 'CHN' or CountryCode = 'RUS')")
+ ------------------- + ------------- +
| 名称| CountryCode |
+ ------------------- + ------------- +
| 郑州| CHN |
| 淄博| CHN |
| 张家口| CHN |
| 株洲| CHN |
......
| Zeleznogorsk | RUS |
+ ------------------- + ------------- +
29行(0.01秒)
限价,订单和抵消结果

您可以应用limit()order_by()offset() 方法来管理由返回的记录的数量和顺序select()的方法。

要指定结果集中包含的记录数,请将limit()方法附加值附加select()方法中。例如,以下查询返回国家/地区表中的前五个记录。

MySQL的-PY> db.country.select(["Code", "Name"]).limit(5)
+ ------ + ------------- +
| 代码| 名称|
+ ------ + ------------- +
| ABW | 阿鲁巴|
| AFG | 阿富汗|
| AGO | 安哥拉|
| 友邦保险| 安圭拉|
| ALB | 阿尔巴尼亚|
+ ------ + ------------- +
5行(0.00秒)

要指定结果的顺序,请将order_by()方法附加 select()方法。order_by()一个或多个列的列表传递给方法以进行排序,并根据需要将descending(desc)或ascending(asc)属性(可选传递给它 升序是默认订单类型。

例如,以下查询按名称列对所有记录进行排序,然后按降序返回前三个记录。

MySQL的-PY> db.country.select(["Code", "Name"]).order_by(["Name desc"]).limit(3)
+ ------ + ------------ +
| 代码| 名称|
+ ------ + ------------ +
| ZWE | 津巴布韦|
| ZMB | 赞比亚|
| YUG | 南斯拉夫|
+ ------ + ------------ +
3组(0.00秒)

默认情况下,该limit()方法从表中的第一个记录开始。您可以使用该 offset()方法更改起始记录。例如,要忽略第一个记录并返回与条件匹配的下三个记录,请将offset()传递给 方法1。

MySQL的-PY> db.country.select(["Code", "Name"]).order_by(["Name desc"]).limit(3).offset(1)
+ ------ + ------------ +
| 代码| 名称|
+ ------ + ------------ +
| ZMB | 赞比亚|
| YUG | 南斯拉夫|
| YEM | 也门|
+ ------ + ------------ +
3组(0.00秒)
相关信息

20.4.4.3更新表

您可以使用该update()方法修改表中的一个或多个记录。update() 方法通过过滤查询以仅包括要更新的记录,然后将您指定的操作应用于这些记录来工作。

要替换城市表中的城市名称,set()请将新城市名称传递给 方法。然后,传递给where()城市名称定位和替换的方法。以下示例将北京城市替换为北京。

MySQL的-PY> db.city.update().set("Name", "Beijing").where("Name = 'Peking'")
查询OK,1项受影响(0.04秒)

使用该select()方法验证更改。

MySQL的-PY> db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).where("Name = 'Beijing'")
+ ------ + ----------- ------------- + + ---------- + ----- ------------------------ +
| ID | 名称| CountryCode | 区| 信息|
+ ------ + ----------- ------------- + + ---------- + ----- ------------------------ +
| 1891年| 北京| CHN | 北京| {“人口”:7472000} |
+ ------ + ----------- ------------- + + ---------- + ----- ------------------------ +
1排(0.00秒)
相关信息

20.4.4.4删除表

您可以使用该delete()方法从数据库中的表中删除部分或全部记录。X DevAPI提供了与方法一起使用的其他方法,用于 delete()过滤和排序要删除的记录。

使用条件删除记录

下面的示例将搜索条件传递给 delete()方法。符合条件的所有记录都将从city表中删除。在此示例中,一条记录与条件匹配。

MySQL的-PY> db.city.delete().where("Name = 'Olympia'")
查询OK,1项受影响(0.01秒)
删除第一条记录

要删除city表中的第一条记录,请使用limit()值为1 方法。

MySQL的-PY> db.city.delete().limit(1)
查询OK,1项受影响(0.02秒)
删除表中的所有记录

您可以删除表中的所有记录。为此,请在delete()不指定搜索条件的情况下使用该 方法。

警告

删除记录时请小心,而不指定搜索条件。此操作将删除表中的所有记录。

放一张桌子

drop_collection()方法还在MySQL Shell中用于从数据库中删除关系表。例如,要从world_x数据库中删除citytest表 ,请键入:

MySQL的-PY> session.drop_collection("world_x", "citytest")
查询正常(0.04秒)
相关信息

20.4.5表格中的文件

在MySQL中,表可能包含传统的关系数据,JSON值或两者。您可以将文档存储在具有本机JSON数据类型的列中,从而将传统数据与JSON文档相结合

本节中的示例使用world_x数据库中的city表

城市表描述

城市表有五列(或字段)。

+ --------------- + ------------ + ------- ------- + ---- + ----- + ------------------ +
| 领域| 输入| 空| 钥匙| 默认| 额外的|
+ --------------- + ------------ + ------- ------- + ---- + ----- + ------------------ +
| ID | int(11)| 没有| PRI | null | auto_increment |
| 名称| char(35)| 没有| | | |
| CountryCode | char(3)| 没有| | | |
| 区| char(20)| 没有| | | |
| 信息| json | 是的| | null | |
+ --------------- + ------------ + ------- ------- + ---- + ----- + ------------------ +

插入记录

要将文档插入表的列,请values()按正确的顺序方法传递给 格式良好的JSON文档。在以下示例中,将文档作为要插入Info列的最终值传递。

MySQL的-PY> db.city.insert().\
values(None, "San Francisco", "USA", "California", '{"Population":830000}')
查询OK,1项受影响(0.01秒)

选择一个记录

您可以使用搜索条件发出查询,该搜索条件评估表达式中的文档值。

MySQL的-PY> db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).\
  where("CountryCode = :country and Info->'$.Population' > 1000000").\
  bind('country', 'USA')
+ ------ + ---------------- + ------------- ----------- + ----- + ----------------------------- +
| ID | 名称| CountryCode | 区| 信息|
+ ------ + ---------------- + ------------- ----------- + ----- + ----------------------------- +
| 3793 | 纽约| 美国| 纽约| {“人口”:8008278} |
| 3794 | 洛杉矶| 美国| 加州| {“人口”:3694820} |
| 3795 | 芝加哥| 美国| 伊利诺伊州 {“人口”:2896016} |
| 3796 | 休斯顿| 美国| 德克萨斯州 {“人口”:1953631} |
| 3797 | 费城| 美国| 宾州| {“人口”:1517550} |
| 3798 | 凤凰城| 美国| Arizona | {“人口”:1321045} |
| 3799 | 圣地亚哥| 美国| 加州| {“人口”:1223400} |
| 3800 | 达拉斯| 美国| 德克萨斯州 {“人口”:1188580} |
| 3801 | 圣安东尼奥| 美国| 德克萨斯州 {“人口”:1144646} |
+ ------ + ---------------- + ------------- ----------- + ----- + ----------------------------- +
9行(0.01秒)

相关信息

20.5 X插件

本节介绍如何使用,配置和监控X插件。

20.5.1检查X插件安装

默认情况下,MySQL插件中启用了X插件,因此安装或升级到MySQL 8可以使插件可用。您可以使用以下命令验证X插件是否安装在MySQL服务器的实例上SHOW plugins 语句查看插件列表,

要使用MySQL Shell验证是否已安装X插件,请发出:

shell> mysqlsh -u user--sqlc -P 3306 -e“SHOW plugins”

要使用MySQL Client验证是否已安装X插件,请发出:

shell> mysql -u user-p -e“SHOW插件”

如果安装了X Plugin,则会在此处突出显示示例结果:

+ ---------------------------- + ---------- + --------- ----------- --------- + --------- + +
| 名称| 状态| 输入| 图书馆| 许可证|
+ ---------------------------- + ---------- + --------- ----------- --------- + --------- + +

...


| mysqlx | ACTIVE | DAEMON | NULL | GPL |

...

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

20.5.2禁用X插件

可以在启动时通过设置mysqlx=0MySQL配置文件,或者通过传入 --mysqlx=0--skip-mysqlx 启动MySQL服务器来禁用X插件

或者,使用 -DWITH_MYSQLX=OFFCMake选项在没有X插件的情况下编译MySQL服务器。

20.5.3使用带X插件的安全连接

本节介绍如何配置X插件以使用安全连接。有关更多背景信息,请参见 第6.3节“使用加密连接”

X Plugin有自己的SSL设置,可能与MySQL Server使用的设置不同。这意味着可以使用与MySQL服务器不同的SSL密钥,证书和证书颁发机构文件来配置X插件。同样,X Plugin有自己的SSL状态变量,独立于MySQL Server SSL相关变量计算。默认情况下,X插件SSL配置取自 mysqlx_ssl_*变量,如 第20.5.5.2节“X插件选项和系统变量”中所述如果没有使用提供配置 mysqlx_ssl_*变量,X插件回退到使用MySQL服务器SSL系统变量。这意味着您可以通过单独配置每个SSL协议和X协议连接来选择单独的SSL配置,或者通过仅配置ssl-*变量来共享MySQL协议和X协议连接之间的SSL配置

在安装了X插件的服务器上,要使用单独的SSL配置配置MySQL协议和X协议连接,请使用以下两个ssl-*mysqlx-ssl-*变量 my.cnf

的[mysqld]
SSL的CA = ca1.pem
SSL证书=服务器cert1.pem
SSL的密钥=服务器key1.pem

mysqlx-SSL-CA = ca2.pem
mysqlx-SSL证书=服务器cert2.pem
mysqlx的SSL密钥=服务器key2.pem

可用mysqlx_ssl_*变量镜像MySQL服务器中的SSL变量,因此在第6.3.1节“配置MySQL使用加密连接”配置MySQL服务器以使用SSL的文件和技术 与配置X插件以使用安全连接相关。

您可以使用tls_version 系统变量配置X协议SSL连接使用的TLS版本因此,MySQL协议和X协议连接使用的TLS版本与TLS版本相同。

每个连接的加密是可选的,但可以强制特定用户对X协议和MySQL协议连接使用加密。您可以通过发出GRANT带有该REQUIRE选项语句来 配置此类用户 有关更多详细信息,请参见 第13.7.1.6节“GRANT语法”或者,可以通过设置强制所有X协议和MySQL协议连接使用加密require_secure_transport

20.5.4将X插件与缓存SHA-2身份验证插件一起使用

X Plugin支持使用第6.4.1.3节“缓存SHA-2可插入身份验证”插件创建的MySQL帐户 您可以使用X插件使用具有SHA256_MEMORY 身份验证的非SSL连接和具有身份验证的SSL连接对此类帐户进行身份PLAIN 验证。

虽然缓存SHA-2身份验证插件包含身份验证缓存,但要使用带有X Plugin的此类帐户,将使用名为的X Plugin身份验证缓存插件 mysqlx_cache_cleaner与X插件一样,默认情况下启用它。

在使用非SSL连接对使用该caching_sha2_password插件的帐户进行身份验证之前,该帐户必须至少通过SSL连接进行一次身份验证才能将密码存储在X Plugin身份验证缓存中。这意味着首次使用帐户必须使用启用了X Plugin身份验证缓存的SSL连接。通过SSL的初始身份验证成功后,可以使用非SSL连接。

20.5.5 X插件选项和变量

本节介绍配置X插件的命令选项和系统变量。如果在启动时指定的值不正确,则X Plugin可能无法正确初始化,并且服务器无法加载它。在这种情况下,服务器还可能会为其他X插件设置生成错误消息,因为它无法识别它们。

20.5.5.1 X插件选项和变量参考

此表概述了X Plugin提供的命令选项以及系统和状态变量。

表20.1 X插件选项和变量参考

名称 CMD线 选项文件 系统变量 状态变量 Var范围 动态
mysqlx
Mysqlx_aborted_clients 全球 没有
Mysqlx_address 全球 没有
mysqlx_bind_address 全球 没有
Mysqlx_bytes_received 没有
Mysqlx_bytes_sent 没有
mysqlx_connect_timeout 全球
Mysqlx_connection_accept_errors 没有
Mysqlx_connection_errors 没有
Mysqlx_connections_accepted 全球 没有
Mysqlx_connections_closed 全球 没有
Mysqlx_connections_rejected 全球 没有
Mysqlx_crud_create_view 没有
Mysqlx_crud_delete 没有
Mysqlx_crud_drop_view 没有
Mysqlx_crud_find 没有
Mysqlx_crud_insert 没有
Mysqlx_crud_modify_view 没有
Mysqlx_crud_update 没有
mysqlx_document_id_unique_prefix 全球
mysqlx_enable_hello_notice 全球
Mysqlx_errors_sent 没有
Mysqlx_errors_unknown_message_type 没有
Mysqlx_expect_close 没有
Mysqlx_expect_open 没有
mysqlx_idle_worker_thread_timeout 全球
Mysqlx_init_error 没有
mysqlx_interactive_timeout 全球
mysqlx_max_allowed_pa​​cket 全球
mysqlx_max_connections 全球
mysqlx_min_worker_threads 全球
Mysqlx_notice_global_sent 没有
Mysqlx_notice_other_sent 没有
Mysqlx_notice_warning_sent 没有
Mysqlx_notified_by_group_replication 没有
Mysqlx_port 全球 没有
mysqlx_port 全球 没有
mysqlx_port_open_timeout 全球 没有
mysqlx_read_timeout 会议
Mysqlx_rows_sent 没有
Mysqlx_sessions 全球 没有
Mysqlx_sessions_accepted 全球 没有
Mysqlx_sessions_closed 全球 没有
Mysqlx_sessions_fatal_error 全球 没有
Mysqlx_sessions_killed 全球 没有
Mysqlx_sessions_rejected 全球 没有
Mysqlx_socket 全球 没有
mysqlx_socket 全球 没有
Mysqlx_ssl_accept_renegotiates 全球 没有
Mysqlx_ssl_accepts 全球 没有
Mysqlx_ssl_active 没有
mysqlx_ssl_ca 全球 没有
mysqlx_ssl_capath 全球 没有
mysqlx_ssl_cert 全球 没有
Mysqlx_ssl_cipher 没有
mysqlx_ssl_cipher 全球 没有
Mysqlx_ssl_cipher_list 没有
mysqlx_ssl_crl 全球 没有
mysqlx_ssl_crlpath 全球 没有
Mysqlx_ssl_ctx_verify_depth 没有
Mysqlx_ssl_ctx_verify_mode 没有
Mysqlx_ssl_finished_accepts 全球 没有
mysqlx_ssl_key 全球 没有
Mysqlx_ssl_server_not_after 全球 没有
Mysqlx_ssl_server_not_before 全球 没有
Mysqlx_ssl_verify_depth 全球 没有
Mysqlx_ssl_verify_mode 全球 没有
Mysqlx_ssl_version 没有
Mysqlx_stmt_create_collection 没有
Mysqlx_stmt_create_collection_index 没有
Mysqlx_stmt_disable_notices 没有
Mysqlx_stmt_drop_collection 没有
Mysqlx_stmt_drop_collection_index 没有
Mysqlx_stmt_enable_notices 没有
Mysqlx_stmt_ensure_collection 没有
Mysqlx_stmt_execute_mysqlx 没有
Mysqlx_stmt_execute_sql 没有
Mysqlx_stmt_execute_xplugin 没有
Mysqlx_stmt_kill_client 没有
Mysqlx_stmt_list_clients 没有
Mysqlx_stmt_list_notices 没有
Mysqlx_stmt_list_objects 没有
Mysqlx_stmt_ping 没有
mysqlx_wait_timeout 会议
Mysqlx_worker_threads 全球 没有
Mysqlx_worker_threads_active 全球 没有
mysqlx_write_timeout 会议

20.5.5.2 X插件选项和系统变量

要控制X插件的激活,请使用此选项:

  • --mysqlx[=value]

    属性
    命令行格式 --mysqlx[=value]
    介绍 8.0.11
    类型 列举
    默认值 ON
    有效值

    ON

    OFF

    FORCE

    FORCE_PLUS_PERMANENT

    此选项控制服务器在启动时加载X插件的方式。在MySQL 8.0中,默认情况下启用X插件,但此选项可用于控制其激活状态。

    选项值应该是可用于插件加载选项的选项之一,如 第5.6.1节“安装和卸载插件”中所述

如果启用了X插件,它会公开几个允许控制其操作的系统变量:

  • mysqlx_bind_address

    属性
    命令行格式 --mysqlx-bind-address=value
    系统变量 mysqlx_bind_address
    范围 全球
    动态 没有
    SET_VAR 提示适用 没有
    类型
    默认值 *

    X Plugin侦听TCP / IP连接的网络地址。此变量不是动态的,只能在启动时配置。这是bind_address系统变量的X Plugin等价物 ; 请参阅该变量描述以获取更多信息。

    如果mysqlx_bind_address被指定,其值必须是一个单个非通配符IP地址或主机名,或在允许对多个网络接口侦听的通配符地址格式中的一种(*0.0.0.0,或 ::)。

    IP地址可以指定为IPv4或IPv6地址。如果值是主机名,则X Plugin会将名称解析为IP地址并绑定到该地址。如果主机名解析为多个IP地址,则X插件使用第一个IPv4地址(如果有),否则使用第一个IPv6地址。

    X插件处理不同类型的地址,如下所示:

    • 如果地址是*,则X Plugin接受所有服务器主机IPv4接口上的TCP / IP连接,如果服务器主机支持IPv6,则接受所有IPv6接口上的TCP / IP连接。使用此地址允许X插件的IPv4和IPv6连接。该值是默认值。

    • If the address is 0.0.0.0, X Plugin accepts TCP/IP connections on all server host IPv4 interfaces.

    • If the address is ::, X Plugin accepts TCP/IP connections on all server host IPv4 and IPv6 interfaces.

    • If the address is an IPv4-mapped address, X Plugin accepts TCP/IP connections for that address, in either IPv4 or IPv6 format. For example, if X Plugin is bound to ::ffff:127.0.0.1, a client such as MySQL Shell can connect using --host=127.0.0.1 or --host=::ffff:127.0.0.1.

    • 如果地址是常规 IPv4或IPv6地址(例如127.0.0.1::1),则X Plugin仅接受该IPv4或IPv6地址的TCP / IP连接。

    如果绑定到地址失败,X插件会产生错误,服务器不会加载它。

  • mysqlx_connect_timeout

    属性
    命令行格式 --mysqlx-connect-timeout=#
    系统变量 mysqlx_connect_timeout
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 30
    最低价值 1
    最大价值 1000000000

    X插件等待从新连接的客户端接收第一个数据包的秒数。这是X插件的等价物 connect_timeout; 请参阅该变量以获取更多信息。

  • mysqlx_document_id_unique_prefix

    属性
    命令行格式 --mysqlx-document-id-unique-prefix=#
    系统变量 mysqlx_document_id_unique_prefix
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 0
    最低价值 0
    最大价值 65535

    设置将文档添加到集合时由服务器生成的文档ID的前4个字节。通过将此变量设置为每个实例的唯一值,可以确保文档ID在实例之间是唯一的。请参阅 了解文档ID

  • mysqlx_enable_hello_notice

    属性
    命令行格式 --mysqlx-document-id-unique-prefix[={OFF|ON}]
    系统变量 mysqlx_enable_hello_notice
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 布尔
    默认值 ON

    控制发送到试图通过X协议连接的经典MySQL协议客户端的消息。启用后,不支持尝试连接到服务器X协议端口的X协议的客户端会收到错误消息,说明它们使用了错误的协议。

  • mysqlx_idle_worker_thread_timeout

    属性
    命令行格式 --mysqlx-idle-worker-thread-timeout=#
    系统变量 mysqlx_idle_worker_thread_timeout
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 60
    最低价值 0
    最大价值 3600

    空闲工作线程终止之后的秒数。

  • mysqlx_interactive_timeout

    属性
    命令行格式 --mysqlx-interactive-timeout=#
    介绍 8.0.4
    系统变量 mysqlx_interactive_timeout
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 28800
    最低价值 1
    最大价值 2147483

    mysqlx_wait_timeout交互式客户端会话变量的默认值 (等待交互式客户端超时的秒数。)

  • mysqlx_max_allowed_packet

    属性
    命令行格式 --mysqlx-max-allowed-packet=#
    系统变量 mysqlx_max_allowed_packet
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 67108864
    最低价值 512
    最大价值 1073741824

    X插件可以接收的网络数据包的最大大小。这是X插件的等价物 max_allowed_packet; 请参阅该变量以获取更多信息。

  • mysqlx_max_connections

    属性
    命令行格式 --mysqlx-max-connections=#
    系统变量 mysqlx_max_connections
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 100
    最低价值 1
    最大价值 65535

    X插件可以接受的最大并发客户端连接数。这是X插件的等价物 max_connections; 请参阅该变量以获取更多信息。

    对于此变量的修改,如果新值小于当前连接数,则仅对新连接考虑新限制。

  • mysqlx_min_worker_threads

    属性
    命令行格式 --mysqlx-min-worker-threads=#
    系统变量 mysqlx_min_worker_threads
    范围 全球
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 2
    最低价值 1
    最大价值 100

    X Plugin用于处理客户端请求的最小工作线程数。

  • mysqlx_port

    属性
    命令行格式 --mysqlx-port=port_num
    系统变量 mysqlx_port
    范围 全球
    动态 没有
    SET_VAR 提示适用 没有
    类型 整数
    默认值 33060
    最低价值 1
    最大价值 65535

    X Plugin侦听TCP / IP连接的网络端口。这是X插件的等价物 port; 请参阅该变量以获取更多信息。

  • mysqlx_port_open_timeout

    属性
    命令行格式 --mysqlx-port-open-timeout=#
    系统变量 mysqlx_port_open_timeout
    范围 全球
    动态 没有
    SET_VAR 提示适用 没有
    类型 整数
    默认值 0
    最低价值 0
    最大价值 120

    X插件等待TCP / IP端口空闲的秒数。

  • mysqlx_read_timeout

    属性
    命令行格式 --mysqlx-read-timeout=#
    介绍 8.0.4
    系统变量 mysqlx_read_timeout
    范围 会议
    动态
    SET_VAR 提示适用 没有
    类型 整数
    默认值 28800
    最低价值 30
    最大价值 2147483

    X Plugin等待阻止读取操作完成的秒数。在此之后,如果读取操作不成功,则中止连接。

  • mysqlx_socket

    属性
    命令行格式 --mysqlx-socket=file_name
    系统变量 mysqlx_socket
    范围 全球
    动态 没有
    SET_VAR 提示适用 没有
    类型
    默认值 /tmp/mysqlx.sock

    The path to a Unix socket file which X Plugin uses for connections. This setting is only used by MySQL Server when running on Unix operating systems. Clients can use this socket to connect to MySQL Server using X Plugin.

    The default mysqlx_socket path and file name is based on the default path and file name for the main socket file for MySQL Server, with the addition of an x appended to the file name. The default path and file name for the main socket file is /tmp/mysql.sock, therefore the default path and file name for the X Plugin socket file is /tmp/mysqlx.sock.

    If you specify an alternative path and file name for the main socket file at server startup using the socket system variable, this does not affect the default for the X Plugin socket file. In this situation, if you want to store both sockets at a single path, you must set the mysqlx_socket system variable as well. For example in a configuration file:

    socket=/home/sockets/mysqld/mysql.sock
    mysqlx_socket=/home/sockets/xplugin/xplugin.sock
    

    If you change the default path and file name for the main socket file at compile time using the MYSQL_UNIX_ADDR compile option, this does affect the default for the X Plugin socket file, which is formed by appending an x to the MYSQL_UNIX_ADDR file name. If you want to set a different default for the X Plugin socket file at compile time, use the MYSQLX_UNIX_ADDR compile option.

    The MYSQLX_UNIX_PORT environment variable can also be used to set a default for the X Plugin socket file at server startup (see Section 4.9, “MySQL Program Environment Variables”). If you set this environment variable, it overrides the compiled MYSQLX_UNIX_ADDR value, but is overridden by the mysqlx_socket value.

  • mysqlx_ssl_ca

    Property Value
    Command-Line Format --mysqlx-ssl-ca=file_name
    System Variable mysqlx_ssl_ca
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type File name

    This is the X Plugin equivalent of ssl_ca; see that variable for more information.

  • mysqlx_ssl_capath

    Property Value
    Command-Line Format --mysqlx-ssl-capath=dir_name
    System Variable mysqlx_ssl_capath
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type Directory name

    This is the X Plugin equivalent of ssl_capath; see that variable for more information.

  • mysqlx_ssl_cert

    Property Value
    Command-Line Format --mysqlx-ssl-cert=name
    System Variable mysqlx_ssl_cert
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type File name

    This is the X Plugin equivalent of ssl_cert; see that variable for more information.

  • mysqlx_ssl_cipher

    Property Value
    Command-Line Format --mysqlx-ssl-cipher=name
    System Variable mysqlx_ssl_cipher
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type String

    The SSL cipher to use for X Protocol connections. This is the X Plugin equivalent of ssl_cipher; see that variable for more information.

  • mysqlx_ssl_crl

    Property Value
    Command-Line Format --mysqlx-ssl-crl=file_name
    System Variable mysqlx_ssl_crl
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type File name

    This is the X Plugin equivalent of ssl_crl; see that variable for more information.

  • mysqlx_ssl_crlpath

    Property Value
    Command-Line Format --mysqlx-ssl-crlpath=dir_name
    System Variable mysqlx_ssl_crlpath
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type Directory name

    This is the X Plugin equivalent of ssl_crlpath; see that variable for more information.

  • mysqlx_ssl_key

    Property Value
    Command-Line Format --mysqlx-ssl-key=file_name
    System Variable mysqlx_ssl_key
    Scope Global
    Dynamic No
    SET_VAR Hint Applies No
    Type File name

    This is the X Plugin equivalent of ssl_key; see that variable for more information.

  • mysqlx_wait_timeout

    Property Value
    Command-Line Format --mysqlx-wait-timeout=#
    Introduced 8.0.4
    System Variable mysqlx_wait_timeout
    Scope Session
    Dynamic Yes
    SET_VAR Hint Applies No
    Type Integer
    Default Value 28800
    Minimum Value 1
    Maximum Value 2147483

    The number of seconds that X Plugin waits for activity on a connection. After this time, if the read operation is not successful, the connection is aborted. If the client is noninteractive, the initial value of the session variable is copied from the global mysqlx_wait_timeout variable. For interactive clients, the initial value is copied from the session mysqlx_interactive_timeout.

  • mysqlx_write_timeout

    Property Value
    Command-Line Format --mysqlx-write-timeout=#
    Introduced 8.0.4
    System Variable mysqlx_write_timeout
    Scope Session
    Dynamic Yes
    SET_VAR Hint Applies No
    Type Integer
    Default Value 60
    Minimum Value 1
    Maximum Value 2147483

    The number of seconds that X Plugin waits for blocking write operations to complete. After this time, if the write operation is not successful, the connection is aborted.

20.5.6 Monitoring X Plugin

This section describes how to monitor X Plugin. There are two available methods of monitoring, using Performance Schema tables or status variables.

20.5.6.1 Status Variables for X Plugin

The status variables have the following meanings.

原文