JSONデータ型は、データベース内でJSON(JavaScript Object Notation)データを格納および処理するための特殊なデータ型です。JSON値は、オブジェクト(JSONオブジェクト)、配列、文字列、数値、ブール値(false/true)、または null で構成されている必要があります。ここで、false、true、null は小文字のみを許可します。
JSONテキスト構造
JSONテキスト構造には、文字、文字列、数値、および3つのリテラル名が含まれます。任意の構造文字の前後には、スペース、水平タブ、改行、キャリッジリターンなど、さまざまな区切り文字を使用できます。
配列開始 = [ 左角カッコ
オブジェクト開始 = { 左中括弧
配列終了 = ] 右角カッコ
オブジェクト終了 = } 右中括弧
名前区切り文字 = : コロン
値区切り文字 = , カンマ
オブジェクト
オブジェクトの構造は、0個以上の名前/値ペア(またはメンバー)を含む一対の大括弧で表されます。オブジェクト内の名前は一意である必要があります。名前は文字列であり、各名前の後にはコロンが続き、名前と値を区切ります。複数の名前/値ペアを区切る場合は、単一のカンマを使用します。
例:
{ "NAME": "SAM", "Height": 175, "Weight": 100,"Registered" : false}
配列
配列の構造は、0個以上の値(要素とも呼ばれる)を含む一方括弧で表されます。配列の要素はカンマで区切られ、配列内の値がすべて同じである必要はありません。
例:
["abc", 10, null, true, false]
数字
数字は10進数形式で表され、整数部を含みます。オプションですが、マイナス記号(-)を接頭辞として使用することができ、その後に分数部と/または指数部を続けることができます。先導ゼロは許可されません。小数部は小数点の後に1文字以上の数字が続きます。指数部は大文字または小文字の E で始まり、その後にプラス記号(+)またはマイナス記号(-)を続けることができます。E とオプションの記号の後には、1文字以上の数字を続けることができます。
例:
[100, 0, -100, 100.11, -12.11, 10.22e2, -10.22e2]
文字列
文字列は、開始と終了の両方で引用符(")を使用します。すべてのUnicode文字を引用符内に配置できますが、エスケープが必要な文字(引用符、バックスラッシュ、制御文字を含む)は除きます。
JSONテキストは、UTF-8、UTF-16、またはUTF-32でエンコードする必要があります。デフォルトのエンコードはUTF-8です。
例:
{"Url": "http://www.example.com/image/481989943"}
JSON値の作成
OceanBaseデータベースは、JSON型に対して以下のDDL操作をサポートしています:
JSON列を持つテーブルの作成。
JSON列の追加/削除。
生成列を基にJSON型の列にインデックスを作成します。
使用制限
ユーザーは各テーブルに複数のJSON型列を作成できますが、以下の制限があります:
JSON型列は
PRIMARY KEY、FOREIGN KEY、UNIQUE KEYとしては使用できませんが、NOT NULLまたはCHECK制約を追加することはできます。JSON型列にデフォルト値を設定することはできません。
JSON型列はパーティションキーとしては使用できません。
JSONデータの長さは
LONGTEXTの長さを超えてはならず、各JSONオブジェクトまたは配列の最大深さは99です。
型変換
JSONデータ型とTEXT、MEDIUMTEXT、LONGTEXT型との相互変換をサポートします。
例
例1:基本的なDDL操作
obclient> CREATE TABLE tbl1 (id INT PRIMARY KEY, docs JSON NOT NULL, docs1 JSON);
Query OK, 0 rows affected
obclient> ALTER TABLE tbl1 MODIFY docs JSON CHECK(docs <'{"a" : 100}');
Query OK, 0 rows affected
obclient> CREATE TABLE json_tab(
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '主キー',
json_info JSON COMMENT 'JSONデータ',
json_id INT GENERATED ALWAYS AS (json_info -> '$.id') COMMENT 'JSONデータの仮想フィールド',
json_name VARCHAR(5) GENERATED ALWAYS AS (json_info -> '$.NAME'),
index json_info_id_idx (json_id)
)COMMENT 'json サンプルテーブル';
Query OK, 0 rows affected
obclient> ALTER TABLE json_tab ADD COLUMN json_info1 JSON;
Query OK, 0 rows affected
obclient> ALTER TABLE json_tab ADD INDEX (json_name);
Query OK, 0 rows affected
obclient> ALTER TABLE json_tab drop COLUMN json_info1;
Query OK, 0 rows affected
例2:生成列をキーとして使用してインデックスを作成する
obclient> CREATE TABLE jn ( c JSON, g INT GENERATED ALWAYS AS (c->"$.id"));
Query OK, 0 rows affected
obclient> CREATE INDEX idx1 ON jn(g);
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
obclient> INSERT INTO jn (c) VALUES
('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'),
('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}');
Query OK, 4 rows affected
Records: 4 Duplicates: 0 Warnings: 0
obclient> SELECT c->>"$.name" AS name FROM jn WHERE g <= 2;
+-------+
| name |
+-------+
| Fred |
| Wilma |
+-------+
2 rows in set
obclient> EXPLAIN SELECT c->>"$.name" AS name FROM jn WHERE g <= 2\G
*************************** 1. row ***************************
Query Plan: =========================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-----------------------------------------
|0 |TABLE SCAN|jemp(idx1)|2 |92 |
=========================================
Outputs & filters:
-------------------------------------
0 - output([JSON_UNQUOTE(JSON_EXTRACT(jemp.c, '$.name'))]), filter(nil),
access([jemp.c]), partitions(p0)
1 row in set