1) NORM is a proposed alternative to ORM frameworks that aims to improve data transfer speeds between applications and databases.
2) It works by having both the application and database convert their internal data representations into complex hierarchical object structures defined by a shared "contract".
3) This allows any application endpoint to retrieve data from the database with a single call by mapping objects between the application and database models.
3. Money by the numbers
2020 3
1 sec pageloadslowdown=> $1.6billion
lost sales/year
Slowing searchresultsby0.4 sec– lossof 8
million searchesperday
50% visitors abandonthe site, which is notloadedwithin3 sec
79%visitors will never return again
5. Welcome to ORM!
ORM – Object-Relational Mapper
• solves a problem of abstraction from details of data storing
• does not provide effective means of manipulation with data sets
2020 5
7. Our Solution - NORM
TransferMapping Mapping
Database Model
(Object-
Relational)
JDBC TextText
Transfer model (JSON)
Transfer
Application Model
(Object-Oriented)
8. 8
CONTRACT
• Both sides (an application and a
database) convert internal
representations into complex
hierarchical object
• Contract establishes object structure
implemented on both sides
• Now, for any application endpoint it
takes one database call to transfer
data to and from database
App DB
2020
13. Create a UDT with Nested Types
CREATE TYPE phone_record as
( phone_id bigint ,
phone_number text ,
phone_type_id int ,
phone type text );
CREATE TYPE email_record as
(email_id bigint,
email text,
email_priority_id int,
email_priority text);
CREATE TYPE account_record as
(account_id bigint,
last_name text,
first_name text,
dob date,
phones phone_record[],
email_addresses email_record[]);
2020 13
14. Why Not Storing JSON?!
• The power of relational search is lost
• By using JSON as a return type for functions we are loosing the strong type
dependencies
That’s why we organize funcitons in “packages”:
we want to ensure that all functions from one “package” return the same object
2020 14
15. Solution
SELECT ROW(account_id ,
username,
first_name,
last_name,
dob ,
(SELECT array_agg(row(phone_id,
phone,
p.phone_type_id,
phone_type )::phone_record)
FROM phone p
JOIN phone_type pt USING (phone_type_id) WHERE p.account_id=a.account_id),
(SELECT array_agg(row(email_id,
email,
e.email_priority_id,
email_priority )::email_record)
FROM email e
JOIN email_priority ep using(email_priority_id) WHERE e.account_id=a.account_id)
)::account_record AS single_item
FROM account a WHERE a.account_id=p_account_id
2020 15
16. Transforming to Text
CREATE OR REPLACE
FUNCTION array_transport (all_items anyarray) returns setof text
RETURNS NULL ON NULL INPUT
LANGUAGE plpgsql as
$body$
DECLARE
item record;
BEGIN
FOREACH item IN array all_items
LOOP
RETURN next( to_json(item))::text;
END LOOP;
END;
2020 16
17. Example: How to Build it
https://github.com/hettie-d/NORM
2020 17