08 Lesson 08: Data Organization / Databases and Schemas
This page is extracted from the official PDF into native Markdown. Slide text, code and speaker notes are kept in reading order; the original PDF and HTML remain the layout references. HTML source: dba1_08_data_databases.html Archive: DBA1-handouts-16-en.zip PDF pages: 24
Page 1: Data Organization / Databases and Schemas
Copyright
© Postgres Professional, 2017–2025 Authors: Egor Rogov, Pavel Luzanov, Ilya Bashtanov, Aleksei Beresnev Translated by: Liudmila Mantrova, Alexander Meleshko, Elena Sharafutdinova Photo: Oleg Bartunov (Phu Monastery and Bhrikuti Peak, Nepal)
Use of Course Materials
Non-commercial use of course materials (presentations, demonstrations) is allowed without restrictions. Commercial use is possible only with the written permission of Postgres Professional. It is prohibited to make changes to the course materials.
Feedback
Please send your feedback, comments and suggestions to: edu@postgrespro.ru
Disclaimer
Postgres Professional assumes no responsibility for any damages and losses, including loss of income, caused by direct or indirect, intentional or accidental use of course materials. Postgres Professional company specifically disclaims any warranties on course materials. Course materials are provided “as is,” and Postgres Professional company has no obligations to provide maintenance, support, updates, enhancements, or modifications.
Page 2: Topics
- Databases and Templates
- Schemas and Search Path
- Special Schemas, Temporary Objects
- Managing Databases, Schemas, and Objects
Page 3: Database Cluster
{#source-figure-003 caption=“Source slide page 3: Database Cluster”}
Cluster initialization creates three databases
- A new database is always cloned from an existing one
Speaker notes
A PostgreSQL instance manages a database cluster which comprises multiple databases. When a cluster is initialized, three identical databases are created in a specific way.
https://postgrespro.com/docs/postgresql/16/bki
All other databases created by users are cloned from an existing one.
The template1 database is used by default when creating new databases. Any objects and extensions added to the template will be copied into any database created from it.
The template0 must never be modified. It is required in at least two scenarios. Firstly, it is necessary when restoring a database from a backup created via pg_dump (since the copy will include not only the database objects, but also any objects from template1). Secondly, it is used when creating a new database with an encoding different from the one specified during cluster initialization.
The postgres database is used to connect to by default by the postgres user. It is not a hard requirement to have it, but some utilities expect it to be there, so removing it is not a good idea, even if you never use the database directly.
https://postgrespro.com/docs/postgresql/16/manage-ag-templatedbs
Page 4: Databases
The \l[ist] command shows a list of all databases:
The list includes a fourth database, student, which is not created during cluster initialization. This database was specifically added for course purposes — it allows users to omit the database name when launching psql, as it defaults to a database matching the OS username. You can also view the list of databases in the database itself:
datistemplate — whether the database is a template datallowconn — whether database connections are allowed datconnlimit — maximum number of connections (-1 = unlimited)
Creating a Database from a Template
Connect to the template1 database:
Check if we can use the digest function, which calculates the hash code of a text string:
There is no such function. In fact, the digest function is defined in the pgcrypto extension. Install it:
Now, we can use the functions provided by the pgcrypto extension. For example, the MD5 digest calculation function:
Page 5: Page 5
In order to be used to create a database from, the template must have no active connections. So, disconnect from template1 first.
New databases are created with the CREATE DATABASE command:
A new database can also be created from the OS by using the createdb tool.
Since template1 is the template used by default, the newly created database will have the pgcrypto extension already installed:
Database Management
The created database can be renamed (must have no active connections):
Other parameters can also be changed, such as the maximum number of concurrent connections:
Page 6: Database Size
A database size is shown by the following function:
The output can be displayed in a more readable form:
The database has no user objects so far (except for pgcrypto), so this is the size of an “empty” database.
Page 7: Schemas
Database object namespace
- each object belongs to a schema
- Purposes
- dividing objects into logical groups
- prevent name conflicts between applications
- Schemas and users are different entities
Speaker notes
Schemas are namespaces for database objects. They separate objects into groups for easier management and serve to prevent name conflicts when multiple users or applications access the same database.
Every object that exists in the database belongs to a schema.
In PostgreSQL, schema and user are different entities (although the default settings allow users to conveniently operate schemas of the same name).
https://postgrespro.com/docs/postgresql/16/ddl-schemas
Page 8: Databases and Schemas
{#source-figure-008 caption=“Source slide page 8: Databases and Schemas”}
Speaker notes
A cluster comprises multiple databases. Each database contains various schemas across which database objects are distributed.
There are several standard schemas that exist in any database. More schemas can be added by users.
Clients may connect to only one database at a time, but within the database, the client can work with objects in any schema.
Page 9: Schemas
The psql command (dn = describe namespace) shows a list of schemas in a database:
Create a new schema:
Now create a table (it will get into the public schema by default):
You can get a list of tables with the \dt command:
Objects can be moved between schemas. Since this is the logical level, the moving takes place only in the system catalog; physically, the data remains in place.
Now, the table t can be accessed using its schema name:
Without the schema name, the table is not found.
So, how do you access objects located in various schemas?
Page 10: Page 10
Page 11: Search Path
Determining an object’s schema
- a schema is explicitly defined by a qualified name (schema.name)
- a name without a qualifier is looked up in the schemas specified in the search
- path
- Search path
- defined by the search_path parameter
- non-existent schemas and schemas with restricted access are excluded;
- implicit schemas are included
- the actual value is shown by the current_schemas function
- the first explicitly specified schema in the path is where objects are created
Speaker notes
When specifying an object, the schema it belongs to must be determined, since different schemas may contain objects of the same name.
When the object name is qualified (with the schema name), the object is looked up in the given schema, as shown on the previous slide. If the name is used without a qualifier, PostgreSQL tries to look the name up in one of the schemas listed in the search path, which is determined by the search_path configuration parameter.
The actual search path may differ from the search_path parameter value: any non-existent schemas are excluded, as well as schemas to which the user does not have access (see the Access Control module for details). In addition, some special schemas are implicitly added to the beginning of the search path.
The actual search path, including implicit schemas, is returned by a call to the current_schemas(true) function. The schemas are searched in the order specified in the search path, from left to right. If the desired object name is not found in the first schema, the next one is searched, and so on.
When an object is created with an unqualified name, it is placed into the first explicitly defined schema in the path.
The concept of search_path is similar to the PATH variable in operating systems.
https://postgrespro.com/docs/postgresql/16/ddl-schemas#DDL-SCHEMAS-P ATH
https://postgrespro.com/docs/postgresql/16/runtime-config-client#GUC-SEA RCH-PATH
Page 12: Special Schemas
Public schema
- included in the search path by default
- all objects will belong to this schema, unless configured otherwise
- Schema named after the user
- included in the search path by default but is not created automatically
- if created, the user objects will belong to this schema
- pg_catalog schema
- a schema for system catalog objects
- if not explicitly included in the path, implicitly included as the first one
Speaker notes
There are several special schemas usually present in any database.
The public schema is used by default for storing objects, unless intentionally configured otherwise.
The pg_catalog schema contains system catalog objects. The system catalog is a collection of tables containing metadata about objects belonging to the cluster. information_schema is another schema with an alternative representation of the system catalog (as defined in the SQL standard).
If pg_catalog is not specified in the search path, the schema will be implicitly placed in the front of the path so that system objects remain visible.
Page 13: Search Path
First, let’s find out why the table was created in the public schema. To do that, look at the search path:
Construction “$user” defines the schema with the same name as the current user (in this case, student). Since there is no such schema, it is ignored, and the table is created in public. To avoid the headache of tracking which schemas exist, which do not, and which are not explicitly declared, use the following function:
When the function is called with a true argument, the result includes system schemas (e.g., pg_catalog). We can define the search path, for example:
Now, the table t will be found:
We have just set a configuration parameter at the session level. If we restart the session, it will have reverted to default. Setting it on the cluster level would not be a good solution either, since this path may not be needed often and not by all users. Thankfully, you can set such parameters for a specific database:
Now, it will be applied for all new connections to appdb. Let’s try:
Another function current_schema() returns the first non-system schema name. This identifies the regular schema where new objects will be created by default.
Page 14: Page 14
Page 15: Special Schemas
Temporary tables
- exist for the duration of the session or transaction
- not logged (no recovery after a crash)
- do not utilize the shared buffer cache
- pg_temp_N schema
- created automatically for temporary tables
- pg_temp: a link to a specific temporary schema for the session
- if not explicitly included in the path, implicitly included as the very first one
- at the end of the session, all objects of the temporary schema are dropped;
- the schema itself remains and is reused for other sessions
Speaker notes
PostgreSQL can work with temporary tables. Temporary tables store data that should only be available to the current session and only for as long as the session is active (or even for the duration of a single transaction within the session).
When recovering after a crash, previous sessions do not exist, so temporary tables contents will be lost. Therefore, such tables are unlogged. Additionally, temporary table pages are never stored in the shared buffer cache, residing in the internal memory of their backend process instead. Thanks to that, temporary tables can be accessed a bit more quickly than regular ones.
Temporary tables are organized using schemas. When a session is started, a temporary schema named pg_temp_N (pg_temp_1, pg_temp_2, etc.) is created for it. It can be accessed by the name pg_temp (without a number, the name will always refer to the temporary schema specific for the session).
If pg_temp is not specified in the path, it is searched before all others. Otherwise, you can specify its position in the path explicitly, like with pg_catalog.
After the session ends, all objects belonging to the temporary schema are dropped, and the schema itself remains to be reused later on.
There are other special schemas, more technical in nature.
Page 16: Temporary Tables and pg_temp
Create a temporary table:
The table is created in a special schema. Each session has its own temporary schema, so that sessions cannot access each other’s temporary schemas. But, where did the regular table t disappear? The answer lies in the extended search path. Now, the search path includes the temporary schema, and the object in it “overshadows” the object in the app schema by the same name.
Still, you can access objects in either schema by providing the schema name explicitly. For the temporary table, use the pseudo-schema pg_temp: it will automatically transform to the current session’s pg_temp_N:
Temporary schemas are not limited to just tables.
Temporary schemas and data in them may have different scopes of life (depending on the clauses ON COMMIT DELETE, PRESERVE, and DROP). In any case, all temporary objects are deleted upon reconnecting to a database:
Page 17: Deleting Objects
A schema cannot be deleted as long as any objects remain in it:
But you can delete a schema together with all its objects:
If the database is no longer needed, it can be deleted as well.
Page 18: Takeaways
On the logical level
- cluster contains databases,
- database contains schemas,
- schema contains specific objects (tables, indexes etc.)
- Databases are created by cloning existing ones
- A schema can be specified explicitly or determined using the search path
- Some schemas have specific purposes
Page 19: Practice
- Create a new database and connect to it. 2. Check the size of the created database. 3. Create two schemas. Name one app, and the other after your user name. Create several tables in both schemas and populate them with data. 4. Check how much the database size has increased. 5. Modify the search path variable value so that when connecting to the database, tables from both schemas are accessible by an unqualified name. The “username” schema should have priority.
Page 20: 1. Database
2. Database Size
Save the value in a psql variable:
3. Schemas and Tables
Which schema receives tables created without explicit schema qualification?
student schema tables:
app schema tables:
Page 21: 4. Database Size Change
The size has changed to:
5. Search Path
With the current search path configuration, only student schema tables are visible:
Modify the search path:
Now, tables from both schemas are visible, but student takes priority:
Page 22: Page 22
Page 23: Practice+
- Create a database. For all sessions connecting to this database, set the temp_buffers parameter to four times the default value.
Speaker notes
- Use the command ALTER DATABASE … SET:
https://postgrespro.com/docs/postgresql/16/sql-alterdatabase
More about the temp_buffers parameter:
https://postgrespro.com/docs/postgresql/16/runtime-config-resource#GUC-T EMP-BUFFERS
Page 24: 1. Setting the temp_buffers Parameter
The temp_buffers parameter determines the amount of memory allocated for the local cache for temporary tables during any session. If the temporary tables data does not fit into temp_buffers, the pages are evicted, like with the regular buffer cache. Too low of a value may affect the server performance if temporary tables are used frequently. The default temp_buffers value is 8MB:
Set the value to 32MB for all new sessions:
The parameter changes made by ALTER DATABASE are stored in the pg_db_role_setting table. You can view them in psql with the following command:
Naturally, you do not have to set the temp_buffers parameter just at the database level. For example, you can set them for the whole cluster if you define it in postgresql.conf.