日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

JSON數(shù)據(jù)類(lèi)型

更新時(shí)間:

Lindorm寬表引擎支持在建表、插入數(shù)據(jù)和更新數(shù)據(jù)時(shí)使用JSON數(shù)據(jù)類(lèi)型。JSON(JavaScriptObject Notation)是一種可以在多種語(yǔ)言之間進(jìn)行數(shù)據(jù)格式交換的數(shù)據(jù)類(lèi)型。JSON數(shù)據(jù)的格式為鍵值對(duì),結(jié)構(gòu)清晰,語(yǔ)法易讀,同時(shí)也方便前后端的數(shù)據(jù)傳輸。

適用引擎

JSON數(shù)據(jù)類(lèi)型僅適用于寬表引擎。

前提條件

寬表引擎為2.6.2及以上版本。如何查看或升級(jí)當(dāng)前版本,請(qǐng)參見(jiàn)寬表引擎版本說(shuō)明升級(jí)小版本

使用限制

Lindorm寬表的主鍵列不支持JSON數(shù)據(jù)類(lèi)型。

DDL

您可以在創(chuàng)建表或者修改表(新增列時(shí))語(yǔ)句中指定相關(guān)列為JSON數(shù)據(jù)類(lèi)型。

  • 創(chuàng)建表語(yǔ)句示例如下,相關(guān)語(yǔ)法請(qǐng)參見(jiàn)CREATE TABLE

    CREATE TABLE tb (p1 INT, c1 VARCHAR, c2 JSON, PRIMARY KEY(p1));
  • 修改表(新增c3列)語(yǔ)句示例如下,相關(guān)語(yǔ)法請(qǐng)參見(jiàn)ALTER TABLE

    ALTER TABLE tb ADD c3 JSON;
    說(shuō)明

    增加列時(shí),數(shù)據(jù)表不會(huì)被鎖定,DML請(qǐng)求可以正常進(jìn)行。

上述示例中,表tb的主鍵列為p1且數(shù)據(jù)類(lèi)型為INT。c1為非主鍵列且數(shù)據(jù)類(lèi)型為VARCHAR。c2為非主鍵列且數(shù)據(jù)類(lèi)型為JSON。c3為非主鍵列且數(shù)據(jù)類(lèi)型為JSON。通過(guò)以下語(yǔ)句查看tb的表結(jié)構(gòu)。

DESCRIBE tb;

返回結(jié)果如下:

+--------------+---------------------+------------------------+---------+----------------+------------+
| TABLE_SCHEMA |     TABLE_NAME      |      COLUMN_NAME       |  TYPE   | IS_PRIMARY_KEY | SORT_ORDER |
+--------------+---------------------+------------------------+---------+----------------+------------+
| default      | tb                  | p1                     | INT     | true           | ASC        |
| default      | tb                  | c1                     | VARCHAR | false          | none       |
| default      | tb                  | c2                     | JSON    | false          | none       |
| default      | tb                  | c3                     | JSON    | false          | none       |
+--------------+---------------------+------------------------+---------+----------------+------------+

DML

以下內(nèi)容介紹對(duì)JSON數(shù)據(jù)類(lèi)型的列進(jìn)行數(shù)據(jù)寫(xiě)入、讀取和刪除。

UPSERT

