• No results found

How to Move Object-Relational Mapping into the Database. David Wheeler Kineticode OSCON 2005

N/A
N/A
Protected

Academic year: 2021

Share "How to Move Object-Relational Mapping into the Database. David Wheeler Kineticode OSCON 2005"

Copied!
173
0
0

Loading.... (view fulltext now)

Full text

(1)

How to Move

Object-Relational Mapping

into the Database

David Wheeler

Kineticode

OSCON 2005

(2)

Polymorphic

Database Design

David Wheeler

Kineticode

OSCON 2005

(3)
(4)

Executive summary

(5)

Executive summary

Look at simple object-oriented examples

(6)

Executive summary

Look at simple object-oriented examples

Examine typical database serialization approach

Make the

database do the work

(7)

Executive summary

Look at simple object-oriented examples

Examine typical database serialization approach

Make the

database do the work

(8)
(9)

Start with a class

CD::Album

title

artist

publisher

isbn

(10)

Start with a class

CD::Album

title

artist

publisher

isbn

(11)
(12)

Standard Approach

(13)

Standard Approach

Rules:

(14)

Standard Approach

Rules:

Class == Table

Object == Row

(15)

Standard Approach

Rules:

Class == Table

Object == Row

(16)

Standard Approach

Rules:

Class == Table

Object == Row

Attribute == Column

Methodology

(17)

Standard Approach

Rules:

Class == Table

Object == Row

Attribute == Column

Methodology

Create Table

(18)

Standard Approach

Rules:

Class == Table

Object == Row

Attribute == Column

Methodology

Create Table

(19)
(20)

Create a Table

CREATE TABLE album (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

title TEXT,

artist TEXT,

publisher TEXT,

isbn TEXT

);

(21)

Not much to see here

Create a Table

CREATE TABLE album (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

title TEXT,

artist TEXT,

publisher TEXT,

isbn TEXT

);

(22)

Not much to see here

Create a Table

CREATE TABLE album (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

title TEXT,

artist TEXT,

publisher TEXT,

isbn TEXT

);

(23)
(24)

SELECT id, title, artist, publisher,

isbn

FROM album;

(25)

SELECT id, title, artist, publisher,

isbn

FROM album

WHERE id = ?;

(26)

Gee, that was easy

SELECT id, title, artist, publisher,

isbn

FROM album

WHERE id = ?;

(27)

Gee, that was easy

Inflate objects from each row

SELECT id, title, artist, publisher,

isbn

FROM album

WHERE id = ?;

(28)

Gee, that was easy

Inflate objects from each row

SELECT id, title, artist, publisher,

isbn

FROM album

WHERE id = ?;

(29)

Examine the output

id title artist publisher isbn ---- --- ---1 Rage Against the Machine Rage Against the Machine Atlantic 0---12848939 2 OK Computer Radiohead Atlantic 934293249 3 Elephant The White Stripes BMG 000864P55 4 Get Behind Me Satan The White Stripes BMG 949394595 5 Purple Rain Prince and the Revolution Warner Bro 638594823 6 Roots of a Revolution James Brown Polydor 496758395 7 Blood Sugar Sex Magik Red Hot Chili Peppers Warnter Br 957483845 8 Frizzle Fry Primus Atlantic 685968345

(30)

Examine the output

Hey cool!

id title artist publisher isbn ---- --- ---1 Rage Against the Machine Rage Against the Machine Atlantic 0---12848939 2 OK Computer Radiohead Atlantic 934293249 3 Elephant The White Stripes BMG 000864P55 4 Get Behind Me Satan The White Stripes BMG 949394595 5 Purple Rain Prince and the Revolution Warner Bro 638594823 6 Roots of a Revolution James Brown Polydor 496758395 7 Blood Sugar Sex Magik Red Hot Chili Peppers Warnter Br 957483845 8 Frizzle Fry Primus Atlantic 685968345

(31)

Examine the output

Hey cool!

Single row == single object

