Decoupling from the details:

  • Don't need to worry about what is real
  • The more complex, the more you need views
  • Encapsulation

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

-- View example setup

CREATE TABLE customer (
  id      SERIAL UNIQUE,
  cname   VARCHAR
);
INSERT INTO customer (cname) VALUES ('Joe Sixpack');
INSERT INTO customer (cname) VALUES ('Jane Sixpack');

CREATE TABLE transaction (
  id           SERIAL UNIQUE,
  customer     INTEGER NOT NULL,
  product      INTEGER NOT NULL,
  price        NUMERIC(6,2) NULL,
  payment_type VARCHAR,
  txndate      TIMESTAMPTZ NOT NULL DEFAULT now()
);
ALTER TABLE transaction ADD CONSTRAINT "txn_cust" FOREIGN KEY (customer) 
REFERENCES customer(id);

INSERT INTO transaction(customer,product,price,payment_type) VALUES (1,26,'5.25','Cash');

INSERT INTO transaction(customer,product,price,payment_type) VALUES (2,4,'150.00','Visa');

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


oscon=> CREATE VIEW txn AS SELECT * FROM transaction;
CREATE VIEW

oscon=> SELECT * FROM txn;

 id | customer | product | price  | payment_type |            txndate            
----+----------+---------+--------+--------------+-------------------------------
  1 |        1 |      26 |   5.25 | Cash         | 2004-07-22 01:33:47.202985-04
  2 |        2 |       4 | 150.00 | Visa         | 2004-07-22 01:33:50.512945-04


oscon=> SELECT * FROM transaction;

 id | customer | product | price  | payment_type |            txndate            
----+----------+---------+--------+--------------+-------------------------------
  1 |        1 |      26 |   5.25 | Cash         | 2004-07-22 01:33:47.202985-04
  2 |        2 |       4 | 150.00 | Visa         | 2004-07-22 01:33:50.512945-04

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Convenience:

 
  • Add and remove columns
  • Custom WHERE, GROUP BY, ORDER BY, LIMIT, OFFSET
  • Overloading columns names
  • Reformatting columns
  • Functions everwhere

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


oscon=> CREATE USER susan;
CREATE USER

oscon=> CREATE GROUP managers WITH USER mike, susan;
CREATE GROUP

oscon=> REVOKE ALL ON transaction FROM public;
REVOKE

oscon=> REVOKE ALL ON txn FROM public;
REVOKE

oscon=> GRANT SELECT ON txn TO GROUP managers;
GRANT

oscon=> \c oscon susan
You are now connected to database "oscon" as user "susan".

oscon=> SELECT * FROM transaction;
ERROR:  permission denied for relation transaction

oscon=> SELECT * FROM txn;

 id | customer | product | price  | payment_type |            txndate
----+----------+---------+--------+--------------+-------------------------------
  1 |        1 |      26 |   5.25 | Cash         | 2004-07-22 01:33:47.202985-04
  2 |        2 |       4 | 150.00 | Visa         | 2004-07-22 01:33:50.512945-04

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Security:

 
  • Best (some cases the only) way to allow "partial access" to your data.
  • Database itself does login permissions (pg_hba.conf)
  • GRANT/REVOKE = chmod
  • Schemas = search path and directories
  • Roles = groups

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Both at once

 
  • Convenience: denormalization, formatting, overloading
  • Security: hiding, permissions

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


1. CREATE VIEW txn2 AS 
2.   SELECT c.cname AS customer, t.price AS Price, t.payment_type AS "Payment Type", 
3.     TO_CHAR(txndate, 'Mon DD, YYYY HH:MM') AS "Payment Date"
4.   FROM transaction t, customer c
5.   WHERE t.customer=c.id;

oscon=> REVOKE ALL ON txn2 FROM public;
REVOKE

oscon=> GRANT SELECT ON txn2 TO GROUP managers;
GRANT

oscon=> SELECT * from txn2;

greg=# SELECT * from txn2;
   customer   | Price  | Payment Type |   Payment Date
--------------+--------+--------------+--------------------
 Joe Sixpack  |   5.25 | Cash         | Jul 22, 2004 10:07
 Jane Sixpack | 150.00 | Visa         | Jul 22, 2004 10:07


oscon=> SELECT * FROM transaction;
 id | customer | product | price  | payment_type |            txndate            
----+----------+---------+--------+--------------+-------------------------------
  1 |        1 |      26 |   5.25 | Cash         | 2004-07-22 01:33:47.202985-04
  2 |        2 |       4 | 150.00 | Visa         | 2004-07-22 01:33:50.512945-04


Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Better?

 
  • Normalized data is efficient but a pain in the ass to work with
  • End user does not care about third-normalized form
  • See what they need to see

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Real-life

joymail=> \d spamcount

   View "public.spamcount"
 Column |  Type  | Modifiers
--------+--------+-----------
 ip     | cidr   |
 count  | bigint |
View definition:
 SELECT spamtrack.ip, count(spamtrack.ip) AS count
   FROM spamtrack
  GROUP BY spamtrack.ip
  ORDER BY count(spamtrack.ip) DESC;


SELECT * FROM spamcount;

  • (nice layout)
  • 400+ / day
  • After iptables
  • New fodder

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Security and customization:

 
  • Customized for conveience
  • Customized for security
  • Who, what, where, when
  • Overloading

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


oscon=> show search_path;
 search_path
--------------
 $user,public

(mike)
oscon=> SELECT * FROM txn2;
   customer   | Price  | Payment Type |   Payment Date
--------------+--------+--------------+--------------------
 Joe Sixpack  |   5.25 | Cash         | Jul 22, 2004 10:07

(susan)
oscon=> SELECT * FROM txn2;
   customer   |    Email      | Price  | Payment Type |   Payment Date
--------------+---------------+--------+--------------+-------------------
 Joe Sixpack  | joe@gmail.com |   5.25 | Cash         | Jul 22, 2004 10:07

(susan)
managers=> SELECT * FROM txn2;
   customer   | Price  | Payment Type |   Payment Date
--------------+--------+--------------+--------------------
 Joe Sixpack  |   **** | Cash         | Jul 22, 2004 10:07

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 




(susan at 10pm)
managers=> SELECT * FROM txn2;
   customer   | Price  | Payment Type |   Payment Date
--------------+--------+--------------+--------------------
 Joe Sixpack  |  small | Cash         | Jul 22, 2004 10:07

managers=> SELECT * FROM showcustomers();
   customer   | Price  | Payment Type |   Payment Date
 Joe Sixpack  |   5.25 | Cash         | Jul 22, 2004 10:07




Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Application coping:

 
  • The app can try and be flexible about all this
  • Field names are sent back as well
  • Simple display option:

Next


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Before
ColumnValue
CustomerJoe Sixpack
Price5.25
Payment TypeCash
Payment DateJul 22, 2004 10:07
After
ColumnValue
CustomerJoe Sixpack
Email Addressjoe@gmail.com
Price5.25
Payment TypeCash
Payment DateJul 22, 2004 10:07





Thoughts:

 
  • Overloading not always the best way
  • Can keep some business logic close to the data
  • Easy to make sweeping changes

      Last             TOC             Next