Decoupling from the details:
 |
- Don't need to worry about what is real
- The more complex, the more you need views
- Encapsulation
|

-- 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');

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

Convenience:
| |
- Add and remove columns
- Custom WHERE, GROUP BY, ORDER BY, LIMIT, OFFSET
- Overloading columns names
- Reformatting columns
- Functions everwhere
|

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

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
|

Both at once
| |
- Convenience: denormalization, formatting, overloading
- Security: hiding, permissions
|

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

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
|

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
|

Security and customization:
| |
- Customized for conveience
- Customized for security
- Who, what, where, when
- Overloading
|

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

(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

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

| Before |
| Column | Value |
| Customer | Joe Sixpack |
| Price | 5.25 |
| Payment Type | Cash |
| Payment Date | Jul 22, 2004 10:07 |
|
| After |
| Column | Value |
| Customer | Joe Sixpack |
| Email Address | joe@gmail.com |
| Price | 5.25 |
| Payment Type | Cash |
| Payment Date | Jul 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
|