Kantar AI Summit- Under Embargo till Wednesday, 24th April 2024, 4 PM, IST.pdf
Store non-structured data in JSON column types and enhancements of JSON
1. Store non-structured data in JSON column types and
enhancements of JSON in new versions of Oracle
JSON data type is one of the important and essential features that is available in Oracle.
Without Json support, any databases have a challenge for compatibility and exchange data ,
migration data with other and new systems such as bigdata, data science, developers usage, ...
JSON (JavaScript Object Notation) is a lightweight format that is used for data
interchanging. It is based on a subset of JavaScript language (the way objects are built in
JavaScript). As stated in the MDN, some JavaScript is not JSON, and some JSON is not
JavaScript.
An example of where this is used is web services responses. In the 'old' days, web services used
XML as their primary data format for transmitting back data, but since JSON appeared (The JSON
format is speci
fi
ed in RFC 4627 by Douglas Crockford), it has been the preferred format because it
is much more lightweight
JSON is built on two structures:
• A collection of name/value pairs. In various languages, this is realized as an object, record,
struct, dictionary, hash table, keyed list, or associative array.
• An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
Oracle Database support for JavaScript Object Notation (JSON) is designed to provide the best
fi
t
between the worlds of relational storage and querying JSON data, allowing relational and JSON
queries to work well together. Oracle SQL/JSON support is closely aligned with the JSON support
in the SQL Standard.
In a relational database, it’s best to store data according to the principles of the relational model.
However, it might be that you also need to store non-structured data, in which case, a JSON
column can help you deal with such a requirement.
JSON data features is going on to improve in new versions and
fi
nally in 23c, Oracle achieved
very new and amazing features on the JSON.
The Proble
Prior to Oracle 21c, all JSON data was stored in the database as text, typically in columns with
data types such as BLOB, CLOB or VARCHAR2. With the introduction of the JSON data type in
Oracle 21c, people may wish to convert their text-based JSON columns to use the JSON data
type. There are several methods to do this, including the following.
• CREATE TABLE ... AS SELECT (CTAS)
• Data Pump
• Online Table Rede
fi
nition
• Add the new column and perform a DML update
In all cases we don't know if the data in the column is suitable for such a conversion until we
attempt it.
2. The Solution :
DBMS_JSON.JSON_TYPE_CONVERTIBLE_CHECK
In Oracle 23c the JSON_TYPE_CONVERTIBLE_CHECK procedure has been added to the
DBMS_JSON package.
This procedure allows us to perform a pre-migration check on the contents of the text-based
JSON column, to make sure it is suitable for conversion to a JSON data type column.
I run the JSON_TYPE_CONVERTIBLE_CHECK procedure, passing in the column of interest, and a
status table name. This table will be created.
create table json_data (
id number generated always as identity,
data clob
);
We populate it with three rows that are suitable for conversion to a JSON data type column.
insert into json_data (data)
values (null);
insert into json_data (data)
values ('{}');
insert into json_data (data)
values ('{"product":"banana", "quantity":10}');
commit;
begin
dbms_json.json_type_convertible_check(
owner => 'testuser1',
tablename => 'json_data',
columnname => 'data',
statustablename => 'json_data_precheck'
);
end;
/
select status from json_data_precheck;
Result: Process completed (Errors found: 0)
SQL>
If status contains any error we must resolve it and error means column contents is incomplete
with json type.
Migrate the Data to a JSON Column
We can now move forward and convert the data using one of the valid methods.
-- Add a JSON column,
alter table json_data add (
data2 json
);
-- Populate the new column.
update json_data
set data2 = JSON(data);
-- Drop the old column. You may prefer to mark it as unused.
3. alter table json_data drop column data;
-- Rename the new column to match the original name.
alter table json_data rename column data2 to data;
In Oracle 21c we can add a JSON column type:
CREATE TABLE book (
id NUMBER(19, 0) NOT NULL PRIMARY KEY,
isbn VARCHAR2(15 CHAR),
properties JSON);
If you’re using Oracle 12c, 18c, 19c you can store JSON objects in VARCHAR2, BLOB, or CLOB
column types.
It’s recommended to store small JSON objects so they can
fi
t in a VARCHAR2(4000) column and,
therefore,
fi
t into the Bu
ff
er Pool page.
When you create the table, you can validate the stored JSON objects using a CHECK constraint:
CREATE TABLE book (
id NUMBER(19, 0) NOT NULL PRIMARY KEY,
isbn VARCHAR2(15 CHAR),
properties VARCHAR2(4000)
CONSTRAINT ENSURE_JSON CHECK (properties IS JSON));
To index JSON attributes that have high selectivity, you can use a B+Tree index:
CREATE INDEX book_properties_title_idx
ON book (properties.title);
To index JSON attributes that have low selectivity, such as boolean or Enum values, you can use
a BITMAP index:
CREATE BITMAP INDEX book_properties_reviews_idx
ON book (JSON_EXISTS(properties,'$.reviews'));
Because a bitmap index record references many rows of the associated indexed table, concurrent
UPDATE or DELETE statements can lead to concurrency issues (e.g., deadlocks, lock timeouts,
high response times).
For this reason, they are useful for read-only columns or if the column values change very
infrequently.
You can also use a generic SEARCH index for the JSON column, which will allow you to match
key/value JSON attribute data:
CREATE SEARCH INDEX book_search_properties_idx
ON book (properties) FOR JSON;
When we insert json values may have some syntax error on inserting. In 23c this problem is
resolved by following:
4. VALIDATE Keyword With IS JSON Condition
We can use VALIDATE as part of an IS JSON condition. In the following example we recreate the
table, this time using the IS JSON condition as part of a check contraint.
drop table if exists t1 purge;
create table t1 (
id number,
json_data json,
constraint t1_pk primary key (id),
constraint json_data_chk check (json_data is json validate '{
"type" : "object",
"properties" : {"fruit" : {"type" : "string",
"minLength" : 1,
"maxLength" : 10},
"quantity" : {"type" : "number",
"minimum" : 0,
"maximum" : 100}},
"required" : ["fruit", "quantity"]
}')
);
We can also use the VALIDATE keyword with an IS JSON condition in a query.
Also we can use this feature when doing select :
select *
from t1
where json_data is json validate '{
"type" : "object",
"properties" : {"fruit" : {"type" : "string",
"minLength" : 1,
"maxLength" : 10},
"quantity" : {"type" : "number",
"minimum" : 0,
"maximum" : 100}},
"required" : ["fruit", "quantity"]
}';
Finaly above query only list standard and without syntax error records in result.
DBMS_JSON_SCHEMA.IS_SCHEMA_VALID
The IS_SCHEMA_VALID function in the DBMS_JSON_SCHEMA package can check the validity of
a JSON schema de
fi
nition. In the following example we call it with a valid JSON schema, then an
invalid one.
Sql>
select dbms_json_schema.is_schema_valid('{
"type" : "object",
"properties" : {"fruit" : {"type" : "string",
"minLength" : 1,
"maxLength" : 10},
"quantity" : {"type" : "number",
"minimum" : 0,
"maximum" : 100}},
"required" : ["fruit", "quantity"]
}') as is_valid;
IS_VALID