Modul PostgreSQL Terbaru - WebHozz
Modul PostgreSQL Terbaru - WebHozz
We have written this small book for those who only start
getting acquainted with the world of PostgreSQL. From this
book, you will learn:
We hope that our book will make your first experience with
PostgreSQL more pleasant and help you blend into the Post-
greSQL community. Good luck!
I About PostgreSQL
Some History
Current State
Indexing
• Hash,
a hash-based index. Unlike B-trees, such indexes work
only for equality checks, but in some cases they can prove
to be more efficient and compact.
• GiST,
a generalized balanced search tree. This access method
is used for the data that cannot be ordered. For example,
R-trees that are used to index points on a plane and can
serve to implement fast k-nearest neighbor (k-NN) search,
or indexing overlapping intervals.
• SP-GiST,
a generalized non-balanced tree based on dividing the
search space into non-intersecting nested partitions. For
example, quad-trees for spatial data and radix trees for
text strings.
• GIN,
a generalized inverted index used for compound multi-
element values. It is mainly applied in full-text search to
12 find documents that contain the words used in the search
i query. Another example is search for elements in data
arrays.
• RUM,
an enhancement of the GIN method for full-text search.
Available as an extension, this index type can speed
up phrase search and return the results in the order of
relevance without any additional computations.
• BRIN,
a compact structure that provides a trade-off between the
index size and search efficiency. Such index is useful for
huge clustered tables.
• Bloom,
an index based on the Bloom filter. Having a compact rep-
resentation, this index can quickly filter out non-matching
tuples, but the remaining ones have to be re-checked.
Cross-Platform Support
Extensibility
• data types
• functions and operators to support new data types
• index and table access methods
• server programming languages
• foreign data wrappers
• loadable extensions
• CitusDB,
which implements massively parallel query execution and
data distribution between different PostgreSQL instances
(sharding).
• PostGIS,
one of the most popular and powerful geoinformation
data processing systems.
14 • TimescaleDB,
i which provides support for time-series data, including
special partitioning and sharding.
Availability
Independence
SQL Commands
Functions
Partitioning
Logical Replication
Backup
Monitoring
Postgres_fdw
Optimizations
Documentation
You can also use Postgres Pro Standard 15: it is fully com-
patible with vanilla PostgreSQL, includes some additional
features developed by Postgres Professional, and is free when
used for trial or educational purposes. Check out installation
instructions at postgrespro.com/products/download in this
case.
24 Windows
iii
Installation
You can leave the default settings in all the other fields.
26
iii
To start the service, run the “Start Server” program from the
same folder.
Installation
$ locale
$ export LC_CTYPE=fr_FR.UTF8
$ export LC_COLLATE=fr_FR.UTF8
You should also make sure that the operating system has the
required locale installed:
• /etc/postgresql/15/main/postgresql.conf is the
main configuration file that contains server parameters.
• /etc/postgresql/15/main/pg_hba.conf file defines ac-
cess settings. For security reasons, the default configura-
tion only allows access from the local system on behalf of
the database user that has the same name as the current
OS user.
Now it’s time to connect to the database and try out SQL.
IV Trying SQL
Now let’s try out some commands. Enter only the part printed
in bold; the prompt and the system response are provided
here solely for your convenience.
Databases 35
iv
Let’s create a new database called test:
postgres=# \c test
You are now connected to database "test" as user
"postgres".
test=#
The command that we’ve just entered does not look like SQL,
as it starts with a backslash. This is a convention for special
commands that can only be run in psql (so if you are using
pgAdmin or some other GUI tool, skip all commands starting
with a backslash or try to find an equivalent).
There are quite a few psql commands, and we’ll use some of
them a bit later. To get the full list of psql commands right
now, you can run:
test=# \?
• integer
• text
• boolean, which is a logical data type taking true or false
values
CREATE TABLE
You can find the exact syntax of the CREATE TABLE command
in the documentation, or view command-line help right in
psql:
INSERT 0 4
Data Retrieval
Simple Queries
To read data from tables, use the SQL operator SELECT. For
example, let’s display two columns of the courses table. The
AS clause allows you to rename the column if required:
The result can contain several rows with the same data. Even
if all rows in the original table are different, the data can
appear duplicated if not all the columns are displayed:
Joins
In this example, the result does not include any rows of the
table specified on the left side of the join clause if they have
no pair in the right table: although the condition is applied
to the subjects, the students that did not take the exam in
this subject are also excluded. To include all the students
into the result, we have to use the outer join:
Note that the rows of the left table that don’t have a counter-
part in the right table are added to the result (that’s why the
operation is called LEFT JOIN). The corresponding values of
the right table are NULL in this case.
name | score
--------+-------
Anna | 5
Victor | 4
(2 rows)
Subqueries
test=# SELECT *
FROM exams
WHERE (SELECT start_year FROM students
WHERE students.s_id = exams.s_id) > 2014;
s_id | c_no | score
------+-------+-------
1556 | CS301 | 5
(1 row)
Let’s display all the students who have any scores in the
specified course:
name | start_year
--------+------------
Victor | 2014
(1 rows)
Note that this query result can also include those students
who have not received any scores at all.
name | start_year
--------+------------
Victor | 2014
(1 rows)
48 For more details, see the documentation: postgrespro.com/
iv doc/functions-subquery.
name | score
------+-------
Anna | 5
Nina | 5
(2 rows)
Grouping
Let’s select the names of the students who got more than
one excellent score (5), in any course:
test=# SELECT students.name 51
FROM students, exams iv
WHERE students.s_id = exams.s_id AND exams.score = 5
GROUP BY students.name
HAVING count(*) > 1;
name
------
Anna
(1 row)
For example, let’s double the number of lecture hours for the
“Databases” course:
test=# \d students
Table "public.students"
Column | Type | Modifiers
------------+---------+----------
s_id | integer | not null
name | text |
start_year | integer |
g_no | text |
...
You can also get the list of all the tables available in the 53
database: iv
test=# \d
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | courses | table | postgres
public | exams | table | postgres
public | groups | table | postgres
public | students | table | postgres
(4 rows)
Now let’s create a new group called “A-101,” move all the
students into this group, and make Anna its monitor.
test=# BEGIN;
BEGIN
Will the second session see the changes made in the first
session?
postgres=# \c test
You are now connected to database "test" as user
"postgres".
test=# SELECT * FROM groups;
g_no | monitor
------+---------
(0 rows)
test=*# COMMIT;
COMMIT
\l List of databases.
test=# \q
V Demo Database
Overview
Flights
# flight_id
Tickets flight_no
Ticket_flights
∗
scheduled_departure Aircrafts
# ticket_no
∗
# ticket_no scheduled_arrival
book_ref # aircraft_code
∗
# flight_id departure_airport
∗
passenger_id
∗
fare_conditions arrival_airport
∗ ∗ model
passenger_name
∗ ∗
amount status
∗ ∗ range
contact_data
∗ ∗
aircraft_code
∗
∗
◦ actual_departure
◦ actual_arrival
Boarding_passes
Seats
# ticket_no
# aircraft_code
# flight_id
# seat_no
∗ boarding_no
seat_no
∗ fare_conditions
∗
v
61
1
62
v
Bookings 63
v
To fly with our airline, passengers book the required tickets in
advance (book_date, which must be within one month before
the flight). The booking is identified by its number (book_ref,
a six-position combination of letters and digits).
Tickets
Flight Segments
Each flight segment has its price (amount) and travel class
(fare_conditions).
64 Flights
v
Each flight has a scheduled date and time of departure and ar-
rival (scheduled_departure and scheduled_arrival). The
actual_departure and actual_arrival times may differ
from the scheduled ones: the difference is usually insignifi-
cant, but sometimes can be up to several hours if the flight
is delayed.
• Scheduled
The flight can be booked. This value is set one month
before the planned departure date; at this point, the
information about the flight is entered into the database.
• On Time
The flight is open for check-in (twenty-four hours before
the scheduled departure) and is not delayed.
• Delayed 65
The flight is open for check-in (twenty-four hours before v
the scheduled departure), but is delayed.
• Departed
The aircraft has already departed and is airborne.
• Arrived
The aircraft has reached the point of destination.
• Cancelled
The flight is cancelled.
Airports
Boarding Passes
Seats
Flights View
• flight duration
scheduled_duration, actual_duration
Routes View
• edu.postgrespro.com/demo-small-en.zip
A small database with flight data for one month (21 MB,
DB size is 280 MB).
• edu.postgrespro.com/demo-medium-en.zip
A medium database with flight data for three months
(62 MB, DB size is 702 MB).
• edu.postgrespro.com/demo-big-en.zip
A large database with flight data for one year
(232 MB, DB size is 2638 MB).
$ sudo su - postgres
$ wget https://edu.postgrespro.com/demo-small-en.zip
Then run the following command: 69
v
$ zcat demo-small-en.zip | psql
postgres# \i demo-small-en-20170815.sql
If the file is not found, check the “Start in” property of the
shortcut; the file must be located in this directory.
Sample Queries
postgres=# \c demo
You are now connected to database "demo" as user
"postgres".
now
------------------------
2017-08-15 18:00:00+03
(1 row)
airport_code | city
--------------+---------------
YKS | Yakutsk
MJZ | Mirnyj
KHV | Khabarovsk
PKC | Petropavlovsk
(4 rows)
The contents of the database is provided in English and in 71
Russian. You can switch between these languages by setting v
the bookings.lang parameter to en or ru, respectively. By
default, the English language is selected. You can change
this setting as follows:
ALTER DATABASE
demo=# \c
airport_code | city
--------------+--------------------------
YKS | Якутск
MJZ | Мирный
KHV | Хабаровск
PKC | Петропавловск-Камчатский
(4 rows)
SELECT t.passenger_name,
b.book_date
FROM bookings b
JOIN tickets t
ON t.book_ref = b.book_ref
JOIN boarding_passes bp
ON bp.ticket_no = t.ticket_no
JOIN flights f
ON f.flight_id = bp.flight_id
WHERE f.departure_airport = 'SVO'
AND f.arrival_airport = 'OVB'
AND f.scheduled_departure::date =
bookings.now()::date - INTERVAL '2 day'
AND bp.seat_no = '1A';
SELECT count(*)
FROM
(
SELECT s.seat_no
FROM seats s
WHERE s.aircraft_code = (
SELECT aircraft_code
FROM flights
WHERE flight_no = 'PG0404'
AND scheduled_departure::date =
bookings.now()::date - INTERVAL '1 day'
)
EXCEPT
SELECT bp.seat_no
FROM boarding_passes bp
WHERE bp.flight_id = (
SELECT flight_id
FROM flights
WHERE flight_no = 'PG0404'
AND scheduled_departure::date =
bookings.now()::date - INTERVAL '1 day'
)
) t;
74 Problem. Which flights had the longest delays? Print the list
v of ten “leaders.”
SELECT f.flight_no,
f.scheduled_departure,
f.actual_departure,
f.actual_departure - f.scheduled_departure
AS delay
FROM flights f
WHERE f.actual_departure IS NOT NULL
ORDER BY f.actual_departure - f.scheduled_departure
DESC
LIMIT 10;
You can define the same condition using the status column
by listing all the applicable statuses. Or you can skip the
WHERE condition altogether by specifying the DESC NULLS
LAST sorting order, so that undefined values are returned at
the end of the selection.
Aggregate Functions
Solution. Use the fact that boarding pass numbers are issued
in the check-in order.
SELECT t.passenger_name,
t.ticket_no
FROM tickets t
JOIN boarding_passes bp
ON bp.ticket_no = t.ticket_no
GROUP BY t.passenger_name,
t.ticket_no
HAVING max(bp.boarding_no) = 1
AND count(*) > 1;
Window Functions
SELECT tf.ticket_no,
f.departure_airport,
f.arrival_airport,
f.scheduled_arrival,
lead(f.scheduled_departure) OVER w
AS next_departure,
lead(f.scheduled_departure) OVER w -
f.scheduled_arrival AS gap
FROM bookings b
JOIN tickets t
ON t.book_ref = b.book_ref
JOIN ticket_flights tf
ON tf.ticket_no = t.ticket_no
JOIN flights f
ON tf.flight_id = f.flight_id
WHERE b.book_date =
bookings.now()::date - INTERVAL '7 day'
WINDOW w AS (PARTITION BY tf.ticket_no
ORDER BY f.scheduled_departure);
As you can see, the time cushion between flights can reach 77
up to several days: round-trip tickets and one-way tickets v
are treated in the same way, and the time of the stay in the
point of destination is treated just like the time between con-
necting flights. Using the solution for one of the problems in
the “Arrays” section, you can take this fact into account when
building the query.
SELECT passenger_name,
round( 100.0 * cnt / sum(cnt) OVER (), 2)
AS percent
FROM (
SELECT passenger_name,
count(*) cnt
FROM tickets
GROUP BY passenger_name
) t
ORDER BY percent DESC;
Problem. Solve the previous problem for first names and last
names separately.
Arrays
Recursive Queries
Solution. We can take the previous query as the basis for the
solution. However, the first iteration must now contain all
the possible airport pairs, not just a single pair: each airport
must be connected to all the other airports. For all these pairs
of airports we first find the shortest path, and then select the
longest of them.
WITH RECURSIVE p(
departure,
last_arrival,
destination,
hops,
found
) AS (
SELECT a_from.airport_code,
a_from.airport_code,
a_to.airport_code,
array[a_from.airport_code],
a_from.airport_code = a_to.airport_code
FROM airports a_from,
airports a_to
UNION ALL
SELECT p.departure,
r.arrival_airport,
p.destination,
(p.hops || r.arrival_airport)::char(3)[],
bool_or(r.arrival_airport = p.destination)
OVER (PARTITION BY p.departure, p.destination)
FROM p JOIN routes r
ON r.departure_airport = p.last_arrival
WHERE NOT r.arrival_airport = ANY(p.hops)
AND NOT p.found
)
SELECT max(cardinality(hops)-1)
FROM p
WHERE p.last_arrival = p.destination;
This query also uses the found attribute, but here it should 83
be calculated separately for each pair of airports. v
WITH RECURSIVE p(
last_arrival,
destination,
flights,
flight_time,
min_time
) AS (
SELECT a_from.airport_code,
a_to.airport_code,
array[]::char(6)[],
interval '0',
NULL::interval
FROM airports a_from,
airports a_to
WHERE a_from.airport_code = 'UKX'
AND a_to.airport_code = 'CNN'
UNION ALL
SELECT r.arrival_airport,
p.destination,
(p.flights || r.flight_no)::char(6)[],
p.flight_time + r.duration,
least(
p.min_time, min(p.flight_time+r.duration)
FILTER (
WHERE r.arrival_airport = p.destination
) OVER ()
)
FROM p
JOIN routes r
ON r.departure_airport = p.last_arrival
WHERE p.flight_time + r.duration <
coalesce(p.min_time, INTERVAL '1 year')
) CYCLE last_arrival SET is_cycle USING hops
84 SELECT hops,
v flights,
flight_time
FROM (
SELECT hops,
flights,
flight_time,
min(min_time) OVER () min_time
FROM p
WHERE p.last_arrival = p.destination
) t
WHERE flight_time = min_time;
A Separate User
appdb=>
Note that the database name is not the only thing that has
changed in the prompt: instead of the hash symbol (#), the
greater than sign is displayed (>). The hash symbol indicates
the superuser rights, similar to the root user in Unix.
The app user can work with the database without any restric-
tions. For example, this user can create a table:
CREATE TABLE
INSERT 0 1
Remote Connections
In our example, both the client and the database are located
on the same system. Clearly, you can install PostgreSQL
onto a separate server and connect to it from a different
system (for example, from an application server). In this
case, you must specify your database server address instead
of localhost. But it is not enough: for security reasons,
PostgreSQL only allows local connections by default.
To connect to the database from the outside, you must edit 89
two files. vi
#listen_addresses = 'localhost'
listen_addresses = '*'
To allow the app user to access the appdb database from any
address upon providing a valid password, add the following
line to the end of the pg_hba.conf file:
You can install PHP for Windows from the PHP website:
windows.php.net/download. The extension for PostgreSQL
is already included into the binary distribution, but you
must find and uncomment (by removing the semicolon) the
following line in the php.ini file:
;extension=php_pgsql.dll
<?php
$conn = pg_connect('host=localhost port=5432 ' .
'dbname=appdb user=app ' .
'password=p@ssw0rd') or die;
$query = pg_query('SELECT * FROM greeting') or die;
while ($row = pg_fetch_array($query)) {
echo $row[0].PHP_EOL;
}
pg_free_result($query);
pg_close($conn);
?>
$ php test.php
Hello, world!
There are several Perl builds for Windows, which are listed
at perl.org/get.html. Popular builds of ActiveState Perl and
Strawberry Perl already include the driver required for Post-
greSQL.
use DBI;
use open ':std', ':utf8';
my $conn = DBI->connect(
'dbi:Pg:dbname=appdb;host=localhost;port=5432',
'app','p@ssw0rd') or die;
my $query = $conn->prepare('SELECT * FROM greeting');
$query->execute() or die;
while (my @row = $query->fetchrow_array()) {
print @row[0]."\n";
}
$query->finish();
$conn->disconnect();
$ perl test.pl
Hello, world!
import psycopg2
conn = psycopg2.connect(
host='localhost', port='5432', database='appdb',
user='app', password='p@ssw0rd')
cur = conn.cursor()
cur.execute('SELECT * FROM greeting')
rows = cur.fetchall()
for row in rows:
print row[0]
conn.close()
$ python3 test.py
Hello, world!
Java 95
vi
In Java, databases are accessed via the JDBC interface. We
are going to install Java SE 11; additionally, we will need a
package with the JDBC driver:
import java.sql.*;
public class Test {
public static void main(String[] args)
throws SQLException {
Connection conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/appdb",
"app", "p@ssw0rd");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(
"SELECT * FROM greeting");
while (rs.next()) {
System.out.println(rs.getString(1));
}
rs.close();
st.close();
conn.close();
}
}
Hello, world!
Backup
Although our database contains only one table, it’s still worth
taking care of data durability. While your application has
little data, the easiest way to create a backup is to use the
pg_dump utility:
$ createdb appdb2
$ pg_basebackup -D backup
Here we’ll cover only some of the basic settings that must
be considered for a production-level database system. Fine-
tuning for a particular application requires additional knowl-
edge, which you can get, for example, in PostgreSQL database
administration courses (see p. 145).
Instead of changing the file in a text editor, you can set the
parameter value using an SQL command (it also requires the
server configuration to be reloaded):
shared_buffers = '8GB'
effective_cache_size = '24GB'
work_mem = '128MB'
maintenance_work_mem = '512MB'
random_page_cost = 1.2
Connection Settings
Configuration Parameters
Connection Settings
ALTER ROLE
108 In configuration settings
vii of the 1C information
database, specify the
IP-address and port of
the PostgreSQL server
as your database server
and choose “PostgreSQL”
as the required DBMS
type. Specify the name of
the database that will be
used for 1C and select the
“Create database if none
present” check box (do
not create this database
using PostgreSQL means).
Provide the name and
password of a superuser
role that will be used to establish connections.
Installation
Connecting to a Server
If you don’t want to enter the password every time, select the
Save password check box. Passwords are encrypted using a
master password, which you are prompted to enter when you
start pgAdmin for the first time.
When you click the Save button, the application checks that
the server with the specified parameters is available, and
registers a new connection.
111
viii
Browser
The left pane displays the Browser tree. As you expand its
objects, you can get to the server, which we have called
LOCAL. At the next level, you can see all its databases:
If you expand the Schemas item for the appdb database, you
can find the greetings table that we have created, view its
columns, integrity constraints, indexes, triggers, etc.
For each object type, the context (right-click) menu lists all
the possible actions, for example: export to a file, load from
a file, assign privileges, delete.
Running Queries
Enter your query in the upper part of the window and press
F5. The Data Output tab in the lower part of the window will
display the result of the query.
114 To type in the next query, you do not have to delete the
viii previous one: just select the required code fragment before
pressing F5. Thus, the whole history of your actions will be
always in front of you. It is usually more convenient than
searching for the required query in the log on the Query
History tab.
Other Features
Full-Text Search
CREATE TABLE
Now let’s enter the text of the first lectures for our courses 117
CS301 and CS305: ix
INSERT 0 3
-[ RECORD 1 ]-----------------------------------------
no | I
ch_title | Databases
txt | We start our acquaintance with the
fascinating world of databases
-[ RECORD 2 ]-----------------------------------------
no | II
ch_title | First Steps
txt | Getting more fascinated with the world of
databases
-[ RECORD 3 ]-----------------------------------------
no | I
ch_title | Local Networks
txt | Here we start our adventurous journey
through the intriguing world of networks
Now let’s find some information in our database with the help
of traditional SQL means (using the LIKE operator):
118 test=# SELECT ch_no AS no, ch_title, txt
ix FROM course_chapters
WHERE txt LIKE '%fascination%' \gx
The query
will return the row from chapter II (but not from chapter I,
where the adjective “fascinating” is used):
-[ RECORD 1 ]-----------------------------------------
no | II
ch_title | First Steps
txt | Getting more fascinated with the world of
databases
You can check that the query 'fascinated & database' and
its other grammatical variants will return the same result.
Here we have used the comparison operator @@, which plays
the same role in full-text search as the LIKE operator does in
regular search. The syntax of the @@ operator does not allow
natural language expressions with spaces, so words in the
query are connected by the “and” logical operator.
The {0.1, 0.0, 1.0, 0.0} array sets the weights. It is an optional
argument of the ts_rank_cd function. By default, array {0.1,
0.2, 0.4, 1.0} corresponds to D, C, B, A. The word’s weight affects
ranking of the returned row.
-[ RECORD 1 ]-----------------------------------------
ts_headline | with the fascinating <b>world</b> of
databases
-[ RECORD 2 ]-----------------------------------------
ts_headline | with the <b>world</b> of databases
-[ RECORD 3 ]-----------------------------------------
ts_headline | through the intriguing <b>world</b> of
networks
Once the initial shock had passed, it became clear that for
most real tasks such a simple structure was insufficient.
Composite keys were introduced, and then groups of keys
appeared. Relational database systems didn’t want to fall
behind and started adding new features that were typical of
NoSQL.
The new query only returns Nina, whose merits are real.
However, this method does not always work. Let’s try to find
out which guitars our musician Victor plays:
name | Victor
details | { "hobbies": +
| { "guitarist": +
| { "band": "Postgressors", +
| "guitars":["Strat","Telec"] +
| } +
| } +
| }
To get to guitars, let’s use the #> operator and go down the
hierarchy, starting with “hobbies”:
The json type has a younger sibling: jsonb. The letter “b” im-
plies the binary (rather than text) format of data storage and
structure, which can often result in faster search. Nowadays,
jsonb is used much more frequently than json.
-[ RECORD 1 ]--------------------------------------
de_id | 1
details_b | {"flaws": "immoderate ice cream
consumption", "merits": "none"}
-[ RECORD 2 ]--------------------------------------
de_id | 2
details_b | {"hobbies": {"guitarist": {"guitars":
["Strat", "Telec"], "band":
"Postgressors"}}}
-[ RECORD 3 ]--------------------------------------
de_id | 3
details_b | {"hobbies": "cosplay", "merits":
{"mother-of-five": {"Basil": "m",
"Lucie": "f", "Alex": "unknown",
"Mark": "m", "Simon": "m"}}}
-[ RECORD 4 ]--------------------------------------
de_id | 4
details_b | {"status": "expelled"}
For example, let’s find the entry that mentions Lucie, a moth-
er-of-five’s daughter:
-[ RECORD 1 ]-------------------------------------
name | Nina
jsonb_each | (hobbies,"""cosplay""")
-[ RECORD 2 ]-------------------------------------
name | Nina
jsonb_each | (merits,"{""mother-of-five"":
{""Alex"": ""unknown"", ""Mark"":
""m"", ""Basil"": ""m"", ""Lucie"":
""f"", ""Simon"": ""m""}}")
To learn more about json and jsonb types and the functions
to be used with them, see the PostgreSQL documentation
at postgrespro.com/doc/datatype-json and postgrespro.com/
doc/functions-json.
Using this query language, you can, for example, search for
data by its path. The dot notation represents the hierarchy
inside jsonb:
test=# SELECT *
FROM student_details
WHERE details::jsonb @@
'hobbies.guitarist.band=Postgressors'::jsquery;
But it’s still very hard to work with the required value without
knowing the hierarchy.
When the SQL:2016 standard was published, which included 131
the SQL/JSON Path language, Postgres Professional devel- ix
oped its implementation, providing the jsonpath type and
several functions for working with JSON using this language.
These features were committed to PostgreSQL 12.
This query searches only through the JSON branch that begins
with the “hobbies” key, checking whether the corresponding
value equals “cosplay.” But if we replace “cosplay” with
“guitarist,” the query won’t return anything because “guitarist”
is used in our table as a key, not as a value of the nested
element.
s_id | jsonb_path_query
------+------------------
1432 | "Postgressors"
(1 row)
In the first example, we defined a filter expression for each 133
entry within the “hobbies.guitarist.band” branch. If we take ix
a look at the JSON itself, we can see that this branch has only
one value: “Postgressors”. So there was actually nothing to
filter out. In the second example, the filter is applied one
step higher, so we have to specify the path to the “group”
within the filter expression; otherwise, the filter won’t find
any values. If we use such syntax, we have to know the JSON
hierarchy in advance. But what if we don’t know the hier-
archy?
s_id | jsonb_path_exists
------+-------------------
1451 | f
1432 | t
1556 | f
1451 | f
(4 rows)
Installing Extensions
Foreign data wrappers for Oracle, MySQL, and SQL Server are
available as extensions:
• Oracle — github.com/laurenz/oracle_fdw;
• MySQL — github.com/EnterpriseDB/mysql_fdw;
• SQL Server — github.com/tds-fdw/tds_fdw.
-[ RECORD 1 ]---+-----------
name | oracle_fdw
default_version | 1.2
Oracle
CREATE EXTENSION
test=# \dew
CREATE SERVER
CREATE SCHEMA
Now let’s import some foreign tables. We’ll do it for just two
popular tables, dept and emp:
-[ RECORD 1 ]----------
emp_no | 10001
birth_date | 1953-09-02
first_name | Georgi
last_name | Facello
gender | M
hire_date | 1986-06-26
Just like the Oracle wrapper, mysql_fdw allows both read and
write operations.
SQL Server
CREATE EXTENSION
CREATE SERVER
You can display the list of imported tables using the \det
command, or find them in the system catalog by running the
following query:
PostgreSQL
CREATE EXTENSION
CREATE SERVER
There is no need to specify the password if you create a user 143
mapping within a single cluster: ix
Documentation
DBA1
Basic PostgreSQL
administration
DEV1
Basic server-side
application development
DEV2 QPT
Advanced server-side Query perfor-
application development mance tuning
Topics:
Basic toolkit
1. Installation and server management
2. Using psql
3. Configuration
Architecture
4. PostgreSQL overview
5. Isolation and multi-version concurrency control
6. Vacuum
7. Buffer cache and write-ahead log
Data management
8. Databases and schemas
9. System catalog
10. Tablespaces
11. Low-level details
Administration tasks 149
12. Monitoring x
Access control
13. Roles and attributes
14. Privileges
15. Row-level security
16. Connection and authentication
Backups
17. Overview
Replication
18. Overview
Duration: 4 days
SQL fundamentals.
Good command of Unix OS.
Familiarity with PostgreSQL within the scope of the DBA1
course.
Topics:
Logging
8. Buffer cache
9. Write-ahead log
10. Checkpoints
11. WAL configuration
Locking
12. Object locks
13. Row-level locks
14. Memory locks
Administration tasks
15. Managing extensions
16. Localization
17. Server upgrades
SQL fundamentals.
Good command of Unix OS.
Familiarity with PostgreSQL within the scope of the DBA1
course.
Taking backups.
Setting up physical and logical replication.
Recognizing replication use cases.
Understanding cluster technologies.
Topics:
Backups
1. Logical backup
2. Base backup
3. WAL archive
Replication
4. Physical replication
5. Switchover to a replica
6. Logical replication
7. Usage scenarios
Cluster Technologies
8. Overview
SQL fundamentals.
Experience with any procedural programming language.
Basic knowledge of Unix OS.
Topics:
Basic toolkit
1. Installation and server management, psql
Architecture
2. A general overview of PostgreSQL
3. Isolation and MVCC
4. Buffer cache and WAL
Data organization
5. Logical structure
6. Physical structure
Bookstore application
7. Application schema and interface
SQL
8. Functions
9. Procedures 153
10. Composite types x
PL/pgSQL
11. Overview and programming structures
12. Executing queries
13. Cursors
14. Dynamic commands
15. Arrays
16. Error handling
17. Triggers
18. Debugging
Access control
19. Access control overview
Backup
20. Logical backup
Duration: 4 days
Topics:
Architecture
1. Isolation
2. Server internals
3. Vacuum
4. Write-ahead logging
5. Locks
Bookstore
6. Bookstore application 2.0
Extensibility
7. Connection pooling
8. Data types for large values
9. User-defined data types
10. Operator classes
11. Semi-structured data
12. Background processes
13. Asynchronous processing
14. Creating extensions
15. Programming languages
16. Aggregate and window functions
17. Full-text search
18. Physical replication
19. Logical replication
20. Foreign data
Topics:
1. Airlines database
2. Query execution
3. Sequential scans
4. Index scans
5. Bitmap scans
9. Statistics
• PostgreSQL internals.
• Server setup and monitoring, database maintenance
tasks.
• Performance optimization tasks, query tuning.
• Taking backups.
• Physical and logical replication setup for various usage
scenarios.
While taking the test, you can refer to our course materials
and the PostgreSQL documentation, but usage of any other
sources of information is prohibited.
Academic Courses
SQL Basics
ISBN 978-5-9775-4022-3
Contents:
Introduction
Configuring the environ-
ment
Basic operations
Data types
DDL fundamentals
Queries
Data manipulation
Indexes
Transactions
Performance tuning
160 A soft copy of this book in Russian is available on our website:
x postgrespro.ru/education/books/sqlprimer.
ISBN 978-5-97060-841-8
Contents:
Introduction
Some database theory
Getting started with databases
Introduction to SQL
Database access management
Transactions and data consistency
Database application development
Relational model extensions
Various types of database systems
162 Part II. From Practice to Proficiency
x
Database system architecture
Storage structures and the main algorithms
Query execution and optimization
Transaction management
Database reliability
Advanced SQL features
Database functions and procedures
PostgreSQL extensibility
Full-text search
Data security
Database administration
Replication
Parallel and distributed database systems
Books
PostgreSQL Internals
This book is for those who will not settle for a black-box
approach when working with a database. Targeted at readers
who have some experience with PostgreSQL, this book will
also be useful for those who are familiar with another
database system but switch over to PostgreSQL and would
like to understand how they differ.
Contents:
Introduction
Mailing Lists
Having signed up for any of these lists, you will start receiving
regular emails and will be able to participate in discussions
if you like. Another option is to browse through the email
archive at postgresql.org/list or on our company’s website 169
(postgrespro.com/list). xi
Commitfest
This way, you can stay informed about new features already
included into PostgreSQL or planned for the next release.
Conferences
Contact information:
Postgres Training
postgrespro.com/community/books/introbook
ISBN 978-5-6045970-3-3