通過(guò)以下三種方式寫(xiě)入JSON數(shù)據(jù)。如果在JSON列中寫(xiě)入的數(shù)據(jù)不是JSON對(duì)象或者JSON字符串,寫(xiě)入過(guò)程中會(huì)報(bào)錯(cuò)。Lindorm寬表SQL提供的json_objectjson_array函數(shù)將寫(xiě)入的數(shù)據(jù)轉(zhuǎn)換為JSON對(duì)象。

  • 直接寫(xiě)入JSON字符串。列舉以下兩種寫(xiě)入方式。

    • 使用Statement()方式寫(xiě)入SQL,把JSON格式的字符串寫(xiě)入JSON列。

      Connection conn = DriverManager.getConnection("Lindorm URL", properties);
      Statement stmt = conn.createStatement();
      String jsonStr1 = "{\"k1\":4,\"k2\":{\"k3\":{\"k4\":4}}}"; 
      String upsertSQL = "UPSERT INTO tb(p1, c1, c2) VALUES(1, '1', '"+ jsonStr1 + "')"; 
      //返回寫(xiě)入數(shù)據(jù)條數(shù)
      int ret = stmt.executeUpdate(upsertSQL);
    • 使用PrepareStatement()方式寫(xiě)入SQL,先進(jìn)行SQL預(yù)處理再為該SQL模板的參數(shù)指定參數(shù)值。

      String jsonStr1 = "{\"k1\":4,\"k2\":{\"k3\":{\"k4\":4}}}";
      //寫(xiě)入的SQL模板
      String upsertSQL = "UPSERT INTO tb(p1, c1, c2) VALUES(1, '1', ?)";
      PreparedStatement preStmt = conn.prepareStatement(upsertSQL);
      //將JSON字符串寫(xiě)入JSON列
      preStmt.setString(1, jsonStr1);
      int ret = stmt.executeUpdate();
  • 使用json_object函數(shù)將函數(shù)中的數(shù)據(jù)按照寫(xiě)入順序轉(zhuǎn)換為key-value形式的JSON對(duì)象,再把JSON對(duì)象寫(xiě)入JSON列。

    String upsert = "UPSERT INTO tb(p1,c1,c2) VALUES(2,'2',json_object('k1', 2, 'k2', '2'))";

    如果使用Lindorm寬表SQL寫(xiě)入上述數(shù)據(jù)時(shí),請(qǐng)執(zhí)行以下語(yǔ)句。

    UPSERT INTO tb(p1,c1,c2) VALUES(2,'2','{"k1":2,"k2":"2"}');
  • 使用json_array函數(shù)將函數(shù)中的數(shù)據(jù)按照寫(xiě)入順序轉(zhuǎn)換為數(shù)組形式JSON對(duì)象,再把JSON對(duì)象寫(xiě)入JSON列。

    String  upsert = "UPSERT INTO " + tableName + "(p1,c1,c2) VALUES(3,'3', json_array(1, 2, json_object('k1', 3, 'k2', '3')))";

    如果使用Lindorm寬表SQL寫(xiě)入上述數(shù)據(jù)時(shí),請(qǐng)執(zhí)行以下語(yǔ)句。

    UPSERT INTO tb(p1,c1,c2) VALUES(3,'3','[1,2,{"k1":3,"k2":"3"}]');

結(jié)果驗(yàn)證

執(zhí)行以下語(yǔ)句,可以驗(yàn)證數(shù)據(jù)寫(xiě)入結(jié)果。

SELECT * FROM tb;

SELECT

在查詢JSON列的數(shù)據(jù)時(shí),需要使用json_extract函數(shù)返回JSON列的值或者對(duì)JSON列的值進(jìn)行條件過(guò)濾。

