Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20170714_MySQLドキュメントストア JSONデータ型&JSON関数 by 日本オラクル株式会社 MySQL GBU 山﨑由章

743 views

Published on

MySQL 5.7は、地図情報を使ったアプリケーションやJSONを扱うアプリケーションとの親和性が向上しています。本セッションでは、MySQL 5.7で刷新されたGIS(地理情報システム)機能や、MySQL 5.7で実装されたJSONデータ型やJSON関数等について、ご紹介いたします。地図情報を使ったアプリケーションや、JSONを扱うアプリケーションに関わられている方は、是非ご参加下さい!!

Published in: Technology
  • Be the first to comment

  • Be the first to like this

20170714_MySQLドキュメントストア JSONデータ型&JSON関数 by 日本オラクル株式会社 MySQL GBU 山﨑由章

  1. 1. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | MySQLドキュメントストア JSONデータ型&JSON関数 Yoshiaki Yamasaki / 山﨑 由章 MySQL Senior Sales Consultant, Asia Pacific and Japan updated: 2017/07/14
  2. 2. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. Safe Harbor Statement 以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。 また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことはでき ません。以下の事項は、マテリアルやコード、機能を提供することをコミットメントするも のではない為、購買決定を行う際の判断材料になさらないで下さい。 オラクル製品に関して記載されている機能の開発、リリースおよび時期については、 弊社の裁量により決定されます。 2
  3. 3. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 3 One of the most popular database in the world
  4. 4. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 4 MySQLの歴史 4.0 全文検索/GIS (MyISAM) 複数テーブルUPDATE/DELETE 組み込みライブラリ型サーバ OracleMySQL Sun 3.23 MyISAM InnoDB レプリケーション 5.1 プラグガブル・ ストレージエンジン・ アーキテクチャ パーティショニング タスクスケジューラ 5.6 memcached API UNDO表領域 Global Transaction ID マルチスレッドスレーブ オンラインALTER TABLE トランスポータブル表領域 5.5 InnoDBがデフォルトに 準同期型レプリケーション PERFORMANCE_SCHEMA 1.0-3.22以前 ストレージエンジン (ISAM, HEAP) マルチスレッド Windows対応/64bit対応 日本語文字コード (SJIS/UJIS) 5.0 ストアドプロシージャ ストアドファンクション カーソル/トリガ/ビュー XAトランザクション INFORMATION_SCHEMA 4.1 Unicode対応 サブクエリ CSV, ARCHIVE ndbcluster 1995 2000 2005 2010 2015 5.7 2015年10月21日 - 5.7.9 GA 新コストモデル オプティマイザ ロスレス レプリケーション マルチソース レプリケーション グループ レプリケーション(Up Coming) 全文検索CJK対応/GIS (InnoDB) セキュリティ強化 (コンプライアンス対応) NoSQLオプション (JSON) General Tablespace MySQL Router (HA) and more… Performance: Benchmark ・ 1995年:スウェーデンにてMySQL AB設立 (2005年:オラクルがInnobase Oyを買収) ・ 2008年:Sun MicrosystemsがMySQL ABを買収 ・ 2010年:オラクルがSun Microsystemsを買収
  5. 5. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 5 Agenda 1. ドキュメントストア概要 • リレーショナルとスキーマレス(ドキュメントデータ) 2. MySQL JSONデータ • JSONデータ型、JSON関数、生成列 3. ドキュメント処理拡張機能群 • X Protocol, X DevAPI, MySQL Shell 4. 備考 • その他,MySQL参考情報
  6. 6. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 6 ドキュメントストア概要
  7. 7. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. リレーショナルとスキーマレス? 7 両方共にそれぞれのアプローチ mysql> SELECT * FROM pizza; +------+------------------+-------+ | code | name | price | +------+------------------+-------+ | CLA | Classic Pizza | 400 | | MAR | Margherita Pizza | 500 | +------+------------------+-------+ mysql> SELECT * FROM toppings; +--------+------------+ | p_code | name | +--------+------------+ | CLA | Pepperoni | | CLA | Parmesan | | MAR | Basil | | MAR | Mozzarella | +--------+------------+ { "name":"Classic Pizza", "price":400, "toppings":[ "Pepperoni", "Parmesan" ] } { "name":"Margherita Pizza", "price":500, "toppings":[ "Basil", "Mozzarella" ], "options":[ { "name":"Olive", "price":100 } ] } リレーショナル スキーマレス (ドキュメント) 属性値のペアのコレクション表, カラム, 行
  8. 8. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. リレーショナル 8 □ アプリケーションに対し、スキーマの適用が容易 □スキーマにより長期的に、アプリケーションの変更管理がコントロールしやすい - 表, カラム, 行を使用して効率よくデータを管理 - データにいくつかの制約を設定可能 (データ型、外部キー制約等) - データ重複を削減する事が可能 (正規化) □ トランザクション: Atomicity, Consistency, Isolation, Durability □パワフルでオプティマイズ可能なSQL言語
  9. 9. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. スキーマレス (ドキュメント) • 形式・様式 (ex: XML, JSON) • ネストされた配列とオブジェクトツリー構造 ( [], {} ) • スキーマレス: スキーマ設計、正規化、外部キー、制約等の設計不要 • リレーショナルモデルで効率良くモデル化出来ないデータをより柔軟に表現可能 • 迅速且つ容易な設計・プロトタイピング • ORMを利用せずに、オブジェクトの永続化が可能 +------------------------------------------------------------------------------+ | body | +------------------------------------------------------------------------------+ | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | | {“id”: 2, “name”: “テレビ”, “price”: 30000, “Conditions”: [“USED”,2013]} | | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | +------------------------------------------------------------------------------+ 9 CREATE TABLE T_JSON_DOC (body json);
  10. 10. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 10 これらのデータを効率良く 管理する事が、出来ないか?
  11. 11. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. ドキュメントストア機能拡張 in MySQL5.7 • リレーショナル、スキーマレスを同じ技術スタックで利用可能 • MySQLに実装されている機能を活用可 (レプリケーション,InnoDB[ACID]等) • JSONデータ型と関数,追加されたCRUD APIによる容易な開発 11 開発チーム: [ x ] スキーマレス [ x ] 迅速なプロトタイプ/シンプルAPI [ x ] ドキュメントモデル オペレーション: [ x ] パフォーマンス管理/可視化 [ x ] 堅牢レプリケーション,バックアップ, リストア [ x ] 包括的なツールによるエコシステム ビジネス: [ x ] データを確実に保護 = ACIDトランザクション [ x ] 全てのデータをキャプチャー = 拡張性/スキーマレス [ x ] スケージュール/製品化の時間 = 迅速なサービス開発 【ステークスホルダーのニーズを満たす為の機能追加】
  12. 12. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. • 単一データベース – 既存のスキルでより多くのメンバーが 管理する事が可能 • 熟知したスキルで安定稼働 – 管理コストメリット – 少ないドライバーで処理可能 – 少ないツールで管理可能 – 容易なデータ連携 – 運用及び分析を一緒に – SQL処理, CRUD処理共に可能 • 複数の異なったデータベース – 追加のスキルレパートリーが必要, より複雑な管理・開発 … • スキルの取得がより困難に – 管理コストが増加 – 複数のドライバーが必用 – 複数の管理ツールが必用 – データ連携に工数・コストがかかる – 運用と分析を別々のシステムで処理 単一 vs 複数データベースで管理? 12  Relational Tables  Schema less JSON Collection  Relational Tables  Schema less JSON Collection
  13. 13. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 概要:MYSQLのドキュメントストア機能拡張 13 • JSONサポート JSONデータ型(utf8mb4)・JSONファンクション Generated Column(生成列)とIndexによる検索の高速化 MySQL 5.7.9(GA)~ • X Protocol ☑ GA MySQLサーバをドキュメントストアとして拡張する為に、 Xプラグイン(mysqlx)により実装 • X DevAPI ☑ Development Release SQL処理とドキュメントに対してのCRUD処理 Connector/Node.js, Connector/J, Connector/Net, Connector/pythonに実装 • mysqlsh ☑ GA コマンドラインクライアント (Javascript, Python, SQL), Sharding 機能開発中 MySQL 5.7.12~ 参考: https://dev.mysql.com/doc/refman/5.7/en/document-store.html
  14. 14. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 14 MySQL JSONデータ MySQL 5.7.9 ~
  15. 15. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL5.7: ストレージオプション • Text –高速なinsert処理 –ヒューマンリーダブル • Binary (JSON型) –1度のみ検証 –高速な参照 –インプレースUpdate –構文検証が必要 –構文解析が必要 –Updateが困難 –Insert処理が遅い –そのままでは解読不可 Advantage Disadvantage
  16. 16. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSONデータ型  ネイティブJSONデータ型 (バイナリ形式)  Insert時のJSON構文バリデーション機能  組み込みJSON関数 (保存、検索、更新、操作)  ドキュメントにインデックス設定し高速アクセス  SQLとの統合を容易にする、新しいインライン構文  utf8mb4の文字セットとutf8mb4_binの照合 「🐬」  サイズはmax_allowed_packetの値で制限 (Default:4MB) 外部サイト /SNS モバイル デバイス コマース /ポータル その他 (data JSON); REST/JSON mysql> select feature from NEW57.features where json_extract(feature,'$.properties.STREET') = 'MARKET' limit 1¥G ************** 1. row ************** feature: {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[-122.39836263491878, 37.79189388899312, 0], [-122.39845248797837, 37.79233030084018, 0], [-122.39768507706792, 37.7924280850133, 0], [-122.39836263491878, 37.79189388899312, 0]]]}, "properties": {"TO_ST": "388", "BLKLOT": "0265003", "STREET": "MARKET", "FROM_ST": "388", "LOT_NUM": "003", "ST_TYPE": "ST", "ODD_EVEN": "E", "BLOCK_NUM": "0265", "MAPBLKLOT": "0265003"}} 16
  17. 17. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSONデータ型: サポート 17 JSONで表現する全てのデータ型をサポート •数値, 文字列, bool(true,false) •オブジェクト {“キー”: “値”}, 配列 [123456, “String”, …] •null 拡張 •日付(date), 時刻, 日付(datetime), タイムスタンプ, その他 [CONFIRM]> show create table T_JSON_SUPPORT¥G *************************** 1. row *************************** Table: T_JSON_SUPPORT Create Table: CREATE TABLE `T_JSON_SUPPORT` ( `id` int(10) NOT NULL AUTO_INCREMENT, `body` json DEFAULT NULL, `type` varchar(20) GENERATED ALWAYS AS (json_type(`body`)) VIRTUAL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 [CONFIRM]> select * from T_JSON_SUPPORT; +----+---------------------------------------------+----------+ | id | body | type | +----+---------------------------------------------+----------+ | 1 | 123456789 | INTEGER | | 2 | NULL | NULL | | 3 | true | BOOLEAN | | 4 | "abcde" | STRING | | 5 | {“id”: 5, “name”: “オブジェクト”} | OBJECT | | 6 | [-122.42200352825247, 37.80848009696725, 0] | ARRAY | | 7 | "2016-02-29" | DATE | | 8 | "2016-02-29 00:00:00.000000" | DATETIME | +----+---------------------------------------------+----------+
  18. 18. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSONデータ型: Create and Insert 18 CREATE TABLE employees (data JSON); INSERT INTO employees VALUES ('{"id": 1, "name": "Jane"}'); INSERT INTO employees VALUES ('{"id": 2, "name": "Joe"}'); SELECT * FROM employees; +---------------------------+ | data | +---------------------------+ | {"id": 1, "name": "Jane"} | | {"id": 2, "name": "Joe"} | +---------------------------+ 2 rows in set (0,00 sec) JSONデータ型を指定して、テーブル内に列を作成 メモ:JSON配列は内カンマで区切られ、囲まれた値のリスト[と]の文字が含まれています。 JSONオブジェクトは、{と}文字以内カンマで区切られ、囲まれたキー/値のペアのセットが含まれています。
  19. 19. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. utf8mb4 文字セット SET @j = JSON_OBJECT('key', 'value'); [NEW57]> SELECT @j; +------------------+ | @j | +------------------+ | {"key": "value"} | +------------------+ 1 row in set (0.00 sec) [NEW57]> SELECT CHARSET(@j), COLLATION(@j); +-------------+---------------+ | CHARSET(@j) | COLLATION(@j) | +-------------+---------------+ | utf8mb4 | utf8mb4_bin | +-------------+---------------+ 1 row in set (0.00 sec) JSONに変換した文字列はグローバル対応の為, utf8mb4の文字セットとutf8mb4_binの照合がDefaultです。 utf8mb4_binがバイナリ照合であるため、JSON値の比較では、大文字と小文字は区別されます。
  20. 20. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON Comparator 20 SELECT CAST(1 AS JSON) = 1; +---------------------+ | CAST(1 AS JSON) = 1 | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec) JSON 1の値は1と等しい JSON 1の値は’1’と不等 ● 多相性挙動 ● シームレスかつ一貫性のある比較 ● 堅牢性 ● キャッシングの広範な使用による参照処理の最適化 SELECT CAST(1 AS JSON) = '1'; +-----------------------+ | CAST(1 AS JSON) = '1' | +-----------------------+ | 0 | +-----------------------+ 1 row in set (0.00 sec) - JSON vs JSON, JSON vs SQLを比較する事が出来ます - 異なるデータは常に等しくない為、自動的な型変換は行いません https://dev.mysql.com/worklog/task/?id=8249
  21. 21. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. TEXT/VARCHARと比較した優位性 1. JSONドキュメントデータ形式の検証 2. 効率の良い、バイナリーフォーマットでストレージエンジンに格納し、 21 INSERT INTO employees VALUES ('some random text'); ERROR 3130 (22032): Invalid JSON text: "Expect a value here." at position 0 in value (or column) 'some random text'. 出力時にテキスト変換している為、オブジェクトメンバと配列要素への 参照性能が向上
  22. 22. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 22 MySQL JSONデータ処理 JSONデータ型と生成列による、 INDEXを利用した高速な参照処理 JSON関数を利用したデータ処理 JSONドキュメントの一部のみ更新可 UPDATE T_JSON_DOC set T_JSON_DOC.body = JSON_REPLACE(body,"$.price",FLOOR(10000 + (RAND() * 9000))) where id = 3
  23. 23. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 23 [CONFIRM]> show create table T_Character_COLLATE_utf8mb4_bin¥G *************************** 1. row *************************** Table: T_Character_COLLATE_utf8mb4_bin Create Table: CREATE TABLE `T_Character_COLLATE_utf8mb4_bin` ( `pid` int(10) unsigned NOT NULL AUTO_INCREMENT, `string1` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `string2` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `string1_w_string` char(8) GENERATED ALWAYS AS (hex(weight_string(`string1`))) VIRTUAL, `string2_w_string` char(8) GENERATED ALWAYS AS (hex(weight_string(`string2`))) VIRTUAL, `compare` char(1) GENERATED ALWAYS AS ((`string1` = `string2`)) VIRTUAL, PRIMARY KEY (`pid`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 [CONFIRM]> insert into T_Character_COLLATE_utf8mb4_bin(string1,string2) values('A','a'); Query OK, 1 row affected (0.00 sec) [CONFIRM]> insert into T_Character_COLLATE_utf8mb4_bin(string1,string2) values('あ','ぁ'); Query OK, 1 row affected (0.00 sec) [CONFIRM]> insert into T_Character_COLLATE_utf8mb4_bin(string1,string2) values('A','A'); Query OK, 1 row affected (0.00 sec) [CONFIRM]> select * from T_Character_COLLATE_utf8mb4_bin; +-----+---------+---------+------------------+------------------+---------+ | pid | string1 | string2 | string1_w_string | string2_w_string | compare | +-----+---------+---------+------------------+------------------+---------+ | 1 | A | a | 000041 | 000061 | 0 | | 2 | あ | ぁ | 003042 | 003041 | 0 | | 3 | A | A | 000041 | 000041 | 1 | +-----+---------+---------+------------------+------------------+---------+ Generated Columns (生成列)とは? 式から生成された列 GENERATED ALWAYSは省略可能 VIRTUALと STOREDの2種類 Default: VIRTUAL 自動的に計算された列と値
  24. 24. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. ファンクショナル・インデックス 24 [NEW57]> CREATE TABLE `T_JSON` ( `id` int(11) NOT NULL AUTO_INCREMENT, `feature` json NOT NULL, `feature_type` varchar(30) GENERATED ALWAYS AS (json_unquote(feature->"$.type")) VIRTUAL, `feature_street` varchar(30) GENERATED ALWAYS AS (json_extract(`feature`,‘$.properties.STREET’)) VIRTUAL, PRIMARY KEY (`id`), KEY `idx_feature_street` (`feature_street`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; [NEW57]> alter table features add index idx_feature_type(`feature_type`); Query OK, 0 rows affected (6.14 sec) Records: 0 Duplicates: 0 Warnings: 0 生成列に対し,オンラインでインデックスを追加。 → 高速なJSONデータの検索が可能に!! 生成列を使用して列を作成 対象:JSONデータから情報を抽出 (例) User ID, 製品ID, サービスID等 [NEW57]> explain select distinct(feature_type) from features; +----+-------------+----------+------------+-------+------------------+------------------+---------+------+--------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+-------+------------------+------------------+---------+------+--------+----------+-------------+ | 1 | SIMPLE | features | NULL | index | idx_feature_type | idx_feature_type | 123 | NULL | 199013 | 100.00 | Using index | +----+-------------+----------+------------+-------+------------------+------------------+---------+------+--------+----------+-------------+ インデックス利用で処理が 1.25秒 → 0.06秒 Generated Columns (生成列)とは?
  25. 25. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 25 [NEW57]> select feature_type,feature_street from T_JSON limit 10,5; +--------------+----------------+ | feature_type | feature_street | +--------------+----------------+ | Feature | "JEFFERSON" | | Feature | "TAYLOR" | | Feature | "BEACH" | | Feature | "BEACH" | | Feature | "JEFFERSON" | +--------------+----------------+ ① `feature_type` varchar(30) GENERATED ALWAYS AS (json_unquote(feature->"$.type")) VIRTUAL ② `feature_street` varchar(30) GENERATED ALWAYS AS (json_extract(`feature`,'$.properties.STREET')) VIRTUAL ① ② 参考: JSONとファンクショナル・インデックス □ json_extractと->は同等 □ 必要に応じてjson_unquoteでQuoteを外して列を作成 `feature_type` varchar(30) GENERATED ALWAYS AS (json_unquote(feature->"$.type")) VIRTUAL `feature_type` varchar(30) GENERATED ALWAYS AS (json_unquote(json_extract(`feature`,'$.type'))) VIRTUAL select feature from features where feature_street = '"MARKET"'; (左側は列識別子で右側 は JSONパス)
  26. 26. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 生成列に設定可能なインデックスオプション 26 Generated Column (STORED) 挿入・更新時に演算、値を格納 データも含まれる為、参照が早い Generated Column (VIRTUAL) 参照時に演算、値は格納しない メタデータ変更のみ、INSERT/UPDATEが早い Primary and Secondary BTREE, Fulltext, GIS Mixed with fields Requires table rebuild Not Online Secondary Only BTREE Only Mixed with virtual column only No table rebuild INSTANT Alter Faster Insert Bottom Line: 主キー, FULLTEXTまたは仮想GISインデックスを必要とする場合を除き,デフォルトのVIRTUALで問題無い。 Advantage Disadvantage
  27. 27. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 27 ALTER TABLE T_ONLINE ALGORITHM=INPLACE, ADD feature_type varchar(30) AS (feature->"$.type") VIRTUAL; Query OK, 0 rows affected (0.08 sec) Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE T_ONLINE ALGORITHM=INPLACE, ADD feature_type varchar(30) AS (feature->"$.type") STORED; ERROR 1845 (0A000): ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY. ALTER TABLE T_ONLINE ADD feature_type varchar(30) AS (feature->"$.type") STORED; Query OK, 206560 rows affected (6.17 sec) Records: 206560 Duplicates: 0 Warnings: 0 生成列に設定可能なインデックスオプション (続き) VIRTUAL STORED メタデータの変更のみでオンライン処理可能 但し、データを呼び出す度にCPU処理が発生する 実データを含む為、作成時は参照のみが可能 データを含む為、高速だが追加でディスク容量が必用
  28. 28. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 28 JSON関数 • 情報取得 – JSON_VALID() – JSON_TYPE() – JSON_KEYS() – JSON_LENGTH() – JSON_DEPTH() – JSON_CONTAINS() – JSON_CONTAINS_PATH() • データ編集 – JSON_REMOVE() – JSON_APPEND() – JSON_SET() – JSON_INSERT() – JSON_REPLACE() – JSON_ARRAY_INSERT() – JSON_ARRAY_APPEND() • データ作成 – JSON_MERGE() – JSON_ARRAY() – JSON_OBJECT() • データ取得 – JSON_EXTRACT() – JSON_SEARCH() – -> /* JSON_EXTRACT() */ – ->> /* JSON_UNQUOTE(JSON_EXTRACT()) */ • ヘルパー – JSON_QUOTE() – JSON_UNQUOTE() – JSON_VALID() 参照: https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html ※ JSON_APPEND()は、MySQL 5.7.9で JSON_ARRAY_APPEND()に変更されました。
  29. 29. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. • 現在開発中のMySQL 8.0でも、JSON関数は引き続き拡張中 – JSON_PRETTY() – JSON_STORAGE_SIZE() – JSON_STORAGE_FREE() – JSON_ARRAYAGG() – JSON_OBJECTAGG() 29 JSON関数
  30. 30. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON関数でドキュメントの情報を取得 30 [NEW57]> SELECT JSON_VALID(body) from T_JSON_DOC where id = 5; +------------------+ | JSON_VALID(body) | +------------------+ | 1 | +------------------+ [NEW57]> SELECT JSON_TYPE(body) from T_JSON_DOC where id = 5; +-----------------+ | JSON_TYPE(body) | +-----------------+ | OBJECT | +-----------------+ [NEW57]> SELECT JSON_KEYS(body) from T_JSON_DOC where id = 5; +---------------------------------------+ | JSON_KEYS(body) | +---------------------------------------+ | ["id", "name", "price", "Conditions"] | +---------------------------------------+
  31. 31. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 31 リレーショナルテーブルからJSONデータ生成 Relational In, Relational + Document Out データがリレーショナルテーブルに格納されていても、フロントエンドは JSONを使用する事が可能 JSONは多くの言語でネイティブデータ構造に直接マッピングされます アプリケーションコードの使用が容易になるケースがある JavaScript, Python, Ruby, その他 ブラウザのJavaScriptとのデータ連携が容易 Relational REST/JSON DML
  32. 32. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. リレーショナルテーブルからJSONデータ生成 SELECT NAME,CountryCode from world.City where CountryCode ='JPN' limit 1; +-------+-------------+ | NAME | CountryCode | +-------+-------------+ | Tokyo | JPN | +-------+-------------+ 32 SELECT JSON_OBJECT('CITY',NAME,'Country',CountryCode) from world.City where CountryCode ='JPN' limit 1; +------------------------------------------------+ | JSON_OBJECT('CITY',NAME,'Country',CountryCode) | +------------------------------------------------+ | {"CITY": "Tokyo", "Country": "JPN"} | +------------------------------------------------+ リレーショナルから スキーマレスへの変換 [NEW57]> CREATE VIEW v_City_json AS -> SELECT JSON_OBJECT('ID', ID, 'name', Name, 'CountryCode', CountryCode, 'District', District,'Population',Population) as doc FROM City where CountryCode = 'JPN'; Query OK, 0 rows affected (0.01 sec) [NEW57]> select * from v_City_json limit 1¥G *************************** 1. row *************************** doc: {"ID": 1532, "name": "Tokyo", "District": "Tokyo-to", "Population": 7980230, "CountryCode": "JPN"} 1 row in set (0.01 sec) 例) ビュー JSON関数: JSON_OBJECT(), JSON_ARRAY()でJSONを組み立てる 更新と挿入は引き続きテーブルの列を介して行われます
  33. 33. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 33 値の(空を含む)リストを評価し、それらの値を含むJSON配列を返します。 リレーショナルテーブルからJSONデータ生成 JSON関数: JSON_OBJECT(), JSON_ARRAY()でJSONを組み立てる SELECT NAME,CountryCode from world.City where CountryCode ='JPN' limit 1; +-------+-------------+ | NAME | CountryCode | +-------+-------------+ | Tokyo | JPN | +-------+-------------+ [NEW57]> SELECT JSON_ARRAY(NAME,CountryCode) from world.City where CountryCode ='JPN' limit 1; +------------------------------+ | JSON_ARRAY(NAME,CountryCode) | +------------------------------+ | ["Tokyo", "JPN"] | +------------------------------+ [NEW57]> select feature from features limit 10,1¥G *************************** 1. row *************************** feature: {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[-122.41629403378657, 37.807666226310545, 0], [-122.4162948864558, 37.80767056801045, 0], [-122.41636926744471, 37.80804964445761, 0], [-122.41590475297633, 37.80810646146374, 0], [-122.41582868876579, 37.8077282259018, 0], [-122.41598542756716, 37.80770884145562, 0], [- 122.41615558481081, 37.807683349374365, 0], [-122.41629403378657, 37.807666226310545, 0]]]}, "properties": {"TO_ST": "229", "BLKLOT": "0012001", "STREET": "JEFFERSON", "FROM_ST": "211", "LOT_NUM": "001", "ST_TYPE": "ST", "ODD_EVEN": "O", "BLOCK_NUM": "0012", "MAPBLKLOT": "0012001"}} [NEW57]> SELECT JSON_ARRAY(id,feature->"$.properties.STREET",feature->"$.type") AS json_array FROM features ORDER BY id LIMIT 10,1; +------------------------------+ | json_array | +------------------------------+ | [11, "JEFFERSON", "Feature"] | +------------------------------+ リレーショナルから スキーマレスへの変換
  34. 34. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 34 [CONFIRM]> select * from T_JSON_PLACE; +----+-------------------------------------+----------+-----------+ | id | place | latitude | longitude | +----+-------------------------------------+----------+-----------+ | 1 | 東京都港区北青山2-5-8 | 35.67125 | 139.71864 | | 2 | 大阪府大阪市北区堂2-4-27 | 34.69584 | 135.49291 | +----+-------------------------------------+----------+-----------+ [CONFIRM]> select JSON_OBJECT('ID',id,'住所',place,'緯度経度', JSON_ARRAY(latitude,longitude)) from T_JSON_PLACE; +---------------------------------------------------------------------------------------------------+ | JSON_OBJECT('ID',id,'住所',place,'緯度経度', JSON_ARRAY(latitude,longitude)) | +---------------------------------------------------------------------------------------------------+ | {"ID": 1, "住所": "東京都港区北青山2-5-8", "緯度経度": [35.67125, 139.71864]} | | {"ID": 2, "住所": "大阪府大阪市北区堂2-4-27", "緯度経度": [34.69584, 135.49291]} | +---------------------------------------------------------------------------------------------------+ リレーショナルテーブルからJSON抽出 JSON関数: JSON_OBJECT(), JSON_ARRAY()でJSONを組み立てる JSON_ARRAYとJSON_OBJECTを組み合わせてJSONデータを使用する事も可能 オブジェクト {}は、順序が異なっても同じキーと値のペアを含んでいれば同値だが、 配列[]は順序が意味を持つ為、順序が異なると同値では無い。 ST_AsGeoJSONやST_GeomFromGeoJSON等のSpatial GeoJSON Functionsで空間を表すJSONを処理可能
  35. 35. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON Path Search JSON形式のドキュメント内の指定された値のパスを返します To retrieve via: [[database.]table.]column->"$<path spec>" 35 SELECT JSON_SEARCH(feature, 'one', 'MARKET') AS extract_path FROM features WHERE id = 121254; +-----------------------+ | extract_path | +-----------------------+ | "$.properties.STREET" | +-----------------------+ SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254; +-----------------+ | property_street | +-----------------+ | "MARKET" | +-----------------+ feature: {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[-122.39790233801507, 37.790726654724864, 0], [-122.39823963293078, 37.79099174693105, 0], [-122.39835208359005, 37.79090296883558, 0], [-122.3986901921814, 37.79116869825866, 0], [-122.39823249443299, 37.7915300431353, 0], [-122.39756221186288, 37.79099545718336, 0], [-122.39790233801507, 37.790726654724864, 0]]]}, "properties": {"TO_ST": "425", "BLKLOT": "3709016", "STREET": "MARKET", "FROM_ST": "425", "LOT_NUM": "016", "ST_TYPE": "ST", "ODD_EVEN": "O", "BLOCK_NUM": "3709", "MAPBLKLOT": "3709014"}} “$”はJSONドキュメント全体で,オブジェクトメンバーは“.”に続いてパスを表現
  36. 36. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_REMOVE() 36 JSONドキュメントからデータを削除し、結果を返します。 [NEW57]> select * from T_JSON_DOC; +----+---------------------------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+---------------------------------------------------------------------------------------------------+------------+ | 1 | {"id": 1, "name": "自転車", "price": 10000, "Conditions": ["NEW", 2015, "Excellent"]} | 10000.00 | | 2 | {“id”: 2, “name”: “テレビ”, “price”: 30000, “Conditions”: [“USED”, 2013, “故障”]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 17131, "Conditions": ["NEW", 2015]} | 17131.00 | | 4 | {“id”: 4, “name”: “オートバイ”, “price”: 500000, “Conditions”: [“NEW”, 2015]} | 500000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Quantity": "[1,10]", "Conditions": ["NEW", 2015]} | 25000.00 | +----+---------------------------------------------------------------------------------------------------+------------+ [NEW57]> select JSON_REMOVE(body,"$.Quantity") from T_JSON_DOC where id = 5; +-----------------------------------------------------------------------------+ | JSON_REMOVE(body,"$.Quantity") | +-----------------------------------------------------------------------------+ | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | +-----------------------------------------------------------------------------+ [NEW57]> update T_JSON_DOC set body = JSON_REMOVE(body,"$.Quantity") where id = 5;
  37. 37. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_SET () 37 JSONドキュメントにデータを挿入または更新し、結果を返します。 replaces existing values and adds nonexisting values. [NEW57]> select * from T_JSON_DOC; +----+------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+------------------------------------------------------------------------------+------------+ | 1 | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | 10000.00 | | 2 | {"id": 2, "name": "テレビ", "price": 30000, "Conditions": ["USED",2013]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | 11154.00 | | 4 | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | 50000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | 25000.00 | +----+------------------------------------------------------------------------------+------------+ [NEW57]> SELECT JSON_SET(body,'$.name',"オートバイ", '$.price',500000) from T_JSON_DOC where id = 4; +------------------------------------------------------------------------------------+ | JSON_SET(body,'$.name',"オートバイ", '$.price',500000) | +------------------------------------------------------------------------------------+ | {"id": 4, "name": "オートバイ", "price": 500000, "Conditions": ["NEW", 2015]} | +------------------------------------------------------------------------------------+ [NEW57]> update T_JSON_DOC set body = JSON_SET(body,'$.name',"オートバイ", '$.price',500000) where id = 4;
  38. 38. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_INSERT () 38 JSONドキュメントにデータを挿入し、結果を返します inserts values without replacing existing values. [NEW57]> select * from T_JSON_DOC; +----+------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+------------------------------------------------------------------------------+------------+ | 1 | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | 10000.00 | | 2 | {"id": 2, "name": "テレビ", "price": 30000, "Conditions": ["USED",2013]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | 11154.00 | | 4 | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | 50000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | 25000.00 | +----+------------------------------------------------------------------------------+------------+ [NEW57]> select JSON_INSERT(body,'$.Quantity','[1,10]') from NEW57.T_JSON_DOC where id = 5; +---------------------------------------------------------------------------------------------------+ | JSON_INSERT(body,'$.Quantity','[1,10]') | +---------------------------------------------------------------------------------------------------+ | {"id": 5, "name": "自転車", "price": 25000, "Quantity": "[1,10]", "Conditions": ["NEW", 2015]} | +---------------------------------------------------------------------------------------------------+ [NEW57]> update NEW57.T_JSON_DOC set body = JSON_INSERT(body,'$.Quantity','[1,10]') where id = 5;
  39. 39. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_REPLACE () 39 JSON文書の既存の値を置き換え、その結果を返します。 replaces only existing values. [NEW57]> select * from T_JSON_DOC; +----+------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+------------------------------------------------------------------------------+------------+ | 1 | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | 10000.00 | | 2 | {“id”: 2, “name”: “テレビ”, “price”: 30000, “Conditions”: [“USED”,2013]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | 11154.00 | | 4 | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | 50000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | 25000.00 | +----+------------------------------------------------------------------------------+------------+ [NEW57]> select JSON_REPLACE(body,"$.price",FLOOR(10000 + (RAND() * 9000))) from T_JSON_DOC where id = 3; +-----------------------------------------------------------------------------+ | JSON_REPLACE(body,"$.price",FLOOR(10000 + (RAND() * 9000))) | +-----------------------------------------------------------------------------+ | {"id": 3, "name": "冷蔵庫", "price": 18359, "Conditions": ["NEW", 2015]} | +-----------------------------------------------------------------------------+ [NEW57]> update T_JSON_DOC set body = JSON_REPLACE(body,"$.price",FLOOR(10000 + (RAND() * 9000))) where id = 3;
  40. 40. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_ARRAY_INSERT () 40 JSONドキュメントを更新し、ドキュメント内の配列に挿入し変更されたその結果を返します [NEW57]> select * from T_JSON_DOC; +----+------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+------------------------------------------------------------------------------+------------+ | 1 | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | 10000.00 | | 2 | {"id": 2, "name": "テレビ", "price": 30000, "Conditions": ["USED",2013]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | 11154.00 | | 4 | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | 50000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | 25000.00 | +----+------------------------------------------------------------------------------+------------+ SELECT JSON_ARRAY_INSERT(body,'$.Conditions[2]','January') from T_JSON_DOC where id = 5; +----------------------------------------------------------------------------------------+ | JSON_ARRAY_INSERT(body,'$.Conditions[2]','January') | +----------------------------------------------------------------------------------------+ | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015, "January"]} | +----------------------------------------------------------------------------------------+ [NEW57]> update T_JSON_DOC set body = JSON_ARRAY_INSERT(body,'$.Conditions[2]','January') where id = 5;
  41. 41. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_ARRAY_APPEND () 41 JSONドキュメント内の指定された配列の最後に値を追加し、結果を返します [NEW57]> select * from T_JSON_DOC; +----+------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+------------------------------------------------------------------------------+------------+ | 1 | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | 10000.00 | | 2 | {"id": 2, "name": "テレビ", "price": 30000, "Conditions": ["USED",2013]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | 11154.00 | | 4 | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | 50000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | 25000.00 | +----+------------------------------------------------------------------------------+------------+ [NEW57]> select JSON_ARRAY_APPEND(body,'$.Conditions','故障') from NEW57.T_JSON_DOC where id = 2; +----------------------------------------------------------------------------------------+ | JSON_ARRAY_APPEND(body,'$.Conditions','故障') | +----------------------------------------------------------------------------------------+ | {"id": 2, "name": "テレビ", "price": 30000, "Conditions": ["USED", 2013, "故障"]} | +----------------------------------------------------------------------------------------+ [NEW57]> update T_JSON_DOC set body = JSON_ARRAY_APPEND(body,'$.Conditions','故障') where id = 2;
  42. 42. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSON_MERGE () 42 2つ以上のJSONドキュメントをマージし、マージした結果を返します [NEW57]> select * from T_JSON_DOC; +----+------------------------------------------------------------------------------+------------+ | id | body | price_only | +----+------------------------------------------------------------------------------+------------+ | 1 | {“id”: 1, “name”: “自転車”, “price”: 10000, “Conditions”: [“NEW”, 2015]} | 10000.00 | | 2 | {"id": 2, "name": "テレビ", "price": 30000, "Conditions": ["USED",2013]} | 30000.00 | | 3 | {"id": 3, "name": "冷蔵庫", "price": 11154, "Conditions": ["NEW", 2015]} | 11154.00 | | 4 | {"id": 4, "name": "冷蔵庫", "price": 50000, "Conditions": ["NEW", 2015]} | 50000.00 | | 5 | {"id": 5, "name": "自転車", "price": 25000, "Conditions": ["NEW", 2015]} | 25000.00 | +----+------------------------------------------------------------------------------+------------+ [NEW57]> SELECT JSON_MERGE(body,'{"Conditions":"Excellent"}') from T_JSON_DOC where id = 1; +------------------------------------------------------------------------------------------+ | JSON_MERGE(body,'{"Conditions":"Excellent"}') | +------------------------------------------------------------------------------------------+ | {"id": 1, "name": "自転車", "price": 10000, "Conditions": ["NEW", 2015, "Excellent"]} | +------------------------------------------------------------------------------------------+ [NEW57]> update T_JSON_DOC set body = JSON_MERGE(body,'{"Conditions":"Excellent"}') where id = 1;
  43. 43. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. JSONドキュメントの圧縮 • 圧縮効率が良い • スキーマレスの為、識別子は各ドキュメント内で繰り返し使われている。 • 反復は圧縮効率を高めます。 • MySQL 5.7 では32KBと64KB pagesをサポート (improved compression) 43 [NEW57]> SELECT JSON_KEYS(feature) from features; +------------------------------------+ | JSON_KEYS(feature) | +------------------------------------+ | ["type", "geometry", "properties"] | | ["type", "geometry", "properties"] | | ["type", "geometry", "properties"] | <SNIP> | ["type", "geometry", "properties"] | | ["type", "geometry", "properties"] | | ["type", "geometry", "properties"] | | ["type", "geometry", "properties"] | +------------------------------------+ [NEW57]> SELECT JSON_KEYS(feature),count(*) from features group by JSON_KEYS(feature); +------------------------------------+----------+ | JSON_KEYS(feature) | count(*) | +------------------------------------+----------+ | ["type", "geometry", "properties"] | 206560 | +------------------------------------+----------+
  44. 44. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 44 ドキュメント処理拡張機能 MySQL 5.7.12 ~ X Protocol, X DevAPI, MySQL Shell
  45. 45. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL 5.7.12 ~ コネクター, ドライバー, プロトコル MySQL Plugins X Protocol Plugin Memcached Plugin Core MySQL Connectors and Drivers X ProtocolStd Protocol Memcached driver X Protocol 33060 Std Protocol 3306 SQL API CRUD and SQL APIs Memcache Protocol X and Std Protocols MySQL Shell 45
  46. 46. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. X Protocol • 非同期APIサポート – 並列処理とバッチ処理をサポート – パイプライン方式 – 複数リクエストを送信, ラウンドトリップを削減 – CRUD ==大量に小さなPKを処理, 独立した複数のクエリーを処理 • ミドルウエアとの親和性 – ルーティング、シャーディング、読み取り書き込みスプリッティング (XSESSION) • オープンスタンダードの利用: TLS (Transport Layer Security), SASL(Simple Authentication and Security Layer), Protobuf (Protocol Buffers)等 詳細: http://mysqlserverteam.com/mysql-5-7-12-part-2-improving-the-mysql-protocol/ +-------------+----------------+--------------------+ | PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_DESCRIPTION | +-------------+----------------+--------------------+ | mysqlx | 1.0 | X Plugin for MySQL | +-------------+----------------+--------------------+ The X Protocol focuses on: • extensibility • performance • security INSTALL PLUGIN mysqlx SONAME 'mysqlx.so'; 46
  47. 47. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. X DevAPI • X Pluginを有効にする事で、X Protocol経由で通信可能 • ドキュメントとテーブルのコレクションに対してのCRUD処理 • NoSQLライクな構文でドキュメントに対しCRUD処理可能 • Fluent API prod = sess.getSchema("prod") res = prod.users. find("$.name = 'Milk'"). fields(["name", "properties"]) X Plugin (MySQL) ⇔ X Protocol ⇔ X DevAPI (Driver) 47  MySQL Connector/node.js (1.0.x)  MySQL Connector/J (6.0.x)  MySQL Connector/Net (7.0.x)  MySQL Connector/python(2.2.x)  MySQL Shell (1.0.x) 参照: http://dev.mysql.com/downloads/connector/
  48. 48. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL Connectors include X Dev API • Use SQL, CRUD APIs スキーマレスドキュメントおよびリレーショナルテーブルに対応 - Classic APIsに加えて、これらの全てが追加されます 48 Operation Document Relational Create Collection.add() Table.insert() Read Collection.find() Table.select() Update Collection.modify() Table.update() Delete Collection.remove() Table.delete() 参照) http://dev.mysql.com/doc/x-devapi-userguide/en/crud-operations-overview.html
  49. 49. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 49 [root@misc01 nodejs]# cat sample_node_X_API.js const mysqlx = require('mysqlx'); mysqlx.getSession({ host: 'localhost', port: 33060, dbUser: 'demo_user', dbPassword: 'password' }).then(function (session) { return session.createSchema("test_schema").then(function (schema) { return schema.createCollection("myCollection"); }).then(function (collection) { return Promise.all([ collection.add( {baz: { foo: "bar"}},{foo: { bar: "baz"}}).execute(), collection.find("$.baz.foo == 'bar'").execute(function (row) {console.log("Row: %j", row); }).then(function (res) {console.log("Collection find done!");}), collection.remove("($.foo.bar) == 'baz'").execute().then(function () { console.log("Document deleted");}), collection.drop() ]); }).then(function () { return session.dropSchema("test_schema"); }).then(function () { return session.close(); }); }).catch(function (err) { console.log(err.stack); process.exit(); }); [root@misc01 nodejs]# node sample_node_X_API.js Row: {"_id":"630f0d3b-f6fd-1d99-6d80-a8e90352","baz":{"foo":"bar"}} Collection find done! Document deleted Connector:mysql-connector-nodejs-1.0.5.tar.gz
  50. 50. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 50 2016-05-06T15:15:05.364983+09:00 37 Query /* xplugin authentication */ SELECT `authentication_string`, <SNIP> 2016-05-06T15:15:05.369200+09:00 37 Query CREATE DATABASE `test_schema` 2016-05-06T15:15:05.382450+09:00 37 Query CREATE TABLE `test_schema`.`myCollection` (doc JSON,_id VARCHAR(32) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(doc, '$._id'))) STORED NOT NULL UNIQUE) CHARSET utf8mb4 ENGINE=InnoDB 2016-05-06T15:15:05.464364+09:00 37 Query INSERT INTO `test_schema`.`myCollection` (doc) VALUES ('{¥"baz¥":{¥"foo¥":¥"bar¥"},¥"_id¥":¥"c5d6964d-af2a-0b87-36aa- 4f5bc18b¥"}'),('{¥"foo¥":{¥"bar¥":¥"baz¥"},¥"_id¥":¥"3f106b27-e14a-31e0-5297-51da7f1c¥"}') 2016-05-06T15:15:05.481912+09:00 37 Query SELECT doc FROM `test_schema`.`myCollection` WHERE (JSON_EXTRACT(doc,'$.baz.foo') = 'bar') 2016-05-06T15:15:05.528923+09:00 37 Query DELETE FROM `test_schema`.`myCollection` WHERE (JSON_EXTRACT(doc,'$.foo.bar') = 'baz') 2016-05-06T15:15:05.551710+09:00 37 Query DROP TABLE `test_schema`.`myCollection` 2016-05-06T15:15:05.565824+09:00 37 Query DROP DATABASE `test_schema` 2016-05-06T15:15:05.643891+09:00 37 Quit General Log
  51. 51. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. MySQL Shell • 開発および管理用のシェルの統合 • 一般的なスクリプト・インターフェースを介して 利用可能な MySQLコマンドラインクライアント。 • PythonやJavaScriptなどのスクリプト言語で さまざまな製品と対話するための完全な開発用API 51 [root@misc01 admin]# mysqlsh --help | egrep -i "Start in" --sql Start in SQL mode using a node session. --sqlc Start in SQL mode using a classic session. --js Start in JavaScript mode. --py Start in Python mode. [root@misc01 admin]#  バッチ処理に利用可能 shell> mysqlsh --file code.js shell> mysqlsh < code.js shell> echo "show databases" | mysqlsh –sql  2017年4月12日: MySQL Shell 1.0.9 GA
  52. 52. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 52 [root@misc01 MID2016]# mysqlsh --uri demo_user@localhost/NEW57 -ppassword Creating an X Session to demo_user@localhost:33060/NEW57 Default schema `NEW57` accessible through db. Welcome to MySQL Shell 1.0.3 Development Preview ……. Currently in JavaScript mode. Use ¥sql to switch to SQL mode and execute queries. mysql-js> db.createCollection("x_posts"); <Collection:x_posts> mysql-js> db.x_posts.add({"title":"Hello World", "text":"This is the first post via mysqlx"}); Query OK, 1 item affected (0.01 sec) mysql-js> db.x_posts.find("title = 'Hello World'").sort(["title"]); [ { "_id": "baee9a744308e61168170800279cea3c", "text": "This is the first post via mysqlx", "title": "Hello World" } ] 1 document in set (0.00 sec) MySQL Shell Version 1.0.5 Development Preview session.getSchema(‘NEW57')
  53. 53. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 2016-05-26T23:24:45.694581+09:00 11 Query /* xplugin authentication */ SELECT `authentication_string`, <SNIP> 2016-05-26T23:24:45.695786+09:00 11 Query show databases 2016-05-26T23:24:45.697994+09:00 11 Query select schema(), @@lower_case_table_names 2016-05-26T23:24:45.698455+09:00 11 Query select connection_id() 2016-05-26T23:24:45.698899+09:00 11 Query use `NEW57` 2016-05-26T23:24:45.699441+09:00 11 Query SELECT table_name, COUNT(table_name) c FROM information_schema.columns WHERE ((column_name = 'doc' and data_type = 'json') OR (column_name = '_id' and generation_expression = 'json_unquote(json_extract(`doc`,''$._id''))')) AND table_schema = 'NEW57' GROUP BY table_name HAVING c = 2 2016-05-26T23:24:45.701333+09:00 11 Query SHOW FULL TABLES FROM `NEW57` 2016-05-26T23:24:45.703443+09:00 11 Query SELECT table_name, COUNT(table_name) c FROM information_schema.columns WHERE ((column_name = 'doc' and data_type = 'json') OR (column_name = '_id' and generation_expression = 'json_unquote(json_extract(`doc`,''$._id''))')) AND table_schema = 'NEW57' GROUP BY table_name HAVING c = 2 2016-05-26T23:24:45.706091+09:00 11 Query SHOW FULL TABLES FROM `NEW57` 2016-05-26T23:25:15.862883+09:00 11 Query CREATE TABLE `NEW57`.`x_posts` (doc JSON,_id VARCHAR(32) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(doc, '$._id'))) STORED NOT NULL UNIQUE) CHARSET utf8mb4 ENGINE=InnoDB 2016-05-26T23:25:38.026317+09:00 11 Query INSERT INTO `NEW57`.`x_posts` (doc) VALUES ('{¥"_id¥":¥"de3e8cb74d23e6112c1d0800279cea3c¥",¥"text¥":¥"This is the first post via mysqlx¥",¥"title¥":¥"Hello World¥"}') 2016-05-26T23:25:57.011923+09:00 11 Query SELECT doc FROM `NEW57`.`x_posts` WHERE (JSON_EXTRACT(doc,'$.title') = 'Hello World') ORDER BY JSON_EXTRACT(doc,'$.title') 53 General Log
  54. 54. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. root@localhost [NEW57]> SELECT table_name, COUNT(table_name) c FROM information_schema.columns WHERE ((column_name = 'doc' and data_type = 'json') OR (column_name = '_id' and generation_expression = 'json_unquote(json_extract(`doc`,''$._id''))')) AND table_schema = 'NEW57' GROUP BY table_name HAVING c = 2; +------------------------+---+ | table_name | c | +------------------------+---+ | Innovation_Day | 2 | | Innovation_Day_Confirm | 2 | | X_JSON | 2 | | x_posts | 2 | | X_PYTHON | 2 | +------------------------+---+ テーブル構造(doc json列+generated columnのPK(_id) から、通常のテーブルとドキュメントストアを判別 mysql-js> db.getCollections() { "Innovation_Day": <Collection:Innovation_Day>, "Innovation_Day_Confirm": <Collection:Innovation_Day_Confirm>, "X_JSON": <Collection:X_JSON>, "X_PYTHON": <Collection:X_PYTHON>, "x_posts": <Collection:x_posts> } mysql-js> db.getTables() { "T_GIS": <Table:T_GIS>, "T_JSON_DOC": <Table:T_JSON_DOC>, "T_JSON_DOC_TXT": <Table:T_JSON_DOC_TXT>, "T_TDE": <Table:T_TDE>, "citylots": <Table:citylots>, "employees": <Table:employees>, "employees_json": <Table:employees_json>, "employees_txt": <Table:employees_txt>, 54
  55. 55. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 55 備考 その他、MySQL参考情報
  56. 56. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 56 MySQL Cluster 7.5: JSONをサポート JSONデータ型、JSON関数、生成列を利用したJSONデータへのインデックスをサポート NDBテーブルごとに最大3つのJSONカラムをサポートしています。 mysql> select @@version; +----------------------------------+ | @@version | +----------------------------------+ | 5.7.13-ndb-7.5.3-cluster-gpl-log | +----------------------------------+ mysql> show create table JSON75¥G *************************** 1. row *************************** Table: JSON75 Create Table: CREATE TABLE JSON75 ( user_id varchar(32) GENERATED ALWAYS AS (json_unquote(json_extract(`doc`,'$.user_id'))) STORED NOT NULL, doc json DEFAULT NULL, last_update timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`user_id`) ) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 mysql> select * from JSON75 where user_id = 1; +---------+-----------------------------------------+---------------------+ | user_id | doc | last_update | +---------+-----------------------------------------+---------------------+ | 1 | {“name”: “ユーザーA”, “user_id”: 1} | 2016-09-30 21:45:47 | +---------+-----------------------------------------+---------------------+
  57. 57. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 57 RESTJPA 例) MySQL Cluster 7.5で大量のJSONデータ処理 MySQL Cluster Data Nodes {“name”: “ユーザーA”, “user_id”: 1} {“name”: “ユーザーB”, “user_id”: 2}
  58. 58. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 58 参考: 13.16 JSON Functions 13.16.1 JSON Function Reference 13.16.2 Functions That Create JSON Values 13.16.3 Functions That Search JSON Values 13.16.4 Functions That Modify JSON Values 13.16.5 Functions That Return JSON Value Attributes 13.16.6 JSON Path Syntax Modifying JSON Values in MySQL 5.7 https://planet.mysql.com/entry/?id=5994648
  59. 59. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 59 有難うございました
  60. 60. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. 60

×