Пошук уроків, статей та іншого контенту
Створіть послідовні правила назв таблиць, колонок, ключів, індексів і схем у PostgreSQL.
Послідовні назви спрощують читання SQL, пошук об’єктів і роботу в команді. У PostgreSQL варто заздалегідь домовитися про формат назв для всіх об’єктів бази даних:
схем;
таблиць;
колонок;
первинних і зовнішніх ключів;
обмежень;
індексів.
Головне правило — однакові назви мають будуватися за однаковими шаблонами в усій базі даних.
Для ідентифікаторів PostgreSQL зручно використовувати:
лише малі латинські літери;
цифри, якщо вони справді потрібні;
символ підкреслення _ для розділення слів;
назви без подвійних лапок.
Наприклад:
customer_id
created_at
order_items
billing_addressНе рекомендується змішувати стилі:
CustomerID
customerId
customer-id
"CustomerId"PostgreSQL автоматично перетворює неекрановані назви на малі літери:
CREATE TABLE customers (
customer_id integer
);Це те саме, що:
CREATE TABLE customers (
customer_id integer
);Але назва в подвійних лапках зберігає регістр:
CREATE TABLE "Customers" (
"CustomerId" integer
);Тепер до таблиці та колонки потрібно звертатися точно з такими самими лапками й регістром:
SELECT "CustomerId"
FROM "Customers";Такі назви ускладнюють написання запитів, тому для звичайних об’єктів краще не використовувати подвійні лапки.
Схема групує пов’язані таблиці та інші об’єкти бази даних.
Для схем використовуйте:
короткі змістовні назви;
нижній регістр;
формат snake_case, якщо назва складається з кількох слів.
Приклади:
app
billing
catalog
reporting
user_managementНазва схеми має описувати предметну область або призначення об’єктів:
billing — рахунки та платежі;
catalog — товари й категорії;
reporting — об’єкти для звітів.
Не варто створювати схеми з неінформативними назвами:
data
new
test2
miscЯкщо таблиця належить до певної схеми, у запитах можна явно вказувати її повне ім’я:
SELECT *
FROM catalog.products;Формат повного імені:
schema_name.object_nameДля таблиць оберіть один із підходів і використовуйте його всюди. Поширений варіант — назви у множині:
customers
products
orders
order_itemsТоді назва таблиці описує набір однотипних записів:
customers — багато клієнтів;
orders — багато замовлень;
order_items — багато позицій замовлень.
Також можна використовувати однину:
customer
product
order
order_itemОбидва підходи допустимі. Важливо не змішувати їх в одній схемі. Наприклад, набір customers, product, orders є непослідовним.
Для таблиць із кількома словами використовуйте snake_case:
order_items
payment_methods
shipping_addressesНе скорочуйте назви без необхідності:
cust
ord
addrЗрозуміла назва зазвичай краща за коротку, але незрозумілу.
Назва колонки має описувати значення, яке вона зберігає.
Для первинного ключа зручно використовувати назву:
<table_name_singular>_idНаприклад:
customer_id
product_id
order_idЯкщо таблиця називається customers, її первинний ключ може називатися customer_id, а не id. Такий підхід робить назви зрозумілими під час об’єднання таблиць:
SELECT
orders.order_id,
orders.customer_id,
customers.email
FROM orders
JOIN customers
ON customers.customer_id = orders.customer_id;У деяких командах для первинних ключів у всіх таблицях використовують просто id. Це також допустимо, якщо правило застосовується послідовно.
Зовнішній ключ зазвичай має назву первинного ключа таблиці, на яку він посилається:
customer_id
product_id
order_idНаприклад, у таблиці orders:
customer_id integer NOT NULLЦе означає, що колонка містить ідентифікатор клієнта.
Не варто використовувати нечіткі назви:
owner
parent
ref
link_idЯкщо зв’язок має особливу роль, її можна відобразити в назві:
created_by_user_id
approved_by_user_id
billing_address_id
shipping_address_idДля колонок типу boolean використовуйте префікси, які показують, що значення є логічним:
is_active
is_verified
has_discount
can_refundНаприклад:
is_active boolean NOT NULL DEFAULT trueНе змішуйте різні форми для одного призначення:
active
is_active
active_flagОберіть одну угоду, наприклад is_..., і дотримуйтеся її.
Для часових колонок використовуйте суфікс _at:
created_at
updated_at
deleted_at
published_atДля значень, що є лише датою без часу, використовуйте суфікс _date:
birth_date
start_date
due_dateДля тривалості або числового значення часу назва має містити одиницю:
timeout_seconds
duration_minutes
retention_daysНазва duration сама по собі не пояснює, у яких одиницях зберігається значення.
Обмеження можна створювати без явної назви, і PostgreSQL згенерує її автоматично. Проте власні назви роблять структуру бази даних зрозумілішою.
Рекомендований шаблон:
<table_name>_pkeyПриклади:
customers_pkey
orders_pkey
order_items_pkeyРекомендований шаблон:
<child_table>_<column>_fkeyПриклади:
orders_customer_id_fkey
order_items_order_id_fkey
order_items_product_id_fkeyТут:
orders — таблиця, що містить зовнішній ключ;
customer_id — колонка;
fkey — позначення foreign key.
Для інших обмежень використовуйте суфікси, що показують їхній тип:
_pkey — первинний ключ;
_fkey — зовнішній ключ;
_key або _uq — унікальне обмеження;
_check або _ck — перевірка значення.
Рекомендовані шаблони:
<table_name>_<column>_key
<table_name>_<column>_uqПриклади:
customers_email_key
products_sku_keyДля CHECK можна використовувати шаблон:
<table_name>_<condition>_checkабо коротший:
<table_name>_<condition>_ckНаприклад:
products_price_positive_check
orders_total_nonnegative_checkНазва має описувати саме правило, а не лише тип обмеження.
Індекс зазвичай називають за таблицею та колонками, які він використовує.
Рекомендований шаблон:
<table_name>_<column_names>_idxПриклади:
customers_email_idx
orders_customer_id_idx
orders_created_at_idx
order_items_order_id_product_id_idxДля унікального індексу можна додати _uidx:
customers_email_uidxОднак якщо унікальність потрібна як правило для даних, зазвичай краще створити UNIQUE-обмеження. PostgreSQL автоматично створить індекс для такого обмеження.
Не використовуйте назви без контексту:
idx1
index_customers
fast_lookupЗ назви індексу має бути зрозуміло:
для якої таблиці його створено;
які колонки він охоплює;
за потреби — що він унікальний або частковий.
Нижче наведено приклад узгоджених назв для схеми, таблиць, колонок, обмежень та індексів.
BEGIN;
-- Видаляємо лише демонстраційну схему, якщо вона вже існує
DROP SCHEMA IF EXISTS naming_demo CASCADE;
CREATE SCHEMA naming_demo;
CREATE TABLE naming_demo.customers (
customer_id integer GENERATED ALWAYS AS IDENTITY,
email text NOT NULL,
full_name text NOT NULL,
is_active boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT customers_pkey PRIMARY KEY (customer_id),
CONSTRAINT customers_email_key UNIQUE (email)
);
CREATE TABLE naming_demo.orders (
order_id integer GENERATED ALWAYS AS IDENTITY,
customer_id integer NOT NULL,
total_amount numeric(12, 2) NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT orders_pkey PRIMARY KEY (order_id),
CONSTRAINT orders_customer_id_fkey
FOREIGN KEY (customer_id)
REFERENCES naming_demo.customers (customer_id),
CONSTRAINT orders_total_amount_nonnegative_check
CHECK (total_amount >= 0)
);
CREATE INDEX orders_customer_id_idx
ON naming_demo.orders (customer_id);
CREATE INDEX orders_created_at_idx
ON naming_demo.orders (created_at);
COMMIT;У цьому прикладі:
naming_demo — назва схеми в нижньому регістрі;
customers і orders — назви таблиць у множині;
customer_id та order_id — ідентифікатори;
created_at — час створення запису;
customers_pkey і orders_pkey — первинні ключі;
orders_customer_id_fkey — зовнішній ключ;
orders_total_amount_nonnegative_check — перевірка значення;
orders_customer_id_idx — індекс для колонки customer_id.
Не використовуйте зарезервовані слова SQL як назви таблиць або колонок:
user
order
group
select
table
whereНаприклад, замість таблиці order краще використати:
orders
customer_orders
sales_ordersЗамість колонки user можна використати:
user_id
customer_id
account_idЯкщо назва конфліктує із зарезервованим словом, PostgreSQL дозволяє взяти її в подвійні лапки:
CREATE TABLE "order" (
"user" text
);Але це створює незручності під час кожного звернення до об’єкта. Краще змінити назву, а не покладатися на лапки.
PostgreSQL має обмеження на довжину ідентифікаторів — 63 байти. Надто довгі назви можуть бути автоматично обрізані.
Наприклад, дві різні довгі назви після обрізання можуть стати однаковими. Тому назви мають бути:
достатньо змістовними;
достатньо короткими;
без повторення зайвих слів.
Краще:
orders_customer_id_fkeyніж надмірно деталізована назва, яка повторює всю бізнес-логіку правила.
CREATE TABLE CustomerOrders (...);
CREATE TABLE customer_orders (...);Такі назви виглядають як об’єкти з різними правилами. Використовуйте один стиль:
CREATE TABLE customer_orders (...);customers
product
ordersОберіть один підхід:
customers
products
ordersvalue
data
type
statusТакі назви не завжди пояснюють зміст. За можливості уточнюйте призначення:
total_amount
payload_data
payment_type
order_statuscust_addr
ord_dt
qtyКраще:
customer_address
order_date
quantityПоширені й однозначні скорочення можна використовувати, але команда має домовитися про них заздалегідь.
idУ таблиці orders колонка id не пояснює, що саме вона ідентифікує. Зрозуміліше:
customer_idВиняток — коли команда послідовно використовує id як первинний ключ, а назви зовнішніх ключів завжди будуються як <table>_id.
Назви на кшталт "CustomerID" змушують постійно контролювати регістр. Для звичайних ідентифікаторів використовуйте неекрановані назви в нижньому регістрі.
Перед створенням нового об’єкта перевірте:
Чи написана назва малими літерами?
Чи використовується snake_case?
Чи зрозуміло, що означає назва?
Чи відповідає назва правилам команди?
Чи не є вона зарезервованим словом?
Чи не змішує вона однину та множину з іншими таблицями?
Чи містить назва зовнішнього ключа ім’я пов’язаної сутності?
Чи зрозуміло з назви індексу, для якої таблиці та колонок його створено?
Використовуйте малі латинські літери та snake_case.
Не використовуйте подвійні лапки без необхідності.
Оберіть єдиний підхід до назв таблиць: однина або множина.
Називайте ідентифікатори змістовно: customer_id, created_at, is_active.
Для обмежень використовуйте зрозумілі суфікси: _pkey, _fkey, _key, _check.
Назви індексів будуйте з назви таблиці та колонок: orders_customer_id_idx.
Не використовуйте зарезервовані слова та неінформативні скорочення.
Дотримуйтеся обраних правил у всій базі даних.