Lesson 5 / 28

Creating a Table With a vector Column

Enable the extension and store vectors next to ordinary columns.

A normal table with one special column

In PostgreSQL you enable pgvector with CREATE EXTENSION vector;, then declare a column of type vector(n) with the number of dimensions your embedding model produces. The row can also hold the text, tenant, year and anything else, so one query can use both vector similarity and relational conditions, and a transaction can update the document and its vector together. Vectors are written as text literals such as '[0.9, 0.1, 0.0]' or passed as arrays by your driver. The dimension is checked: inserting a vector of the wrong length is an error, which protects you from mixing models. The demo uses 3 dimensions so you can read the numbers; real embeddings use hundreds.

SQL with a distance operator

pgvector adds a vector type, distance operators and ANN indexes to PostgreSQL, so you search with plain SQL.

Four pieces: type, operators, filters, transactions.
Figure 2.1 — Type, operators, filters and transactions.

Create a table and insert five rows, run

I ran this SQL on PostgreSQL 16 with the pgvector extension, version 0.8.6, in a Docker container. The table mixes ordinary columns (tenant, year, body) with a vector(3) column. Five rows go in, including a row from another tenant (beta) and an old 2022 document.

SET client_min_messages = warning;
DROP TABLE IF EXISTS docs;
CREATE TABLE docs (
  id        serial PRIMARY KEY,
  tenant    text NOT NULL,
  year      int  NOT NULL,
  body      text NOT NULL,
  embedding vector(3) NOT NULL
);
INSERT INTO docs (tenant, year, body, embedding) VALUES
 ('acme', 2025, 'leave policy 2025',      '[0.9, 0.1, 0.0]'),
 ('acme', 2022, 'old leave policy',       '[0.8, 0.2, 0.1]'),
 ('acme', 2025, 'travel and hotels',      '[0.1, 0.9, 0.1]'),
 ('beta', 2025, 'beta confidential memo', '[0.9, 0.0, 0.2]'),
 ('acme', 2025, 'security basics',        '[0.0, 0.1, 0.9]');
SELECT id, tenant, year, body FROM docs ORDER BY id;

Output:

 id | tenant | year |          body          
----+--------+------+------------------------
  1 | acme   | 2025 | leave policy 2025
  2 | acme   | 2022 | old leave policy
  3 | acme   | 2025 | travel and hotels
  4 | beta   | 2025 | beta confidential memo
  5 | acme   | 2025 | security basics
(5 rows)

Keep the text beside the vector

Storing the original chunk text in the same row lets you show results without a second lookup.

Quick check: What happens if you insert a vector of the wrong dimension into a vector(3) column?

  • It is silently padded
  • An error is raised
  • It is stored as text
  • The database restarts
Answer

An error is raised — Dimension checks catch mixing of embedding models early.