Professional Documents
Culture Documents
Fixing The Worst DB in The World
Fixing The Worst DB in The World
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Photo by Ken Treloar on Unsplash
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Tables are the
of your database
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Get them wrong
and…
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
…you need to
be a SQL
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
with attrs as (
select pr.productno, attrs.*
from products pr,
json_table (
productinfo , '$' null on error
columns (
description path '$.description'
,colour path '$.colour'
,weight path '$.weight'
,height path '$.dimensions.height'
,width path '$.dimensions.width'
,depth path '$.dimensions.depth'
)
) attrs
union all
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
select productno, description, colour,
weight, height, width, depth
from (
select pr.productno, pa.attrname, pa.attrvalue from (
select productno from products
) pr
left join (
select productno, attrname, attrvalue
from product_attributes
) pa
on pr.productno = pa.productno
)
pivot (
min(attrvalue) for attrname in (
1 height, 2 depth, 3 width,
4 weight, 5 colour, 6 description
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
)
)
), product_details as (
select productno, min(description) descr,
min(colour) clr, min(weight) wt,
min(height) ht, min(width) wd, min(depth) dp
from attrs
group by productno
)
select customers_ssn,
descr,
wt,
clr,
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
case
when ht like '%cm' then
to_number(regexp_substr(ht, '^[0-9\.]*')) / 100
when ht like '%m' then
to_number(regexp_substr(ht, '^[0-9\.]*'))
else to_number(ht) / 100
end *
case
when wd like '%cm' then
to_number(regexp_substr(wd, '^[0-9\.]*')) / 100
when wd like '%m' then
to_number(regexp_substr(wd, '^[0-9\.]*') )
else to_number(dp) / 100
end *
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
case
when dp like '%cm' then
to_number(regexp_substr(dp, '^[0-9\.]*')) / 100
when dp like '%m' then
to_number(regexp_substr(dp, '^[0-9\.]*') )
else to_number(dp) / 100
end volume,
sum ( qty * howmuchtheypay )
from "Order" o
join orderline ol
on o.orderno = ol.order_orderno
join product_details pd
on ol.products_productno = pd.productno
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
where ( to_date (
o."Date" default null on conversion error,
'DD-MON-YYYY'
) > add_months(sysdate, -1) or
to_date (
o."Date" default null on conversion error,
'MM/DD/YYYY'
) > add_months(sysdate, -1) or
to_date (
o."Date" default null on conversion error,
'YYYY/MM/DD'
) > add_months(sysdate, -1)
)
group by customers_ssn, descr, ht, wd, dp, wt, clr
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
DEMO
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
select customer_id,
descr, height, width, depth, weight, colour
sum ( quantity * unit_cost )
from orders o
join orderlines ol
on o.order_id = ol.order_id
join product_details pd
on ol.product_id = pd.product_id
where o.date_time >= add_months(sysdate, -1)
group by customer_id,
descr, height, width, depth, weight, colour
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Bad Primary s
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Bad Primary s
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Always surrogate?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
School Teacher Scheduling
Who is teaching what, when, and where?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
New Requirement!
You can only schedule approved teachers for a class
Surrogate key
create table class_teachers (
class_teacher_id integer,
teacher_id integer,
class_id integer,
primary key ( class_teacher_id ),
unique ( teacher_id, class_id )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Teachers must be approved for classes
No teacher_id!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
No surrogate: can implement rules!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Wrong Data Types
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Wrong Data Types: Invalid Data
create table bad_data_types (
date_yyyymmdd integer
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
alter table bad_data_types add constraint is_date check (
to_number (
to_date ( date_yyyymmdd , 'yyyymmdd' ) ,
'yyyymmdd' ) = date_yyyymmdd
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
alter table bad_data_types add constraint is_date check (
to_number (
to_date ( date_yyyymmdd , 'yyyymmdd' ) ,
'yyyymmdd' ) = date_yyyymmdd
) novalidate;
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Defaults to client's NLS settings!
validate_conversion (
<expression> as <data type>,
[ <format mask> ],
[ <nls_parameters> ]
)
1 = Success!
0 = Failure
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
select to_date(date_yyyymmdd, 'yyyymmdd')
from bad_data_types
where validate_conversion (
date_yyyymmdd as date, 'yyyymmdd'
) = 1;
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
this... ...must match this
cast (
<expression> as <data type>
[ default <value> on conversion error ],
[ <format mask> ],
[ <nls_parameters> ] to_date()
)
to_number()
Also...
to_timestamp()
etc.
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
select to_date(
date_yyyymmdd
default '99991231'
on conversion error,
'yyyymmdd'
)
from bad_data_types;
31-DEC-9999
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Wrong Data Types: Performance
…how to screw up the optimizer's estimates
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Flexible
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Flexible Flexible
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Functions (12.1.0.2)
• json_value – extract single value
• json_query – return JSON fragment
• json_table – convert JSON to relational table
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Functions (12.1.0.2)
• json_value – extract single value
• json_query – return JSON fragment
• json_table – convert JSON to relational table
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Data Guide
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Data Guide (12.2.0.1)
alter table products add constraint
product_desc_is_json_c check (
product_description_json is json
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Data Guide (12.2.0.1)
begin
DBMS_JSON.add_virtual_columns(
'PRODUCTS',
'product_description_json',
DBMS_JSON.get_index_dataguide('PRODUCTS',
'product_description_json',
DBMS_JSON.FORMAT_HIERARCHICAL)
);
end;
/
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Data Guide (12.2.0.1)
begin
DBMS_JSON.create_view (
'products_v',
'PRODUCTS',
'product_description_json',
DBMS_JSON.get_index_dataguide(
'PRODUCTS', 'product_description_json',
DBMS_JSON.FORMAT_HIERARCHICAL)
);
end;
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Oracle Data Modeler Helps
You Build Better Databases
Use it!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
thatjeffsmith.com
#MakeDataGreatAgain
Gratisography
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon