This post walks through a practical and very revealing example of how Oracle Database 26ai infers relational schemas and JSON Relational Duality Views from JSON documents — and how the behaviour changes significantly when you insert JSON using extended syntax.
- A JSON Collection Table
- DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMA
- The same JSON document, inserted in two different ways
demo@ORA26AI>
demo@ORA26AI> begin
2 :x := q'# {
3 "_id": {
4 "$oid": "68d84c709ef2358f438a1cea"
5 },
6 "firstName": "fullName-ro",
7 "type": "Prospect",
8 "fullName": "fullName-ro",
9 "birthDate": "1991-07-09",
10 "nickname": "nickname-ro"
11 } #';
12 end;
13* /
demo@ORA26AI> print x
-------------------------------------------
{
"_id": {
"$oid": "68d84c709ef2358f438a1cea"
},
"firstName": "fullName-ro",
"type": "Prospect",
"fullName": "fullName-ro",
"birthDate": "1991-07-09",
"nickname": "nickname-ro"
}
2 l_sql clob ;
3 l_inputs json;
4 begin
5 l_inputs := json(' {"tableNames" :["MY_DEMO"], "useFlexFields" : false, "updatability" : true }');
6 l_sql := dbms_json_duality.infer_and_generate_schema( l_inputs );
7
8 dbms_output.put_line('------------------ DDL Scripts ------------------------');
9 dbms_output.put_line(l_sql);
10 end;
11* /
------------------ DDL Scripts ------------------------
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE my_demo__id(
"$oid" varchar2(64) DEFAULT ON NULL SYS_GUID(),
PRIMARY KEY("$oid")
)';
type varchar2(64) DEFAULT ON NULL SYS_GUID(),
nickname varchar2(64) /* UNIQUE */,
full_name varchar2(64) /* UNIQUE */,
birth_date timestamp,
first_name varchar2(64) /* UNIQUE */,
"$oid_my_demo__id" varchar2(64),
PRIMARY KEY(type)
)';
ADD CONSTRAINT fk_my_demo_root_to_my_demo__id FOREIGN KEY ("$oid_my_demo__id") REFERENCES my_demo__id("$oid") DEFERRABLE';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS fk_my_demo_root_to_my_demo__id_index ON my_demo_root("$oid_my_demo__id")';
my_demo_root @insert @update @delete
{
_id: my_demo__id @insert @update @object
{
"$oid"
}
type
fullName: full_name
nickname
birthDate: birth_date
firstName: first_name
}';
END;
- $oid becomes a column
- A surrogate primary key is
created
- Business attributes live here
- A foreign key references the ID table
└── "$oid" (PK)
├── type (PK)
├── first_name
├── full_name
├── nickname
├── birth_date
└── "$oid_my_demo__id" (FK)
The inferred duality view explicitly models _id as a nested object:
{
"$oid"
}
- _id is treated as application data
- Oracle normalizes it into a separate relational table
- Referential integrity is inferred automatically
2 l_sql clob ;
3 l_inputs json;
4 begin
5 l_inputs := json(' {"tableNames" :["MY_DEMO"], "useFlexFields" : false, "updatability" : true }');
6 l_sql := dbms_json_duality.infer_and_generate_schema( l_inputs );
7
8 dbms_output.put_line('------------------ DDL Scripts ------------------------');
9 dbms_output.put_line(l_sql);
10 end;
11* /
------------------ DDL Scripts ------------------------
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE my_demo_root(
"_id" raw(64) DEFAULT ON NULL SYS_GUID(),
type varchar2(64) /* UNIQUE */,
nickname varchar2(64) /* UNIQUE */,
full_name varchar2(64) /* UNIQUE */,
birth_date timestamp,
first_name varchar2(64) /* UNIQUE */,
PRIMARY KEY("_id")
)';
my_demo_root @insert @update @delete
{
"_id" @cast(as: id)
fullName: full_name
nickname
birthDate: birth_date
firstName: first_name
}';
END;
- _id is recognized as a document identifier
- $oid is no longer treated as user data
├── _id (RAW, PK)
├── type
├── first_name
├── full_name
├── nickname
└── birth_date
- Physical schema design
- Key modeling
- Join complexity
- Duality view shape
- Document identity
- Application-level attributes
No comments:
Post a Comment