在Lindorm寬表SQL和MySQL中json_extract函數(shù)的用法類(lèi)似。查詢操作中json_extract函數(shù)可以在SELECT子句中或者WHERE子句中使用。

  • 當(dāng)json_extract函數(shù)在SELECT子句中使用時(shí),表示獲取JSON列上具體的值并返回給用戶。示例如下:

    • 寫(xiě)入的JSON列數(shù)據(jù)為"{\"k1\":1}"

      String json = "{\"k1\":1}";
      //SELECT子句中使用json_extract函數(shù),表示返回c2列中k1鍵的值,并將返回結(jié)果的列名設(shè)置為j
      String select = "select p1, c1, c2, json_extract(c2, '$.k1') j from tb where p1 = 1";
      ResultSet resultSet = stmt.executeQuery(select);
      resultSet.next();
      String resultC2 = resultSet.getString(c2);
      //resultC2等于c2列
      String resultC2k1 = resultSet.getString("j");
      //resultC2k1等于c2列中k1鍵的值,結(jié)果為1
    • 寫(xiě)入的JSON列數(shù)據(jù)為"{\"k1\":2,\"k2\":\"2\"}"

      String json ="{\"k1\":2,\"k2\":\"2\"}";
      //SELECT子句中使用json_extract函數(shù),表示返回c2列中k2鍵的值,并將返回結(jié)果的列名設(shè)置為j
      String select =  "select p1, c1, c2, json_extract(c2, '$.k2') j from tb where p1 = 2";
      ResultSet resultSet = stmt.executeQuery(select);
      resultSet.next();
      String resultC2 = resultSet.getString(c2);
      //resultC2等于c2列
      String resultC2k1 = resultSet.getString("j");
      //resultC2k1等于c2列中k2鍵的值,結(jié)果為2
    • 寫(xiě)入的JSON列數(shù)據(jù)為"[1,2,{\"k1\":3,\"k2\":\"3\"}]"

      String json ="[1,2,{\"k1\":3,\"k2\":\"3\"}]";
      //SELECT子句中使用json_extract函數(shù),表示返回c2列中JSON數(shù)組第2個(gè)index上的k2鍵的值,并將返回結(jié)果的列名設(shè)置j
      String "select json_extract(c2, '$[2].k2') j from  tb where p1 = 3";
      ResultSet resultSet = stmt.executeQuery(select);
      resultSet.next();
      String resultC2 = resultSet.getString(c2);
      //resultC2等于c2列
      String resultC2k1 = resultSet.getString("j");
      //resultC2k1等于JSON數(shù)組上index為2的JSON對(duì)象以k2為鍵的值,結(jié)果為3
  • 當(dāng)json_extract函數(shù)在WHERE子句中使用時(shí),表示獲取JSON列上具體的值并進(jìn)行條件過(guò)濾。如果json_extract函數(shù)在WHERE子句中涉及數(shù)據(jù)比較和篩選時(shí),不同數(shù)據(jù)類(lèi)型之間比較數(shù)據(jù)類(lèi)型的等級(jí),比較方式與MySQL的比較方式相同,具體請(qǐng)參見(jiàn)The JSON Data Type

    • 寫(xiě)入的JSON列數(shù)據(jù)為"{\"k1\":2,\"k2\":\"2\"}"

      String json =  "{\"k1\":2,\"k2\":\"2\"}";
      //WHERE子句中使用json_extract函數(shù),表示返回c2列中k2鍵的值大于0的數(shù)據(jù)
      String select = "select p1, c1, c2 from tb where where p1 >= 1 and p1 < 4 and json_extract(c2, '$.k2') > '0'";
      ResultSet resultSet = stmt.executeQuery(select);
      resultSet.next();
      String resultC2 = resultSet.getString(c2);
      //resultC2等于c2列
    • 寫(xiě)入的JSON列數(shù)據(jù)為"{\"k1\":4,\"k2\":{\"k3\":{\"k4\":4}}}"

      String json = "{\"k1\":4,\"k2\":{\"k3\":{\"k4\":4}}}";
      //WHERE子句中使用json_extract函數(shù),表示返回c2列的指定路徑'$.k2.k3.k4'的值大于4的數(shù)據(jù)
      String select = "select * from tb where p1 >= 4 and p1 < 6 and json_extract(c2, '$.k2.k3.k4') > 4";
      ResultSet resultSet = stmt.executeQuery(select);
      resultSet.next();
      String resultC2 = resultSet.getString(c2);
      //resultC2等于c2列
    • 寫(xiě)入的JSON列數(shù)據(jù)為"[1,2,{\"k1\":3,\"k2\":\"3\"}]"

      String json = "[1,2,{\"k1\":3,\"k2\":\"3\"}]";
      //WHERE子句中使用json_extract函數(shù),表示返回c2列中JSON數(shù)組第2個(gè)index上的k2鍵的值大于0的數(shù)據(jù)。
      String select = "select * from  tb where p1 >= 1 and p1 < 4 and json_extract(c2, '$[2].k2') > '0'";
      ResultSet resultSet = stmt.executeQuery(select);
      resultSet.next();
      String resultC2 = resultSet.getString(c2);
      //resultC2等于c2列

UPDATE

重要