id title artist publisher isbn ---- --- ---1 Rage Against the Machine Rage Against the Machine Atlantic 0---12848939 2 OK Computer Radiohead Atlantic 934293249 3 Elephant The White Stripes BMG 000864P55 4 Get Behind Me Satan The White Stripes BMG 949394595 5 Purple Rain Prince and the Revolution Warner Bro 638594823 6 Roots of a Revolution James Brown Polydor 496758395 7 Blood Sugar Sex Magik Red Hot Chili Peppers Warnter Br 957483845 8 Frizzle Fry Primus Atlantic 685968345

(32)

Examine the output

Hey cool!

Single row == single object

id title artist publisher isbn ---- --- ---1 Rage Against the Machine Rage Against the Machine Atlantic 0---12848939 2 OK Computer Radiohead Atlantic 934293249 3 Elephant The White Stripes BMG 000864P55 4 Get Behind Me Satan The White Stripes BMG 949394595 5 Purple Rain Prince and the Revolution Warner Bro 638594823 6 Roots of a Revolution James Brown Polydor 496758395 7 Blood Sugar Sex Magik Red Hot Chili Peppers Warnter Br 957483845 8 Frizzle Fry Primus Atlantic 685968345

(33)

Let’s add a subclass

CD::Album

title

artist

publisher

isbn

(34)

Let’s add a subclass

CD::Music::Classical

composer

conductor

soloist

orchestra

CD::Album

title

artist

publisher

isbn

(35)

Let’s add a subclass

Piece of cake, right?

CD::Music::Classical

composer

conductor

soloist

orchestra

CD::Album

title

artist

publisher

isbn

(36)
(37)

Typical Subclassing Approach

(38)

Typical Subclassing Approach

Create another table

(39)

Typical Subclassing Approach

Create another table

Reference the parent class’ table

Write a two queries for each table

(40)

Typical Subclassing Approach

Create another table

Reference the parent class’ table

Write a two queries for each table

Write a JOIN query for both tables

(41)
(42)

Create the new table

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

album_id INTEGER NOT NULL

