RoOUG 2022 - Relational and JSON - Niall McPhillips
RoOUG 2022 - Relational and JSON - Niall McPhillips
RoOUG
ConTech 2022
Bucharest, Romania
by
Niall Mc Phillips - Long Acre sàrl
[email protected]
@Niall_McP
1
10/11/22
2
10/11/22
• Oracle ACE
• Using Oracle database as a Developer and DBA for >30 years
• Developing web applications with Oracle DB since 1995
• Developing with APEX since 2005
• Organizer of the Swiss APEX Meetup group
@NiallMcP
[email protected]
Nominate
yourself or someone you know:
ace.oracle.com/nominate
For more details on Oracle ACE Program:
ace.oracle.com
3
10/11/22
4
10/11/22
Relational - Normalisation
Let's start with a list of data representing short-term apartment rentals
Apartments
Address Description Landlord Landlord Landlord Currency Price / Amenities
phone e-mail week
21 Rue du Saut blah, blah D. Jepp 022 678 d.jepp@ap CHF 980 Wifi
4322 t.ch Kitchen
Balcony
62 Rue du Pirate blah, blah D. Jepp 022 678 d.jepp@ap CHF 1480 Wifi
4322 t.ch Kitchen
Garden
42 Rue des blah, blah M. Curphy 01 78 43 m.curphy CHF 520 Wifi
Caraïbes 22 56 @xyz.ch Kitchenette
Apartments
Address Description Landlord Landlord Landlord Currency Price / Amenities
phone e-mail week
21 Rue du Saut blah, blah D. Jepp 022 678 d.jepp@ap CHF 980 Wifi,
4322 t.ch Kitchen,
Balcony
62 Rue du Pirate blah, blah D. Jepp 022 678 d.jepp@ap CHF 1480 Wifi,
4322 t.ch Kitchen,
Garden
42 Rue des blah, blah M. Curphy 01 78 43 m.curphy CHF 520 Wifi
Caraïbes 22 56 @xyz.ch
10
5
10/11/22
Apartments
Address Descriptio Landlord Landlord Landlord Currency Price /
n phone e-mail week
Address Amenity
21 Rue du Saut blah, blah D. Jepp 022 678 d.jepp@a CHF 980
4322 pt.ch 21 Rue du Saut Wifi
62 Rue du Pirate blah, blah D. Jepp 022 678 d.jepp@a 21 Rue du1480
CHF Saut Kitchen
4322 pt.ch
21 Rue du Saut Balcony
42 Rue des blah, blah M. Curphy 01 78 43 m.curphy CHF 520
62 Rue du Pirate Wifi
Caraïbes 22 56 @xyz.ch
62 Rue du Pirate Kitchen
62 Rue du Pirate Garden
42 Rue des Caraïbes Wifi
11
Apartments
ID Address Descript Landlor Landlor Landlor Currenc Price /
ion d d phone d e-mail y week
ID Address Amenit
1 21 Rue du blah, D. Jepp 022 678 d.jepp@ CHF 980 y
Saut blah 4322 apt.ch
1 21 Rue du Wifi
2 62 Rue du blah, D. Jepp 022 678 d.jepp@ CHF 1480Saut
Pirate blah 4322 apt.ch
2 21 Rue du Kitche
3 42 Rue des blah, M. 01 78 m.curph CHF 520 Saut n
Caraïbes blah Curphy 43 22 y@xyz.
56 ch 3 21 Rue du Balcon
Saut y
4 62 Rue du Wifi
Pirate
5 62 Rue du Kitche
Pirate n
6 62 Rue du Garde
Pirate n
12 7 42 Rue des Wifi
Caraïbes
6
10/11/22
Relational – Normalisation
We could now construct SQL statements joining tables to
answer questions such as :
• Which apartments have kitchens and how much are they?
• Which apartments are operated by D. Jepp and what are
their amenities?
• etc.
14
7
10/11/22
15
16
8
10/11/22
JSON
• Dates from the early-2000's by Douglas Crockford
17
JSON
• Dates from the early-2000's by Douglas Crockford
• First standardized in 2013 (ECMA-404)
18
9
10/11/22
JSON
• Dates from the early-2000's by Douglas Crockford
• First standardized in 2013 (ECMA-404)
• 2017 – ISO/IEC standard (ISO/IEC 21778:2017)
19
JSON
• Dates from the early-2000's by Douglas Crockford
• First standardized in 2013 (ECMA-404)
• 2017 – ISO/IEC standard (ISO/IEC 21778:2017)
• Independent of underlying technologies
20
10
10/11/22
JSON
• Dates from the early-2000's by Douglas Crockford
• First standardized in 2013 (ECMA-404)
• 2017 – ISO/IEC standard (ISO/IEC 21778:2017)
• Independent of underlying technologies
• Wide adoption in the development community
21
JSON
22
11
10/11/22
23
JSON
«Great - But…»
let's look at this in a different way
24
12
10/11/22
{"id":"1", "weeklyPrice":"1480",
"Balcony"] }
},
25
Adding reviews
Let's add reviews from people that have stayed in the
apartments
• Reviewer ID
• Reviewer Name
• Stars Given
• Review Text
26
13
10/11/22
27
14
10/11/22
29
30
15
10/11/22
31
32
16
10/11/22
33
34
17
10/11/22
More recently
“Let's write the applications,
we'll structure the data as we evolve”
35
Culture Clash?
“Never consider the application
when modelling the data
- let the data speak for itself”
vs.
“Let's write the application,
we'll structure the data as we evolve”
36
18
10/11/22
Culture Clash?
37
PLUS
38
19
10/11/22
39
40
20
10/11/22
Inserting JSON
insert into apartments values
(4, '78 Rue de l''Avenir',
'{"reviews":
[{"name": "James Plunkett",
"stars": 5,
"text": "Great apartment!" },
{"name": "James Connolly",
"stars": 4,
"text": "Nice Apartment, but..."}
]
}');
41
json_object('reviews'
value json_arrayagg(
json_object(key 'name' is d.name,
key 'stars' is d.stars,
key 'text' is d.text)
returning clob)
returning clob)
from (select 'Ard Rí' as name, 5 as stars, 'Enjoyable stay' as text from dual
union
select 'Ard Banríon', 5, 'Good enough for me' from dual) d
42
21
10/11/22
Demo time!
43
Querying JSON –
Dot notation
select a.apt_id,
a.address,
a.recent_reviews.reviews[0].name,
a.recent_reviews.reviews[0].name.string(),
a.recent_reviews.reviews[1].name,
a.recent_reviews.reviews[1].name.string()
from apartments a;
44
22
10/11/22
Querying JSON –
All array elements as a JSON array
select a.apt_id,
a.address,
a.recent_reviews.reviews[*].name as reviewers
from apartments a;
45
Querying JSON –
Using JSON_TABLE to return multiple rows
select a.apt_id, a.address,
j.name as reviewer,
j.stars, j.text as review
FROM apartments a,
json_table(a.recent_reviews, '$.reviews[*]'
columns (name varchar2(30) path '$.name',
stars number path '$.stars',
text varchar2(50) path '$.text')) j;
46
23
10/11/22
Querying JSON –
Creating a view on the JSON values
create or replace view vw_apartment_reviews as
select a.apt_id, a.address,
j.name as reviewer,
j.stars, j.text as review
FROM apartments a,
json_table(a.recent_reviews, '$.reviews[*]'
columns (name varchar2(30) path '$.name',
stars number path '$.stars',
text varchar2(50) path '$.text')) j;
47
48
24
10/11/22
49
50
25
10/11/22
51
Indexing JSON
See Search indexes for JSON – Roger Ford, Oracle - 23rd Nov 2021
52
26
10/11/22
then
select * from apartments a
where a.recent_reviews.latestStay.string() = '2022-09-30';
53
then...
select a.* from apartments a
where json_exists(a.recent_reviews,
'$.reviews?(@.name == "James Plunkett")');
54
27
10/11/22
then...
select a.* from apartments a where
json_textcontains(a.recent_reviews,
'$.reviews.name’,
'james');
55
56
28
10/11/22
57
58
29
10/11/22
59
PL/SQL - APEX_JSON
There is a DB package called APEX_JSON that can be used
for parsing and generating JSON – available since APEX 5.0
apex_json.open_object();
apex_json.write('latestStay','2022-10-06’);
apex_json.openArray('reviews’);
apex_json.open_object();
apex_json.write('name','RoOUG Reviewer');
apex_json.write('stars','5');
apex_json.write(‘text’,’Lovely place’);
apex_json.close_object();
apex_json.close_array();
apex_json.close_object();
60
30
10/11/22
JSON_OBJECT_T
JSON_ARRAY_T
61
For Speeds Sake, Stop Using APEX_JSON (Jon Dixon, 5th June 2022)
62
31
10/11/22
63
64
32
10/11/22
65
Any Questions ??
66
33