MaxCompute mendukung tipe data JSON. Tipe data ini meningkatkan kinerja komputasi dan analisis data JSON dalam tabel. Topik ini menjelaskan cara menggunakan tipe data JSON.
Pengenalan tipe data JSON
Informasi Latar Belakang
Data semi-terstruktur berada di antara data terstruktur dan data tidak terstruktur. Jenis data ini memiliki skema, tetapi skemanya fleksibel dan tidak memiliki batasan yang ketat. Skema tersebut biasanya bersifat self-describing. Data JSON merupakan contoh khasnya. MaxCompute telah meningkatkan dukungan SQL untuk data semi-terstruktur dengan fitur-fitur seperti schema evolution, string JSON, fungsi bawaan untuk tipe kompleks, dan ekspresi Lambda. Dalam model ini, Anda harus memproses data semi-terstruktur secara terstandarisasi sebelum dapat mengimpornya ke dalam tabel terstruktur yang memiliki skema yang ditentukan. Jika data bisnis Anda berubah, Anda harus secara eksplisit menjalankan pernyataan Data Definition Language (DDL) schema evolution untuk memodifikasi skema tabel.
Model ini memiliki batasan skema yang kuat. Anda tidak dapat mengimpor data semi-terstruktur ke dalam sistem secara cepat. Selama impor data, data yang tidak sesuai dengan skema tabel akan dibuang dan tidak dapat disimpan sepenuhnya. Untuk mengatasi masalah ini, MaxCompute menyediakan tipe data baru: JSON. Tipe JSON mendukung data semi-terstruktur tanpa batasan skema yang ketat. Tipe ini juga memanfaatkan sepenuhnya optimisasi penyimpanan berbasis kolom untuk memenuhi kebutuhan fleksibilitas tinggi dan kinerja tinggi.
Prinsip Dasar
Tipe data JSON adalah tipe data baru yang dapat Anda gunakan seperti tipe lainnya. Anda tidak perlu mengelola informasi skema. Setelah Anda memasukkan data JSON, MaxCompute secara otomatis mengekstraksi skema publik dan melakukan optimisasi. MaxCompute menyimpan data dalam format berbasis kolom sedapat mungkin untuk meningkatkan kinerja. Contoh berikut menggunakan data uji:
CREATE TABLE json_table
(
json_val json
);
CREATE TABLE string_table
(
string_val STRING
);
INSERT INTO string_table VALUES
('{"a":1, "b":2}')
,('{"a":"key", "b":2}')
,('{"c":3}');
INSERT INTO json_table
SELECT json_parse(string_val)
FROM string_table;Saat Anda menulis data, MaxCompute secara otomatis mengekstraksi skema publik <"a":binary, "b":bigint, "c":bigint>. Saat Anda membaca data, MaxCompute dapat melakukan column pruning berdasarkan skema tersebut. Hal ini mengurangi jumlah data yang perlu dibaca dan meningkatkan efisiensi. Sebagai contoh:
SELECT json_val["b"]
,json_val["c"]
FROM json_table
;
-- Saat membaca tabel, column pruning dilakukan untuk hanya menyimpan variabel b dan c.
+-----+-----+
| _c0 | _c1 |
+-----+-----+
| 2 | NULL |
| 2 | NULL |
| NULL | 3 |
+-----+-----+Untuk bagian non-publik dari skema, MaxCompute menggunakan tipe BINARY untuk penyimpanan. Hal ini mengurangi ruang penyimpanan dibandingkan dengan tipe STRING. Tipe data JSON baru ini juga sangat meningkatkan efisiensi konversi antara STRING dan JSON dibandingkan dengan user-defined function (UDF).
Menggunakan tipe data JSON
Pada proyek MaxCompute baru, parameter
odps.sql.type.json.enablediatur ke true secara default.Pada proyek MaxCompute yang sudah ada, parameter
odps.sql.type.json.enablediatur ke false secara default.
Untuk menggunakan tipe data JSON pada proyek MaxCompute yang sudah ada, jalankan SET odps.sql.type.json.enable=true; untuk mengaktifkan fitur tersebut. Anda dapat menjalankan perintah setproject; untuk memeriksa nilai saat ini dari parameter odps.sql.type.json.enable.
Cakupan
Persyaratan Versi SDK
Hanya mendukung Java SDK V0.44.0 dan versi yang lebih baru.
Hanya mendukung PyODPS V0.11.4.1 dan versi yang lebih baru.
Batasan Operasi Tabel
Anda tidak dapat menambahkan kolom JSON ke dalam tabel.
Tabel clustered tidak didukung.
Tabel tipe Delta Table tidak didukung.
Batasan Operasi SQL
Operasi perbandingan pada tipe JSON tidak didukung.
Anda tidak dapat menggunakan klausa
ORDER BYatauGROUP BYpada tipe JSON. Anda juga tidak dapat menggunakan kolom tipe JSON sebagai kunciJOIN.
Presisi Data
Bagian integer dari JSON NUMBER disimpan sebagai tipe BIGINT. Terjadi overflow jika integer tersebut berada di luar rentang BIGINT.
Bagian desimal dari JSON NUMBER disimpan sebagai tipe DOUBLE. Kehilangan presisi dapat terjadi saat bagian desimal dikonversi ke tipe DOUBLE.
Batasan Karakter: Karakter Unicode
\u0000tidak didukung dalam string yang digunakan untuk menghasilkan data JSON.Kompatibilitas Engine: Jika Anda menggunakan engine lain, seperti Hologres, untuk membaca data dari tabel, tipe data JSON tidak dapat dibaca.
UDF Java dan UDF Python tidak mendukung tipe JSON.
Tipe data JSON dapat disarangkan hingga kedalaman 20 level.
Alat Pengembangan
Alat pengembangan yang didukung meliputi klien MaxCompute (odpscmd), MaxCompute Studio, dan DataWorks. Ekosistem eksternal seperti Dataphin tidak didukung. Jika Anda ingin menggunakan tipe data JSON dengan sistem eksternal, Anda harus memastikan kompatibilitasnya terlebih dahulu sebelum memulai. Saat menggunakan klien odpscmd, perhatikan hal-hal berikut:
Anda harus melakukan upgrade klien ke V0.46.5 atau versi yang lebih baru. Jika tidak, Anda tidak dapat menjalankan perintah
DESC json_tableatau mengunduh data JSON menggunakan Tunnel.Pada file
conf\odps_config.inidi path instalasi klien, atur parameteruse_instance_tunnelkefalse. Jika tidak, kueri akan gagal.
Konstanta Literal
Tipe JSON didefinisikan secara ketat sesuai standar JSON. Tipe ini mendukung BOOLEAN, NUMBER, STRING, NULL, ARRAY, dan OBJECT. Tipe NUMBER menggunakan BIGINT dan DOUBLE untuk penyimpanan. Nilai yang melebihi batas dapat mengalami kehilangan presisi. Perhatikan bahwa json 'null' berbeda dari sql null.
JSON 'null'
JSON '123'
JSON '123.34'
JSON 'true'
JSON '{"id":123,"name":"MaxCompute"}'
JSON '[12, 34]'Konstanta harus sesuai dengan standar JSON. Sebagai contoh, JSON '{id:123,"name":"MaxCompute"}' adalah string JSON yang tidak valid karena kunci id harus diapit tanda kutip ganda ("").
Definisi tipe JSON
Anda tidak perlu menentukan skema. Anda dapat membuat tipe JSON seperti halnya tipe data dasar.
CREATE TABLE mf_json_table (json_val JSON);Menghasilkan Data JSON
Anda dapat menghasilkan data JSON dengan beberapa cara:
Literal JSON
INSERT INTO mf_json_table VALUES (json '123');Fungsi JSON
-- JSON_OBJECT dan JSON_ARRAY adalah fungsi bawaan MaxCompute. INSERT INTO mf_json_table SELECT JSON_OBJECT("key",123, "value", "abc"); SELECT * FROM mf_json_table; -- Hasil berikut dikembalikan: +----------+ | json_val | +----------+ | 123 | | {"key":123,"value":"abc"} | +----------+ INSERT INTO mf_json_table SELECT JSON_ARRAY("key",234, "value", "abc"); SELECT * FROM mf_json_table; -- Hasil berikut dikembalikan: +----------+ | json_val | +----------+ | 123 | | ["key",234,"value","abc"] | | {"key":123,"value":"abc"} | +----------+Konversi Tipe
Perhatikan perbedaan antara mengonversi data menggunakan CAST dan mengurai data menggunakan json_parse. Untuk informasi selengkapnya, lihat fungsi JSON.
INSERT INTO mf_json_table SELECT CAST("abc" AS json); SELECT * FROM mf_json_table; -- Hasil berikut dikembalikan: +----------+ | json_val | +----------+ | 123 | | "abc" | | ["key",234,"value","abc"] | | {"key":123,"value":"abc"} | +----------+
Mengakses Data JSON
Anda dapat mengakses data JSON menggunakan pengindeksan, atau menggunakan fungsi json_extract dan get_json_object. Fungsi-fungsi ini mengembalikan tipe JSON.
Akses berdasarkan indeks
Akses berdasarkan indeks menggunakan mode strict. Ini mencakup akses berdasarkan nomor indeks dan nama bidang. Jika JSON Path tidak sesuai dengan struktur aktual, NULL dikembalikan.
json_val['a'][0][1] setara dengan json_extract(json_val, 'strict $.a[0][1]').
-- Mengembalikan 123
SELECT v['id']
FROM VALUES (JSON '{"id":123}') AS t(v);
-- Mengembalikan 12
SELECT v[0]
FROM VALUES (JSON '[12, 34]') AS t(v);
-- Mengembalikan 1
SELECT v['x']['a'] FROM VALUES (json '{"x": {"a": 1, "b": 2}}') AS t(v);
-- Mengembalikan NULL
SELECT v[0]
FROM VALUES (JSON '{"id":123}') AS t(v);
-- Mengembalikan NULL
SELECT v['not_exists']
FROM VALUES (JSON '{"id":123}') AS t(v);Akses menggunakan fungsi JSON
Sebagai contoh, Anda dapat mengakses data menggunakan fungsi JSON_EXTRACT atau GET_JSON_OBJECT.
-- Akses data menggunakan fungsi GET_JSON_OBJECT. Nilai STRING 'MaxCompute' dikembalikan.
SELECT GET_JSON_OBJECT(v, '$.x.name')
FROM VALUES (JSON '{"x": {"id": 1001, "name": "MaxCompute"}}') AS t(v);
-- Hasil berikut dikembalikan:
+-----+
| _c0 |
+-----+
| MaxCompute |
+-----+
-- Akses data menggunakan fungsi JSON_EXTRACT. Nilai JSON 'MaxCompute' dikembalikan.
SELECT JSON_EXTRACT(v, '$.x.name')
FROM VALUES (JSON '{"x": {"id": 1001, "name": "MaxCompute"}}') AS t(v);
-- Hasil berikut dikembalikan:
+-----+
| _c0 |
+-----+
| "MaxCompute" |
+-----+Tipe JSON baru menggunakan parser JSON Path yang lebih terstandarisasi. Parser ini berbeda dari parser yang digunakan oleh fungsi GET_JSON_OBJECT dan dapat menyebabkan masalah kompatibilitas. Kami menyarankan Anda menggunakan fungsi JSON_EXTRACT dalam pernyataan SQL baru.
Untuk informasi selengkapnya tentang fungsi JSON bawaan, lihat fungsi JSON.
Spesifikasi JSON Path
JSON Path menentukan lokasi suatu node dalam data JSON. JSON Path membantu Anda menemukan node dan mengambil data yang diinginkan. JSON Path sering digunakan sebagai parameter dalam fungsi JSON. Parser JSON Path yang digunakan untuk tipe JSON baru konsisten dengan parser PostgreSQL dan merupakan subset darinya. Contohnya ditunjukkan di bawah ini:
Data JSON:
{ "name": "Molly", "phones": [ { "phonetype": "work", "phone#": "650-506-7000" }, { "phonetype": "cell", "phone#": "650-555-5555" } ] }Contoh JSON Path: Hasil dari
$.phones[1]."phone#"adalah "650-555-5555".
Tabel berikut menjelaskan spesifikasi JSON Path berdasarkan data JSON di atas:
Variabel | Operator akses |
pengakses |
|
mode | Nilai opsionalnya adalah lax dan strict. Mode default-nya adalah lax.
Penting Mode lax tidak mendukung optimisasi column pruning. Mode strict mendukungnya. |
Contoh penggunaan tipe JSON
-- Jika parameter odps.sql.type.json.enable proyek Anda bernilai false, jalankan perintah berikut.
SET odps.sql.type.json.enable=true;
CREATE TABLE json_table(json_val json);
CREATE TABLE mf_string_table(string_val string);
INSERT INTO mf_string_table VALUES('{"a":1, "b":2}');
INSERT INTO json_table SELECT json_parse(string_val)
FROM mf_string_table
WHERE json_valid(string_val);
SELECT * FROM json_table WHERE json_val IS NOT NULL;
-- Hasil berikut dikembalikan:
+----------+
| json_val |
+----------+
| {"a":1,"b":2} |
+----------+
SELECT json_val['b'] FROM json_table WHERE json_val IS NOT NULL;
-- Hasil berikut dikembalikan:
+-----+
| _c0 |
+-----+
| 2 |
+-----+