Glossary

PostgreSQL

PostgreSQL is a relational database management system for data integrity, transactions, and more complex queries. JSONB does not turn it into a catch-all document store.

Short definition

A source of truth for relationships, rules, and transactional changes.

PostgreSQL stores data in tables with rows and columns, but its essential advantage is not merely their tabular shape. Primary and foreign keys, unique constraints, check rules, transactions, and indexes can protect relationships among an order, its items, a payment, a customer, and external identifiers even under concurrency.

In an online store or internal system, the database can protect invariants at the final boundary shared by imports, console commands, and concurrent requests. An ORM simplifies how the application works with data, but does not replace thoughtful relational design, constraints, or measurement of real queries.

Use cases

Where relational data needs integrity

PostgreSQL is used for data that requires clear relationships, history, and atomic changes.

  • orders, line items, payments, refunds, and accounting relationships
  • products, variants, prices, inventory, and reservations
  • users, organisations, roles, and internal documents
  • idempotent imports with a unique external identifier
  • relational data complemented by a flexible JSONB payload from an external API

Practical example

A marketplace order in one transaction

The importer stores marketplace, external_order_id, status, and the original payload in JSONB. A unique constraint on the marketplace and external_order_id pair prevents two parallel retries from creating the same order. The order, its items, and an integration record are stored in one transaction.

A foreign key protects the relationship between items and the order, while an index on status and time supports a common administration view. If a step fails, rollback reverts all local changes. JSONB is indexed only when real queries frequently search inside the external payload.

CREATE TABLE marketplace_order (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  marketplace text NOT NULL,
  external_order_id text NOT NULL,
  status text NOT NULL,
  payload jsonb NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT marketplace_order_external_key
    UNIQUE (marketplace, external_order_id)
);

CREATE INDEX marketplace_order_status_created_idx
  ON marketplace_order (status, created_at DESC);

How it works

From the schema to commit or rollback

The database combines data design, rules, and concurrent transactional execution.

  1. Schema Tables, types, identity columns, relationships, and constraints define the permitted state of the data.
  2. Constraints and indexes UNIQUE, FOREIGN KEY, CHECK, and NOT NULL protect rules; indexes support specific queries at a cost to writes and storage.
  3. Transactions Group related changes into an atomic unit. COMMIT makes them visible, while ROLLBACK discards them.
  4. MVCC Multiversion concurrency control gives queries a consistent view and reduces blocking between reads and writes.
  5. Planner and operations The planner considers statistics and indexes; autovacuum, backups, recovery, and monitoring long-running transactions are part of operations.

Important concepts

Data rules should be expressed where they apply.

Application validation matters to users; database rules also protect state during concurrency.

Keys and constraints

PRIMARY KEY identifies a row, FOREIGN KEY maintains a reference, UNIQUE prevents duplication, and CHECK enforces a rule over the given row. Not every business relationship can be expressed with one CHECK.

Transactions and isolation

The default READ COMMITTED level gives each statement a view of data committed before it began. Higher isolation levels have different trade-offs and may require retrying a transaction after a serialisation conflict.

Indexes and the planner

B-tree is common for equality, ranges, and ordering; GIN, GiST, SP-GiST, and BRIN are also available. An index is not an automatic optimisation: it changes write performance and should be evaluated with EXPLAIN.

JSONB

JSONB stores decomposed JSON that can be indexed. It suits a flexible payload, but should not be used to hide key relationships, identifiers, and rules in a single column.

Benefits and limitations

Powerful rules and queries also have an operational cost.

Benefits

  • data integrity through keys, constraints, and transactions
  • concurrency through MVCC and rich data types
  • several indexing strategies for real queries
  • combining a relational model with a flexible JSONB payload

Risks

  • long-running transactions complicate cleanup of old row versions
  • unnecessary indexes slow writes and consume space
  • JSONB can hide relationships, validation, and targeted indexing
  • validation only in the application does not protect a concurrent import or another service

Scope of use

Relational design is not an obstacle; it is a deliberate way of handling the reality of data.

PostgreSQL is a natural choice for orders, payments, inventory, and integration states where a broken relationship or duplicate costs more than a precisely named column and constraint. A different data store may be more suitable for small local data or another access pattern.

A database does not solve every process spanning multiple systems. Transactions protect local changes; event delivery, external APIs, and retries need their own design. For a critical change, it is worth combining a constraint, transaction boundary, monitoring, and an idempotent integration.

What to keep in mind

Measure and enforce integrity at the right boundary.

The data model should reflect real queries and risks, not the database feature catalogue.

  • PRIMARY KEY, FOREIGN KEY, UNIQUE, and NOT NULL for important invariants
  • short transactions with a clear boundary and conflict handling
  • indexes based on EXPLAIN and a measured workload, not on every column
  • JSONB only for flexible supplementary data, with specific queries and indexes
  • backups, recovery, and monitoring of autovacuum and long-running transactions

Common questions

What PostgreSQL does and does not solve

Does JSONB replace relational design?

No. It suits flexible supplementary data, such as a payload from an external API. Key relationships and rules are usually better expressed through columns and constraints.

Why isn’t validation in a form or API enough?

A change can come from an import, console command, or concurrent request. A database constraint protects state at the final shared boundary.

Is every query without an index a mistake?

No. A sequential scan can be the right choice for a small table or a filter with poor selectivity. The plan and measured behaviour decide.

Does MVCC solve every concurrency conflict?

No. It provides consistent snapshots and reduces blocking, but a business conflict still needs the right transaction, constraint, or targeted locking.

How I design data in practice

I use database rules as part of a reliable process.

In e-commerce and integrations, I design the relational model, transactions, constraints, efficient queries, and traceability of data changes.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.