Ebook Learn To Use PostgreSQL For Real
Ebook Learn To Use PostgreSQL For Real
‹#›
WWW.PENTALOG.COM
$ whoami;
Achievements: ElasticSearch
contributor, ZF2 contributor.
‹#›
WWW.PENTALOG.COM
Hey, what about
Postgres?
PostgreSQL user for 5 years.
MySQL hater.
SQL evangelist.
‹#›
WWW.PENTALOG.COM
What this webinar
is NOT about
Database comparison.
PostgreSQL insides.
‹#›
WWW.PENTALOG.COM
What this webinar
IS about
Postgres Users/Roles model.
PostgreSQL DB structure.
DataGrip IDE.
Postgres Features.
‹#›
WWW.PENTALOG.COM
Ready player user one!
$ psql: error?))
‹#›
WWW.PENTALOG.COM
We need a DataBase!
http://www.postgresqltutorial.com/postgresql-sample-database/
$ CREATEDB p5test;
OR
$ psql;
CREATE DATABASE p5test;
‹#›
WWW.PENTALOG.COM
Users, users, users!
‹#›
WWW.PENTALOG.COM
It’s Data time!
$ psql;
$ \l
$ \c p5test;
$ \dt
‹#›
WWW.PENTALOG.COM
SetUp DataGrip!
‹#›
WWW.PENTALOG.COM
DB structure!
2)Schemas - abstract
containers for tables and other
relations.
‹#›
WWW.PENTALOG.COM
First steps!
$ psql;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO p5user;
‹#›
WWW.PENTALOG.COM
Views!
A view is a named query
that provides another way to
present data in the database
tables. A view is defined
based on one or more
tables, which are known as
base tables. When you
create a view, you basically
create a query and assign it
a name, therefore a view is
useful for wrapping a
commonly used complex
query.
‹#›
WWW.PENTALOG.COM
Views, under the hood!
$ psql;
\d+ actor_info;
View definition:
SELECT a.actor_id,
a.first_name,
a.last_name,
group_concat(DISTINCT (c.name::text || ': '::text) || (( SELECT group_concat(f.title::text) AS
group_concat
FROM film f
JOIN film_category fc_1 ON f.film_id = fc_1.film_id
JOIN film_actor fa_1 ON f.film_id = fa_1.film_id
WHERE fc_1.category_id = c.category_id AND fa_1.actor_id = a.actor_id
GROUP BY fa_1.actor_id))) AS film_info
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
LEFT JOIN film_category fc ON fa.film_id = fc.film_id
LEFT JOIN category c ON fc.category_id = c.category_id
GROUP BY a.actor_id, a.first_name, a.last_name;
‹#›
WWW.PENTALOG.COM
MATERIALIZED VIEWS!
CREATE MATERIALIZED VIEW actor_info_mv AS
SELECT a.actor_id,
a.first_name,
a.last_name,
group_concat(DISTINCT (c.name::text || ': '::text) || (( SELECT group_concat(f.title::text) AS
group_concat
FROM film f
JOIN film_category fc_1 ON f.film_id = fc_1.film_id
JOIN film_actor fa_1 ON f.film_id = fa_1.film_id
WHERE fc_1.category_id = c.category_id AND fa_1.actor_id = a.actor_id
GROUP BY fa_1.actor_id))) AS film_info
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
LEFT JOIN film_category fc ON fa.film_id = fc.film_id
LEFT JOIN category c ON fc.category_id = c.category_id
GROUP BY a.actor_id, a.first_name, a.last_name;
‹#›
WWW.PENTALOG.COM
MATERIALIZED VIEWS!
‹#›
WWW.PENTALOG.COM
MATERIALIZED VS SIMPLE VIEWS!
VIEW:
MATERIALIZED VIEW:
‹#›
WWW.PENTALOG.COM
WHY, WHY SIMPLE VIEW EXISTS?
‹#›
WWW.PENTALOG.COM
FUNCTIONS & PROCEDURES!
PostgreSQL functions, also known as Stored
Procedures, allow you to carry out operations that
would normally take several queries and round trips
in a single function within the database
Functions can be created in any language of your
choice like SQL, PL/pgSQL, C, Python, etc.
CREATE OR REPLACE FUNCTION total_films ()
RETURNS integer AS $total$
declare
total integer;
BEGIN
SELECT count(*) into total FROM film;
RETURN total;
END;
$total$ LANGUAGE plpgsql;
SELECT total_films();
‹#›
WWW.PENTALOG.COM
TRIGGERS!
A PostgreSQL trigger is a function invoked automatically
whenever an event e.g., insert, update, or delete occurred
‹#›
WWW.PENTALOG.COM
TRIGGERS!
‹#›
WWW.PENTALOG.COM
Aggregations!
‹#›
WWW.PENTALOG.COM
Aggregations!
Result:
A Fateful Reflection of a Moose And a Husband who must
Overcome a Monkey in Nigeria, A Epic Drama of a Cat And a
Explorer who must Redeem a Moose……
‹#›
WWW.PENTALOG.COM
SEQUENCE!
‹#›
WWW.PENTALOG.COM
CTE!
‹#›
WWW.PENTALOG.COM
CTE in action!
WITH updated_rows AS (
UPDATE film
SET release_year = 2006
WHERE release_year = 2005
RETURNING film_id
),
rated_films AS (
SELECT * FROM film WHERE rental_rate > 4
)
SELECT f.title, f.release_year FROM rated_films f INNER JOIN
updated_rows ur ON f.film_id = ur.film_id;
‹#›
WWW.PENTALOG.COM
RECURSIVE CTE!
UNION
SELECT i + 1
FROM loop
WHERE i < 10
)
SELECT i FROM loop;
‹#›
WWW.PENTALOG.COM
RECURSIVE FOR REAL!
Unfortunately, in our test DB we don’t have
hierarchical data, therefore we will create a new table:
‹#›
WWW.PENTALOG.COM
RECURSIVE FOR REAL!
Let’s try some real-world examples:
WITH RECURSIVE r AS (
SELECT id, parent_id, name
FROM geo
WHERE parent_id = 4
UNION ALL
SELECT geo.id, geo.parent_id, geo.name
FROM geo
JOIN r
ON geo.parent_id = r.id
)
SELECT * FROM r;
‹#›
WWW.PENTALOG.COM
RECURSIVE FOR REAL!
Here is the output:
‹#›
WWW.PENTALOG.COM
RECURSIVE FOR REAL!
Let’s add some extra information, for example the item level
WITH RECURSIVE r AS (
SELECT id, parent_id, name, 1 AS level
FROM geo
WHERE parent_id = 4
UNION ALL
SELECT geo.id, geo.parent_id, geo.name, level +1 AS level
FROM geo
JOIN r
ON geo.parent_id = r.id
)
SELECT * FROM r;
‹#›
WWW.PENTALOG.COM
RECURSIVE FOR REAL!
And the new output will be:
‹#›
WWW.PENTALOG.COM
What’s next?
- Check the official docs
- Try to use it
- Practice, practice, practice
- Wait for my next webinar(query optimization, monitoring,
logging)
‹#›
WWW.PENTALOG.COM
‹#›
WWW.PENTALOG.COM
THANK YOU!