Skip to content

Commit eb7b8f0

Browse files
committed
Rollback to previous version
1 parent 828ec0b commit eb7b8f0

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

pages/blog/posts/oracle-case-study.md

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
title: "How Oracle is Bridging the Gap Between JSON Schema and Relational Databases"
3-
date: "2025-02-06"
3+
date: "2025-02-07"
44
tags:
55
- database
66
- relational
77
type: Case Study
8-
cover: /img/posts/2025/oracle-case-study/banner.webp
8+
cover: /img/posts/2025/oracle-case-study/blog_frontpage.webp
99
authors:
1010
- name: Loïc Lefèvre
1111
photo: /img/avatars/loiclefevre.webp
@@ -16,6 +16,8 @@ excerpt: "As modern multi-model databases increasingly support JSON, it's time t
1616

1717
As modern multi-model databases increasingly support JSON, it's time to explore what role [JSON schema](https://json-schema.org/) will play. In this post, we'll dive into the newly developed ["Database Vocabulary"](https://github.com/json-schema-org/vocab-database/blob/main/database.md), a proposed extension to the official JSON schema specification, developed by Oracle (with inputs from the MySQL and PostgreSQL teams). This vocabulary addresses key database tasks, including validation, type coercion/casting, and metadata preservation, making it easier to manage JSON in databases effectively and bridging the gap with existing relational data. Regardless of whether you are a JSON developer or a relational model developer, you'll learn something reading this post!
1818

19+
![JSON Schema with Oracle Database 23ai](/img/posts/2025/oracle-case-study/banner.webp)
20+
1921
Oracle Database 23ai fully implements this new vocabulary, and we'll describe not only the concepts but we'll also see real-world examples of JSON schema validation in action and how to describe database objects in JSON schema.
2022

2123
## JSON Data Guide
@@ -566,6 +568,7 @@ BEGIN
566568
'select getAnnotatedJSONSchema( ''PRODUCTS'' ) as schema');
567569

568570
COMMIT;
571+
569572
END;
570573
/
571574
```
@@ -593,13 +596,13 @@ With all this in place, our React frontend can now create the following form:
593596

594597
![React frontend with input form generated from an annotated Oracle Database 23ai JSON schema.](/img/posts/2025/oracle-case-study/form.webp)
595598

596-
<Infobox> Interestingly, whenever you change the schema annotation in the database, it is immediately reflected inside your browser once you refreshed it. You can try with:
597-
```sql
598-
ALTER TABLE products MODIFY name ANNOTATIONS (
599-
REPLACE "title" 'Product name'
600-
);
601-
```
602-
</Infobox>
599+
> Interestingly, whenever you change the schema annotation in the database, it is immediately reflected inside your browser once you refreshed it. You can try with:
600+
> ```sql
601+
> ALTER TABLE products MODIFY name ANNOTATIONS (
602+
> REPLACE "title" 'Product name'
603+
> );
604+
> ```
605+
>
603606
604607
605608
#### JSON Relational Duality View
@@ -720,7 +723,7 @@ Running the 2 queries above respectively returns the data in JSON format:
720723
|Wooden spatula|4.99|42|
721724
|Other nice product|5|10|
722725

723-
<Infobox>The `_metadata` object will contain additional information such as an `etag` that can be used for [optimistic concurrency control](https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/using-optimistic-concurrency-control-duality-views.html).</Infobox>
726+
> The `_metadata` object will contain additional information such as an `etag` that can be used for [optimistic concurrency control](https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/using-optimistic-concurrency-control-duality-views.html).
724727
725728
#### POST method
726729

@@ -742,7 +745,9 @@ BEGIN
742745
end;');
743746

744747
COMMIT;
748+
745749
END;
750+
746751
/
747752
```
748753

@@ -752,7 +757,7 @@ With 23ai, a check constraint can now be marked as [`PRECHECK`](https://docs.ora
752757

753758
Once a check constraint is marked as `PRECHECK`, you have the choice whether or not to disable the check constraint on the table as the retrieved JSON schema with `dbms_json_schema.describe()` will contain the check constraints as well.
754759

755-
<Danger>We do **NOT** advise to disable check constraints as it would allow inserting bad data into the relational tables directly. The remark about `PRECHECK` constraints is here to provide as much information as possible.</Danger>
760+
> We do **NOT** advise to disable check constraints as it would allow inserting bad data into the relational tables directly. The remark about `PRECHECK` constraints is here to provide as much information as possible.
756761
757762
```sql
758763
-- Mark check constraints as PRECHECK
@@ -1013,7 +1018,7 @@ select p.content.publishedDate.timestamp() + interval '5' day
10131018
from posts p;
10141019
```
10151020

1016-
<Infobox>We use the item method `timestamp()` in the last statement above because otherwise the SQL dot notation would return a SQL `JSON` (by default in 23ai) on which we cannot apply an interval operation. However, because the value is already stored as `TIMESTAMP` inside the binary JSON format, there will be *no conversion* from `JSON` to `timestamp` here.</Infobox>
1021+
> We use the item method `timestamp()` in the last statement above because otherwise the SQL dot notation would return a SQL `JSON` (by default in 23ai) on which we cannot apply an interval operation. However, because the value is already stored as `TIMESTAMP` inside the binary JSON format, there will be *no conversion* from `JSON` to `timestamp` here.
10171022
10181023
Last but not least, by enabling type casting, native SQL data type checks are also performed ensuring 100% fidelity between stored binary values in the encoded JSON and SQL data types. As a result, we can store not just the standard JSON data types but also the SQL data types inside the encoded binary JSON such as `NUMBER`, `DATE`, `TIMESTAMP`, `TIMESTAMP WITH TIME ZONE`, `INTERVAL`, `RAW`, `VECTOR`, etc.
10191024

@@ -1098,7 +1103,7 @@ Results:
10981103
| {<br/>&nbsp;&nbsp;"firstName": "Bob",<br/>&nbsp;&nbsp;"address": "Paris",<br/>&nbsp;&nbsp;"vat": false<br/>} |Paris|Bob|false|null|
10991104
| {<br/>&nbsp;&nbsp;"firstName": "Bob",<br/>&nbsp;&nbsp;"address": "Paris",<br/>&nbsp;&nbsp;"vat": false,<br/>&nbsp;&nbsp;"tableEvolve": true<br/>} |Paris|Bob|false|true|
11001105

1101-
<Infobox>The trigger executes asynchronously, hence not delaying DML response times, however, because of it being asynchronous, it may take a second before you will see the new virtual column.</Infobox>
1106+
> The trigger executes asynchronously, hence not delaying DML response times, however, because of it being asynchronous, it may take a second before you will see the new virtual column.
11021107
11031108
## Conclusion
11041109

0 commit comments

Comments
 (0)