Към съдържанието
wannacode

Ограничения: правила за данните

Накратко: Ограниченията NOT NULL, DEFAULT, UNIQUE, CHECK и PRIMARY KEY са правила в CREATE TABLE, с които таблицата сама пази данните верни.

Проблем

Таблица, която приема всичко

Ето таблица за доставчиците без никакви правила. Пусни заявката:

SQLпразна база

Влезе доставчик без име. Влезе втори път един и същ ЕИК. Влезе оценка 7 по скала от 1 до 5. Никой не е проверил.

В модула за промяна на данните магазинът отказваше такива редове с грешки. Тези грешки идват от правила, записани в CREATE TABLE. Сега ти ще ги пишеш.

Идеята

NOT NULL и DEFAULT

Правилата се пишат след типа на колоната. Казват се ограничения (constraints).

  • NOT NULL: колоната не може да е празна.
  • DEFAULT стойност: какво да се запише, ако INSERT не даде стойност.
SQLпразна база

Мандрата получи „София“, защото градът ѝ не е даден. Доставчик без име не влиза:

SQLпразна база

DEFAULT CURRENT_DATE записва днешната дата. Удобно е за „кога е добавен“:

SQLпразна база

1 значи „да, днешната дата е“. Смени added_at = CURRENT_DATE само с added_at и ще видиш самата дата.

По-точно, за любопитните

CURRENT_DATE в SQLite е датата по UTC, не по българско време. Между полунощ и 2–3 часа сутринта българската дата вече е новата, а UTC още е старата. CURRENT_TIMESTAMP дава дата и час, също по UTC.

Пробвай

Задължителните полета

Таблицата deliveries има id, supplier_id, amount и status. Направи доставчика и сумата задължителни, а състоянието да е задължително и по подразбиране 'expected'.

SQLпразна база

Идеята

UNIQUE

UNIQUE забранява две еднакви стойности в колоната. ЕИК-ът на фирмата е един:

SQLпразна база

Понякога уникална е двойката. Всеки доставчик дава една цена за един продукт. Двама доставчици може да дават един и същ продукт, а един доставчик дава много продукти. Правилото се пише отделно, след колоните, с двете колони в скоби:

SQLпразна база

Първите три реда влизат. Четвъртият е втора цена от доставчик 1 за продукт 1.

По-точно, за любопитните

UNIQUE позволява много NULL-и: два доставчика без ЕИК не се смятат за еднакви, защото NULL не е равно на NULL. Ако ЕИК-ът е задължителен, пиши vat TEXT NOT NULL UNIQUE. Така е и в PostgreSQL. SQL Server по подразбиране пуска само един NULL в UNIQUE колона.

Идеята

CHECK

CHECK (условие) пуска реда само ако условието е вярно. Условието е като в WHERE:

SQLпразна база

Когато условието е за няколко колони, CHECK се пише след колоните. Промоцията не може да свърши, преди да е започнала:

SQLпразна база

Съобщението на SQLite казва кое условие не е минало. Затова пиши кратки и ясни условия.

Виж го

CHECK пропуска NULL

Оценката е от 1 до 5. А ако не е дадена?

SQLпразна база

Влезе. CHECK отказва реда само когато условието е невярно. NULL BETWEEN 1 AND 5 е „неизвестно“, както всяко сравнение с NULL. Това е обратното на WHERE, което пази само вярното.

Тук това е правилно: нов доставчик още няма оценка. Но ако стойността е задължителна, CHECK не стига. Трябва и NOT NULL.

Пробвай

Цените на доставчиците

Таблицата supplier_prices има supplier_id, product_id и price. Цената е задължителна и по-голяма от 0, а всеки доставчик има само една цена за даден продукт. Допиши правилата.

SQLпразна база

Идеята

PRIMARY KEY

Първичният ключ вече го познаваш: колоната, по която се разпознава редът. В CREATE TABLE е ограничение като другите. Не пуска два реда с един и същ ключ:

SQLпразна база

Когато ключът е от две колони, той се пише отделно, както UNIQUE. Така е в order_items: един продукт е веднъж в една поръчка, а количеството е в quantity.

order_items

  • PKorder_idinteger→ orders
  • PKproduct_idinteger→ products
  • quantityinteger *
  • unit_pricereal *
По-точно, за любопитните

В SQLite има стара особеност: първичен ключ, който не е INTEGER PRIMARY KEY, приема NULL. Пусни го:

SQLпразна база

Два купона без код. Това е грешка от ранните версии, която е оставена, за да не се развалят стари програми. В STRICT таблица първичният ключ не приема NULL. Навсякъде другаде пиши code TEXT NOT NULL PRIMARY KEY. В PostgreSQL и MySQL първичният ключ винаги е NOT NULL.

Упражнение

Доставчиците, както трябва

Направи окончателната таблица suppliers: id (първичен ключ), name (задължително), vat (ЕИК, задължителен и без повторения), city (задължителен, по подразбиране 'София') и rating (цяло число от 1 до 5, може да липсва). Проверката ще опита да добави и грешни доставчици.

SQLпразна база

Тест

Провери се

1. Колоната е city TEXT NOT NULL DEFAULT 'София'. Какво става при INSERT, който не дава град?
2. Как казваш „един доставчик има една цена за продукт“, ако двама доставчици може да дават един и същ продукт?
3. Колоната е rating INTEGER CHECK (rating BETWEEN 1 AND 5). Кое влиза?
4. Какво значи PRIMARY KEY (order_id, product_id) в order_items?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·