Skip to content

Commit 0767737

Browse files
committed
Oracle case study with right blog style.
1 parent 3dda3c5 commit 0767737

File tree

1 file changed

+12
-17
lines changed

1 file changed

+12
-17
lines changed

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

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ tags:
55
- database
66
- relational
77
type: Case Study
8-
cover: /img/posts/2025/oracle-case-study/blog_frontpage.webp
8+
cover: /img/posts/2025/oracle-case-study/banner.webp
99
authors:
1010
- name: Loïc Lefèvre
1111
photo: /img/avatars/loiclefevre.webp
@@ -16,8 +16,6 @@ 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-
2119
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.
2220

2321
## JSON Data Guide
@@ -568,7 +566,6 @@ BEGIN
568566
'select getAnnotatedJSONSchema( ''PRODUCTS'' ) as schema');
569567

570568
COMMIT;
571-
572569
END;
573570
/
574571
```
@@ -596,13 +593,13 @@ With all this in place, our React frontend can now create the following form:
596593

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

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-
>
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>
606603

607604

608605
#### JSON Relational Duality View
@@ -723,7 +720,7 @@ Running the 2 queries above respectively returns the data in JSON format:
723720
|Wooden spatula|4.99|42|
724721
|Other nice product|5|10|
725722

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).
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>
727724

728725
#### POST method
729726

@@ -745,9 +742,7 @@ BEGIN
745742
end;');
746743

747744
COMMIT;
748-
749745
END;
750-
751746
/
752747
```
753748

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

758753
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.
759754

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.
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>
761756

762757
```sql
763758
-- Mark check constraints as PRECHECK
@@ -1018,7 +1013,7 @@ select p.content.publishedDate.timestamp() + interval '5' day
10181013
from posts p;
10191014
```
10201015

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.
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>
10221017

10231018
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.
10241019

@@ -1103,7 +1098,7 @@ Results:
11031098
| {<br/>&nbsp;&nbsp;"firstName": "Bob",<br/>&nbsp;&nbsp;"address": "Paris",<br/>&nbsp;&nbsp;"vat": false<br/>} |Paris|Bob|false|null|
11041099
| {<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|
11051100

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.
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>
11071102

11081103
## Conclusion
11091104

0 commit comments

Comments
 (0)