REFERENCES album(id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(43)

Create the new table

Hrm…not bad

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

album_id INTEGER NOT NULL

REFERENCES album(id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(44)

Create the new table

Hrm…not bad

You use foreign keys,

right?

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

album_id INTEGER NOT NULL

REFERENCES album(id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(45)

Create the new table

Hrm…not bad

You use foreign keys,

right?

What about the SELECT statement?

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

AUTOINCREMENT,

album_id INTEGER NOT NULL

REFERENCES album(id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(46)
(47)

Write SELECT query

SELECT m.id, title, artist, publisher,

isbn, c.id composer, conductor,

orchestra

FROM album m JOIN classical c

ON m.id = c.album_id;

(48)

Write SELECT query

Also not too bad

SELECT m.id, title, artist, publisher,

isbn, c.id composer, conductor,

orchestra

FROM album m JOIN classical c

ON m.id = c.album_id;

(49)

Write SELECT query

Also not too bad

Let’s see how it works…

SELECT m.id, title, artist, publisher,

isbn, c.id composer, conductor,

orchestra

FROM album m JOIN classical c

ON m.id = c.album_id;

(50)

What’s wrong here?

id title id composer --- --- --- ---9 Emperor Concerto 1 Beethoven 10 Eroica Symphony 2 Beethoven 11 Amadeus Soundtrack 3 Mozart

(51)

What’s wrong here?

Two IDs? That’s annoying

id title id composer --- --- --- ---9 Emperor Concerto 1 Beethoven 10 Eroica Symphony 2 Beethoven 11 Amadeus Soundtrack 3 Mozart

(52)

What’s wrong here?

Two IDs? That’s annoying

Different ID for the same object

id title id composer --- --- --- ---9 Emperor Concerto 1 Beethoven 10 Eroica Symphony 2 Beethoven 11 Amadeus Soundtrack 3 Mozart

(53)

What’s wrong here?

Two IDs? That’s annoying

Different ID for the same object

Which to use?

id title id composer --- --- --- ---9 Emperor Concerto 1 Beethoven 10 Eroica Symphony 2 Beethoven 11 Amadeus Soundtrack 3 Mozart

(54)

What’s wrong here?

Two IDs? That’s annoying

Different ID for the same object

Which to use?

id title id composer --- --- --- ---9 Emperor Concerto 1 Beethoven 10 Eroica Symphony 2 Beethoven 11 Amadeus Soundtrack 3 Mozart

(55)
(56)

Create the table again

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

REFERENCES album (id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(57)

Create the table again

Gee, that’s simpler

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

REFERENCES album (id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(58)

Create the table again

Gee, that’s simpler

The primary key is also a foreign key

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

REFERENCES album (id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(59)

Create the table again

Gee, that’s simpler

The primary key is also a foreign key

You still use the foreign key constraint,

right?

CREATE TABLE classical (

id INTEGER NOT NULL PRIMARY KEY

REFERENCES album (id),

composer TEXT,

conductor TEXT,

orchestra TEXT

);

(60)
(61)

Write SELECT query again

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN classical c

ON m.id = c.id;

(62)

Write SELECT query again

That got a bit simpler, too

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN classical c

ON m.id = c.id;

(63)

Write SELECT query again

That got a bit simpler, too

Disambiguate the ID column

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN classical c

ON m.id = c.id;

(64)

Write SELECT query again

That got a bit simpler, too

Disambiguate the ID column

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN classical c

ON m.id = c.id;

(65)

Now we’re talkin’!

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(66)

Now we’re talkin’!

Just one ID

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(67)

Now we’re talkin’!

Just one ID

But why must we write a JOIN query?

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(68)

Now we’re talkin’!

Just one ID

But why must we write a JOIN query?

Couldn’t it be

even simpler?

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(69)

Now we’re talkin’!

Just one ID

But why must we write a JOIN query?

Couldn’t it be

even simpler?

Can’t we truly have one class == one table?

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(70)

Yes, it can!

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN classical c

ON m.id = c.id;

(71)

Yes, it can!

CREATE VIEW classical AS

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN album_classical c

ON m.id = c.id;

(72)

Yes, it can!

Now we have a single “table”

CREATE VIEW classical AS

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN album_classical c

ON m.id = c.id;

(73)

Yes, it can!

Now we have a single “table”

Rename subclass table to represent inheritance

CREATE VIEW classical AS

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN album_classical c

ON m.id = c.id;

(74)

Yes, it can!

Now we have a single “table”

Rename subclass table to represent inheritance

CREATE VIEW classical AS

SELECT m.id AS id, title, artist,

publisher, isbn, composer,

conductor, orchestra

FROM album m JOIN album_classical c

ON m.id = c.id;

(75)
(76)

Query the VIEW

SELECT id, title, artist, publisher,

isbn, composer, conductor,

orchestra

FROM classical;

(77)

Query the VIEW

Also a bit simpler

SELECT id, title, artist, publisher,

isbn, composer, conductor,

orchestra

FROM classical;

(78)

Query the VIEW

Also a bit simpler

The database handles inheritance transparently

SELECT id, title, artist, publisher,

isbn, composer, conductor,

orchestra

FROM classical;

(79)

Query the VIEW

Also a bit simpler

The database handles inheritance transparently

The VIEW is compiled, thus faster

SELECT id, title, artist, publisher,

isbn, composer, conductor,

orchestra

FROM classical;

(80)

Query the VIEW

Also a bit simpler

The database handles inheritance transparently

The VIEW is compiled, thus faster

SELECT id, title, artist, publisher,

isbn, composer, conductor,

orchestra

FROM classical;

(81)

Get the same output

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(82)

Get the same output

Hey, awesome!

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(83)

Get the same output

Hey, awesome!

Returns the same records as before

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(84)

Get the same output

Hey, awesome!

Returns the same records as before

It’s faster, too

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(85)

Get the same output

Hey, awesome!

Returns the same records as before

It’s faster, too

But what about INSERTs, UPDATEs, and DELETEs?

id title composer conductor --- -- ---9 Emperor Concerto Beethoven Ozawa 10 Eroica Symphony Beethoven Bernstein 11 Amadeus Soundtrack Mozart Neville Ma

(86)
(87)

Back to the base class

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Kid B', 'Radiohed', 'Polygramm', '0000');

(88)

Back to the base class

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Kid B', 'Radiohed', 'Polygramm', '0000');

UPDATE album

SET title = 'Kid A',

artist = 'Radiohead',

publisher = 'Polygram',

isbn = '4959'

(89)

Back to the base class

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Kid B', 'Radiohed', 'Polygramm', '0000');

UPDATE album

SET title = 'Kid A',

artist = 'Radiohead',

publisher = 'Polygram',

isbn = '4959'

WHERE id = 12;

DELETE FROM album

(90)

Back to the base class

Seems pretty straight-forward

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Kid B', 'Radiohed', 'Polygramm', '0000');

UPDATE album

SET title = 'Kid A',

artist = 'Radiohead',

publisher = 'Polygram',

isbn = '4959'

WHERE id = 12;

DELETE FROM album

(91)

Back to the base class

Seems pretty straight-forward

Let’s try it…

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Kid B', 'Radiohed', 'Polygramm', '0000');

UPDATE album

SET title = 'Kid A',

artist = 'Radiohead',

publisher = 'Polygram',

isbn = '4959'

WHERE id = 12;

DELETE FROM album

(92)
(93)

And now the subclass

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(94)

And now the subclass

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony'); UPDATE classical

SET title = 'Cinema Serenade', artist = 'Itzak Perlman', publisher = 'BMG',

isbn = '2764', composer = 'Various',

conductor = 'John Williams',

orchestra = 'Pittsburgh Symphony' WHERE id = 13;

(95)

And now the subclass

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony'); UPDATE classical

SET title = 'Cinema Serenade', artist = 'Itzak Perlman', publisher = 'BMG',

isbn = '2764', composer = 'Various',

conductor = 'John Williams',

orchestra = 'Pittsburgh Symphony' WHERE id = 13;

DELETE FROM classical WHERE id = 13;

(96)

And now the subclass

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony'); UPDATE classical

SET title = 'Cinema Serenade', artist = 'Itzak Perlman', publisher = 'BMG',

isbn = '2764', composer = 'Various',

conductor = 'John Williams',

orchestra = 'Pittsburgh Symphony' WHERE id = 13;

DELETE FROM classical WHERE id = 13;

(97)

D’oh! What now?

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony'); SQL error: cannot modify classical because it is a view

(98)

D’oh! What now?

VIEWs are not updatable

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony'); SQL error: cannot modify classical because it is a view

(99)

D’oh! What now?

VIEWs are not updatable

Must modify the two tables separately

INSERT INTO classical (title, artist, publisher, isbn, composer, conductor, orchestra)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323', 'Verious', 'Jon Williams', 'Pittsburg Symphony'); SQL error: cannot modify classical because it is a view

(100)
(101)

INSERT classical object

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323'); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(102)

INSERT classical object

We have to modify the two table separately

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323'); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(103)

INSERT classical object

We have to modify the two table separately

Use function to populate subclass ID

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323'); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(104)

INSERT classical object

We have to modify the two table separately

Use function to populate subclass ID

SQLite: last_insert_rowid()

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323'); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(105)

INSERT classical object

We have to modify the two table separately

Use function to populate subclass ID

SQLite: last_insert_rowid()

MySQL: last_insert_id()

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323'); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(106)

INSERT classical object

We have to modify the two table separately

Use function to populate subclass ID

SQLite: last_insert_rowid()

MySQL: last_insert_id()

INSERT INTO album (title, artist, publisher, isbn)

VALUES ('Cinema Serenad', 'Itzack Perlman', 'BMC', '2323'); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), 'Verious', 'Jon Williams', 'Pittsburg Symphony');

(107)
(108)

UPDATE classical object

UPDATE album

SET title = 'Cinema Serenade', artist = 'Itzak Perlman', publisher = 'BMG',

isbn = '2764' WHERE id = 13;

UPDATE album_classical

SET composer = 'Various',

conductor = 'John Williams',

orchestra = 'Pittsburgh Symphony' WHERE id = 13;

(109)

UPDATE classical object

Again, modify the two table separately

UPDATE album

SET title = 'Cinema Serenade', artist = 'Itzak Perlman', publisher = 'BMG',

isbn = '2764' WHERE id = 13;

UPDATE album_classical

SET composer = 'Various',

conductor = 'John Williams',

orchestra = 'Pittsburgh Symphony' WHERE id = 13;

(110)
(111)

DELETE classical object

DELETE FROM album_classical WHERE id = 13;

DELETE FROM album WHERE id = 13;

(112)

DELETE classical object

And again, modify the two table separately

DELETE FROM album_classical WHERE id = 13;

DELETE FROM album WHERE id = 13;

(113)

DELETE classical object

And again, modify the two table separately

Unless your foreign key is ON DELETE CASCADE

DELETE FROM album_classical WHERE id = 13;

DELETE FROM album WHERE id = 13;

(114)

DELETE classical object

And again, modify the two table separately

Unless your foreign key is ON DELETE CASCADE

DELETE FROM album_classical WHERE id = 13;

DELETE FROM album WHERE id = 13;

(115)
(116)

Is there no other way?

(117)

Is there no other way?

The more complex your relations, the more queries

All because you can’t update VIEWs

(118)

Is there no other way?

The more complex your relations, the more queries

All because you can’t update VIEWs

(119)
(120)

Updatable views

(121)

Updatable views

SQLite supports triggers on VIEWs

PostgreSQL supports rules on VIEWs

(122)

Updatable views

SQLite supports triggers on VIEWs

PostgreSQL supports rules on VIEWs

(123)
(124)

SQLite INSERT trigger

CREATE TRIGGER insert_classical INSTEAD OF INSERT ON classical FOR EACH ROW BEGIN

INSERT INTO album (title, artist, publisher, isbn)

VALUES (NEW.title, NEW.artist, NEW.publisher, NEW.isbn); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), NEW.composer, NEW.conductor, NEW.orchestra);

(125)

SQLite INSERT trigger

Use NEW variable to populate values

CREATE TRIGGER insert_classical INSTEAD OF INSERT ON classical FOR EACH ROW BEGIN

INSERT INTO album (title, artist, publisher, isbn)

VALUES (NEW.title, NEW.artist, NEW.publisher, NEW.isbn); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), NEW.composer, NEW.conductor, NEW.orchestra);

(126)

SQLite INSERT trigger

Use NEW variable to populate values

CREATE TRIGGER insert_classical INSTEAD OF INSERT ON classical FOR EACH ROW BEGIN

INSERT INTO album (title, artist, publisher, isbn)

VALUES (NEW.title, NEW.artist, NEW.publisher, NEW.isbn); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (last_insert_rowid(), NEW.composer, NEW.conductor, NEW.orchestra);

(127)
(128)

PostgreSQL INSERT rule

CREATE RULE insert_classical AS

ON INSERT TO classical DO INSTEAD (

INSERT INTO album (title, artist, publisher, isbn)

VALUES (NEW.title, NEW.artist, NEW.publisher, NEW.isbn); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (CURRVAL('seq_album_id_seq'), NEW.composer, NEW.conductor, NEW.orchestra);

(129)

PostgreSQL INSERT rule

Use NEW variable to populate values

CREATE RULE insert_classical AS

ON INSERT TO classical DO INSTEAD (

INSERT INTO album (title, artist, publisher, isbn)

VALUES (NEW.title, NEW.artist, NEW.publisher, NEW.isbn); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (CURRVAL('seq_album_id_seq'), NEW.composer, NEW.conductor, NEW.orchestra);

(130)

PostgreSQL INSERT rule

Use NEW variable to populate values

CREATE RULE insert_classical AS

ON INSERT TO classical DO INSTEAD (

INSERT INTO album (title, artist, publisher, isbn)

VALUES (NEW.title, NEW.artist, NEW.publisher, NEW.isbn); INSERT INTO album_classical

(id, composer, conductor, orchestra)

VALUES (CURRVAL('seq_album_id_seq'), NEW.composer, NEW.conductor, NEW.orchestra);

(131)
(132)

SQLite UPDATE trigger

CREATE TRIGGER update_classical INSTEAD OF UPDATE ON classical FOR EACH ROW BEGIN

UPDATE album

SET title = NEW.title, artist = NEW.artist, publisher = NEW.publisher, isbn = NEW.isbn

WHERE id = OLD.id; UPDATE album_classical

SET composer = NEW.composer, conductor = NEW.conductor, orchestra = NEW.orchestra WHERE id = OLD.id;

(133)

SQLite UPDATE trigger

Use OLD.id variable to reference existing rows

CREATE TRIGGER update_classical INSTEAD OF UPDATE ON classical FOR EACH ROW BEGIN

UPDATE album

SET title = NEW.title, artist = NEW.artist, publisher = NEW.publisher, isbn = NEW.isbn

WHERE id = OLD.id; UPDATE album_classical

SET composer = NEW.composer, conductor = NEW.conductor, orchestra = NEW.orchestra WHERE id = OLD.id;

(134)
(135)

PostgreSQL UPDATE rule

CREATE RULE update_classical AS

ON UPDATE TO classical DO INSTEAD ( UPDATE album

SET title = NEW.title, artist = NEW.artist, publisher = NEW.publisher, isbn = NEW.isbn

WHERE id = OLD.id; UPDATE album_classical

SET composer = NEW.composer, conductor = NEW.conductor, orchestra = NEW.orchestra WHERE id = OLD.id;

(136)

PostgreSQL UPDATE rule

CREATE RULE update_classical AS

ON UPDATE TO classical DO INSTEAD ( UPDATE album

SET title = NEW.title, artist = NEW.artist, publisher = NEW.publisher, isbn = NEW.isbn

WHERE id = OLD.id; UPDATE album_classical

SET composer = NEW.composer, conductor = NEW.conductor, orchestra = NEW.orchestra WHERE id = OLD.id;

(137)
(138)

SQLite DELETE trigger

CREATE TRIGGER delete_classical INSTEAD OF DELETE ON classical FOR EACH ROW BEGIN

DELETE FROM album_classical WHERE id = OLD.id;

DELETE FROM album WHERE id = OLD.id; END;

(139)

SQLite DELETE trigger

Use OLD.id to delete the proper row

CREATE TRIGGER delete_classical INSTEAD OF DELETE ON classical FOR EACH ROW BEGIN

DELETE FROM album_classical WHERE id = OLD.id;

DELETE FROM album WHERE id = OLD.id; END;

(140)
(141)

PostgreSQL DELETE rule

CREATE RULE delete_classical AS

ON DELETE TO classical DO INSTEAD ( DELETE FROM album_classical

WHERE id = OLD.id; DELETE FROM album WHERE id = OLD.id; );

(142)

PostgreSQL DELETE rule

Use OLD.id to delete the proper row

CREATE RULE delete_classical AS

ON DELETE TO classical DO INSTEAD ( DELETE FROM album_classical

WHERE id = OLD.id; DELETE FROM album WHERE id = OLD.id; );

(143)

PostgreSQL DELETE rule

Use OLD.id to delete the proper row

Let’s see how they work…

CREATE RULE delete_classical AS

ON DELETE TO classical DO INSTEAD ( DELETE FROM album_classical

WHERE id = OLD.id; DELETE FROM album WHERE id = OLD.id; );

(144)
(145)

Trigger/Rule Advantages

(146)

Trigger/Rule Advantages

Queries are pre-compiled

(147)

Trigger/Rule Advantages

Queries are pre-compiled

Much simpler client-side code

(148)

Trigger/Rule Advantages

Queries are pre-compiled

Much simpler client-side code

Fewer queries sent to the database

Reduced network overhead

(149)

Trigger/Rule Advantages

Queries are pre-compiled

Much simpler client-side code

Fewer queries sent to the database

Reduced network overhead

(150)
(151)

One-to-many relationships

(152)

One-to-many relationships

Often have one-to-many relationships

Let’s we add track objects

(153)

One-to-many relationships

Often have one-to-many relationships

Let’s we add track objects

(154)

One-to-many relationships

Often have one-to-many relationships

Let’s we add track objects

Each refers to a single album object

(155)

One-to-many relationships

Often have one-to-many relationships

Let’s we add track objects

Each refers to a single album object

Often need to know album information for the track

Generally requires two queries, one for each object

(156)

One-to-many relationships

Often have one-to-many relationships

Let’s we add track objects

Each refers to a single album object

Often need to know album information for the track

Generally requires two queries, one for each object

SELECT id, title, numb, album_id FROM track;

(157)

JOIN composite objects

SELECT track.id AS id, track.title AS title, numb, album.id AS album__id,

album.title AS album__title, artist AS album__artist, publisher AS album__publisher, isbn AS album__isbn

FROM track JOIN album

(158)

JOIN composite objects

Or, do a JOIN, instead

SELECT track.id AS id, track.title AS title, numb, album.id AS album__id,

album.title AS album__title, artist AS album__artist, publisher AS album__publisher, isbn AS album__isbn

FROM track JOIN album

(159)

JOIN composite objects

Or, do a JOIN, instead

Saves network overhead

SELECT track.id AS id, track.title AS title, numb, album.id AS album__id,

album.title AS album__title, artist AS album__artist, publisher AS album__publisher, isbn AS album__isbn

FROM track JOIN album

(160)

JOIN composite objects

Or, do a JOIN, instead

Saves network overhead

SELECT track.id AS id, track.title AS title, numb, album.id AS album__id,

album.title AS album__title, artist AS album__artist, publisher AS album__publisher, isbn AS album__isbn

FROM track JOIN album

(161)

CREATE VIEW track AS

SELECT _track.id AS id, _track.title AS title, numb, album.id AS album__id,

album.title AS album__title, artist AS album__artist, publisher AS album__publisher, isbn AS album__isbn

FROM _track JOIN album

ON _track.album_id = album.id;

JOIN composite objects

Or, do a JOIN, instead

Saves network overhead

(162)
(163)

What about MySQL?

(164)

What about MySQL?

MySQL 5 supports views

(165)

What about MySQL?

MySQL 5 supports views

Can INSERT, UPDATE, & DELETE on single table views

Cannot on multi-table (JOIN) views

(166)

What about MySQL?

MySQL 5 supports views

Can INSERT, UPDATE, & DELETE on single table views

Cannot on multi-table (JOIN) views

(167)

What about MySQL?

MySQL 5 supports views

Can INSERT, UPDATE, & DELETE on single table views

Cannot on multi-table (JOIN) views

MySQL supports triggers

(168)

What about MySQL?

MySQL 5 supports views

Can INSERT, UPDATE, & DELETE on single table views

Cannot on multi-table (JOIN) views

MySQL supports triggers

Cannot assign triggers to views

No rules

(169)
(170)

Resources

“PostgreSQL: Introduction and Concepts” by Bruce Momjian

http://xrl.us/gy3a

(171)

Resources

“PostgreSQL: Introduction and Concepts” by Bruce Momjian

http://xrl.us/gy3a

(172)

Resources

“PostgreSQL: Introduction and Concepts” by Bruce Momjian

http://xrl.us/gy3a

SQLite: http://www.sqlite.org/

(173)

Thank you

David Wheeler

Kineticode

OSCON 2005

References

Related documents

Iako je analizom dobiven rezultat kako izostajanje s nastave radi prisustvovanja sportskim događajima nije statistički povezano s mišljenjem učenika da su pravila u školi poštena

Create all these analytical services, where clause with easy explanation for post method of range of spring data jpa can inject any mysql java insert update delete example will

The database manager executes the triggered- action before it applies any changes caused by an insert, delete, or update operation on the subject table.. It also

When comparing the 10 pa- tients whose progression was slowed with the other 10 patients, the only difference is the distribution of original renal disease between the two

allows RINA Prime Value Services to provide a specialised, professional range of solutions for either Building, Asset, Facility, Property, or Energy Management. ASSET

MYSQLi Prepared Statement Create Database Create Database so Insert Some Records to MYSQL Table a Database Connection!. PHP MySQL Prepared Statements data

Never faced the database and activating bi, we delete set null cannot be found you now we asked users password from category table into table mysql insert data command line consists

If the opening rate of the air cylinder is 5 cm/s and the opening acceleration of the cylinder is 2 cm/s 2 , find the angular velocity and acceleration of link 2, and the