執(zhí)行UPDATE的路徑必須是map格式。例如:c2列中k1路徑的值為2,則不允許更新k1路徑的值;c2列中k1路徑的值為{"k2":"value"},允許更新k1路徑的值。您可以通過(guò)UPSERT INTO語(yǔ)句,以正確的格式覆蓋原來(lái)的值,再進(jìn)行UPDATE操作。

在更新JSON列中指定路徑的數(shù)據(jù)時(shí),需要使用UPDATE語(yǔ)法,目前JSON列支持以下操作:

  • JSON_SET:更新JSON列中指定路徑的值或者新增不存在JSON列的路徑以及路徑上的值。

    例如:如果c2列中存在k1.k2路徑,那么將k1.k2路徑的值更新為value。如果c2列中不存在k1.k2路徑,則新增k1.k2路徑并將值設(shè)置為value。新增k1.k2路徑時(shí)需要確保存在k1路徑。

    UPDATE tb SET c2 = JSON_SET(c2, '$.k1.k2', 'value') WHERE p1 = 2;
  • JSON_INERT:插入不存在的JSON列路徑上的值。

    例如:如果c2列中不存在k1.k2路徑,則在k1.k2路徑上插入值nvalue,您需要確保存在k1路徑。

    UPDATE tb SET c2 = JSON_INSERT(c2 ,'$.k1.k2' ,'nvalue') WHERE p1 = 2;
  • JSON_REPLACE:更新已存在的JSON列路徑上的值。

    例如:如果c2列中存在k1路徑,那么將k1路徑的值更新為nvalue

    UPDATE tb SET c2 = JSON_REPLACE(c2 ,'$.k1' ,'nvalue') WHERE p1 = 2;
  • JSON_REMOVE:刪除已存在的JSON列路徑和路徑上的值。

    例如:如果c2列中存在k1路徑,那么刪除k1路徑和路徑的值。

    UPDATE tb SET c2 = JSON_REMOVE(c2 , '$.k1') WHERE p1 = 2;

結(jié)果驗(yàn)證

執(zhí)行以下語(yǔ)句,可以驗(yàn)證數(shù)據(jù)修改結(jié)果。

SELECT * FROM tb;

構(gòu)建二級(jí)索引

Lindorm寬表SQL支持為JSON數(shù)據(jù)類(lèi)型列中指定路徑的數(shù)據(jù)構(gòu)建二級(jí)索引,但是在構(gòu)建二級(jí)索引時(shí)需要指定JSON列的json_extract函數(shù)類(lèi)型。

語(yǔ)法

create_index_statement ::=  CREATE INDEX [ index_name ]
                                ON table_name '(' index_identifier ')'
                              [INCLUDE include_identifier]
                              [ASYNC]
                                 [ index_options ]
index_identifier       ::=  '('json_extract_type(column, json_path)')'
include_identifier   ::= '('column_name1,...,column_namen ')'

參數(shù)

參數(shù)

描述

index_name

索引表名。

table_name

寬表名。

json_extract_type

通過(guò)json_extract_type從JSON列中提取對(duì)應(yīng)的數(shù)據(jù)類(lèi)型的字段作為二級(jí)索引的,如果數(shù)據(jù)類(lèi)型不匹配則不構(gòu)建二級(jí)索引。支持以下函數(shù)類(lèi)型:

  • json_extract_string

  • json_extract_long

column

JSON列的列名。

json_path

JSON列的路徑,用于提取JSON列指定路徑的值。

ASYNC

異步構(gòu)建索引,不添加ASYNC表示同步構(gòu)建索引。

示例

為c3列中k1.k2路徑的數(shù)據(jù)(數(shù)據(jù)類(lèi)型為L(zhǎng)ONG)構(gòu)建二級(jí)索引,同時(shí)指定索引表的壓縮算法為ZSTD。如果數(shù)據(jù)類(lèi)型不是LONG,則不進(jìn)行構(gòu)建操作。

CREATE INDEX idx1 ON tb(json_extract_long(c2, '$.k1.k2')) INCLUDE(c1,c3) ASYNC 'COMPRESSION'='ZSTD';

結(jié)果驗(yàn)證

執(zhí)行以下語(yǔ)句,查看索引創(chuàng)建結(jié)果。

SHOW INDEX FROM tb;