Перейти до основного вмісту
Модуль 9 · Урок 2 із 434/57 у курсі~12 min
Модульні уроки (2/4)

Кілька обмежень і обмеження на рівні таблиці

Забезпечення правильності даних у базі даних на самому базовому рівні («цілісність даних») є фундаментальним. Якщо ви записуєте безпеку лише в додаток Node.js, помилки можуть спричинити неузгодженість даних у БД. Обмеження на рівні DDL є останньою, непроникною лінією захисту.

Основні обмеження

На додаток до PRIMARY KEY (що робить стовпець унікальним і НЕ NULL) і класичних NOT NULL і UNIQUE, існує дві основні категорії для логічної узгодженості даних:

1. ЗОВНІШНІЙ КЛЮЧ (посилальна цілісність)

Обмеження REFERENCES гарантує, що ідентифікатор зв’язування дійсно існує в «батьківській» таблиці, на яку він вказує. Наприклад, замовлення має бути пов’язане з існуючим клієнтом.

SQL
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  customer_id INTEGER REFERENCES customers(id)
);

Що робить зовнішній ключ?

  • Це запобігає вставці customer_id, якого немає в customers.
  • Це запобігає DELETE (видаленню) клієнта з customers, якщо є замовлення, що вказують на нього (це захищає від "залишених" записів).

Ми також можемо вирішити, що має статися, коли «батька» буде видалено:

SQL
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE

З ON DELETE CASCADE, якщо ми видалимо клієнта, Postgres автоматично видалить усі зв’язані orders! (Використовуйте з великою обережністю; зазвичай параметри за замовчуванням, які блокують операцію, є кращими.)

2. ПЕРЕВІРТЕ Обмеження

Обмеження CHECK перевіряє рядок, перевіряючи логічний вираз перед тим, як продовжити збереження.

SQL
CREATE TABLE contratti (
  id SERIAL PRIMARY KEY,
  stipendio NUMERIC(10,2) CHECK (stipendio > 0),
  data_inizio DATE,
  data_fine DATE,
  CHECK (data_fine > data_inizio)
);

Перший CHECK є обмеженням стовпця (воно стосується лише stipendio). Другий CHECK внизу є обмеженням таблиці (воно може перетинати значення з кількох стовпців і має бути оголошено внизу).

Якщо INSERT або UPDATE намагається зберегти кінець перед початком, Postgres відхилить це з помилкою!

Обмеження імен

Часто добре давати обмеженням чітке ім’я (за допомогою ключового слова CONSTRAINT). Таким чином, коли Postgres блокує запис, помилка скаже вам, наприклад, "обмеження 'stipendio_positivo' порушено", що набагато зрозуміліше для налагодження!

SQL
CREATE TABLE prodotti (
  id SERIAL PRIMARY KEY,
  nome VARCHAR(50),
  CONSTRAINT nome_univoco UNIQUE(nome)
);

Спробуйте

вправи#sql.m9.l2.e1
Спроби: 0Завантаження…

Створіть таблицю «prenotazioni» з ідентифікатором (SERIAL PRIMARY KEY) і «customer_id» (INTEGER). Використовуйте CONSTRAINT fk_cliente FOREIGN KEY (customer_id) REFERENCES customers(id), щоб дати явне ім’я обмеженню зовнішнього ключа. Зробіть це внизу, як обмеження таблиці.

Завантаження редактора…
Показати підказку

Напишіть CONSTRAINT fk_cliente ЗОВНІШНИЙ КЛЮЧ (локальний_стовпець) ПОСИЛАННЯ external_table(external_column)

Рішення доступне після 3 спроб

Обмеження з настроюваною логікою

вправи#sql.m9.l2.e2
Спроби: 0Завантаження…

Створіть таблицю «eventi» з ідентифікатором (SERIAL PRIMARY KEY), posti_totali (INTEGER) і biglietti_venduti (INTEGER). Додайте обмеження таблиці під назвою 'check_capienza', де biglietti_venduti ніколи не має бути більшим за posti_totali.

Завантаження редактора…
Показати підказку

Додайте обмеження внизу за допомогою CONSTRAINT check_capienza CHECK (вираз)

Рішення доступне після 3 спроб