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です。
型変換
注意
この機能はV4.3.5 BP5バージョンからサポートされています。
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