5.4. ÐгÑаниÑÐµÐ½Ð¸Ñ #
Ð¢Ð¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ Ñами по Ñебе огÑаниÑиваÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво даннÑÑ , коÑоÑÑе можно ÑÐ¾Ñ ÑаниÑÑ Ð² ÑаблиÑе. Ðднако Ð´Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¸Ñ Ð¿Ñиложений Ñакие огÑаниÑÐµÐ½Ð¸Ñ ÑлиÑком гÑÑбÑе. ÐапÑимеÑ, ÑÑолбеÑ, ÑодеÑжаÑий ÑÐµÐ½Ñ Ð¿ÑодÑкÑа, должен, веÑоÑÑно, пÑинимаÑÑ ÑолÑко положиÑелÑнÑе знаÑениÑ. Ðо Ñакого ÑÑандаÑÑного Ñипа даннÑÑ Ð½ÐµÑ. Ðозможно, Ð²Ñ Ñакже Ð·Ð°Ñ Ð¾ÑиÑе огÑаниÑиÑÑ Ð´Ð°Ð½Ð½Ñе ÑÑолбÑа по оÑноÑÐµÐ½Ð¸Ñ Ðº дÑÑгим ÑÑолбÑам или ÑÑÑокам. ÐапÑимеÑ, в ÑаблиÑе Ñ Ð¸Ð½ÑоÑмаÑией о ÑоваÑе должна бÑÑÑ ÑолÑко одна ÑÑÑока Ñ Ð¾Ð¿ÑеделÑннÑм кодом ÑоваÑа.
ÐÐ»Ñ ÑеÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½ÑÑ Ð·Ð°Ð´Ð°Ñ SQL позволÑÐµÑ Ð²Ð°Ð¼ опÑеделÑÑÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑÑолбÑов и ÑаблиÑ. ÐгÑаниÑÐµÐ½Ð¸Ñ Ð´Ð°ÑÑ Ð²Ð°Ð¼ возможноÑÑÑ ÑпÑавлÑÑÑ Ð´Ð°Ð½Ð½Ñми в ÑаблиÑÐ°Ñ Ñак, как Ð²Ñ Ð·Ð°Ñ Ð¾ÑиÑе. ÐÑли полÑзоваÑÐµÐ»Ñ Ð¿Ð¾Ð¿ÑÑаеÑÑÑ ÑÐ¾Ñ ÑаниÑÑ Ð² ÑÑолбÑе знаÑение, наÑÑÑаÑÑее огÑаниÑениÑ, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÐµÑ Ð¾Ñибка. ÐгÑаниÑÐµÐ½Ð¸Ñ Ð±ÑдÑÑ Ð´ÐµÐ¹ÑÑвоваÑÑ, даже еÑли ÑÑо знаÑение по ÑмолÑаниÑ.
5.4.1. ÐгÑаниÑениÑ-пÑовеÑки #
ÐгÑаниÑение-пÑовеÑка â наиболее обÑий Ñип огÑаниÑений. Рего опÑеделении Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе ÑказаÑÑ, ÑÑо знаÑение данного ÑÑолбÑа должно ÑдовлеÑвоÑÑÑÑ Ð»Ð¾Ð³Ð¸ÑеÑÐºÐ¾Ð¼Ñ Ð²ÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (пÑовеÑке иÑÑинноÑÑи). ÐапÑимеÑ, ÑÐµÐ½Ñ ÑоваÑа можно огÑаниÑиÑÑ Ð¿Ð¾Ð»Ð¾Ð¶Ð¸ÑелÑнÑми знаÑениÑми Ñак:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);Ðак Ð²Ñ Ð²Ð¸Ð´Ð¸Ñе, огÑаниÑение опÑеделÑеÑÑÑ Ð¿Ð¾Ñле Ñипа даннÑÑ
, как и знаÑение по ÑмолÑаниÑ. ÐнаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð¸ огÑаниÑÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑÑ ÑказÑваÑÑÑÑ Ð² лÑбом поÑÑдке. ÐгÑаниÑение-пÑовеÑка ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· клÑÑевого Ñлова CHECK, за коÑоÑÑм идÑÑ Ð²ÑÑажение в ÑкобкаÑ
. ÐÑо вÑÑажение должно вклÑÑаÑÑ ÑÑолбеÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑого задаÑÑÑÑ Ð¾Ð³ÑаниÑение, инаÑе оно не Ð¸Ð¼ÐµÐµÑ Ð±Ð¾Ð»ÑÑого ÑмÑÑла.
ÐÑ Ð¼Ð¾Ð¶ÐµÑе Ñакже пÑиÑвоиÑÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð¾ÑделÑное имÑ. ÐÑо ÑлÑÑÑÐ¸Ñ ÑообÑÐµÐ½Ð¸Ñ Ð¾Ð± оÑÐ¸Ð±ÐºÐ°Ñ Ð¸ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð²Ð°Ð¼ ÑÑÑлаÑÑÑÑ Ð½Ð° ÑÑо огÑаниÑение, когда вам понадобиÑÑÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ ÐµÐ³Ð¾. СделаÑÑ ÑÑо можно Ñак:
CREATE TABLE products (
product_no integer,
name text,
price numeric CONSTRAINT positive_price CHECK (price > 0)
); То еÑÑÑ, ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ огÑаниÑение, напиÑиÑе клÑÑевое Ñлово CONSTRAINT, а за ним иденÑиÑикаÑÐ¾Ñ Ð¸ ÑобÑÑвенно опÑеделение огÑаниÑениÑ. (ÐÑли Ð²Ñ Ð½Ðµ опÑеделиÑе Ð¸Ð¼Ñ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ñаким обÑазом, ÑиÑÑема вÑбеÑÐµÑ Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ Ð¸Ð¼Ñ Ð·Ð° ваÑ.)
ÐгÑаниÑение-пÑовеÑка Ð¼Ð¾Ð¶ÐµÑ Ñакже ÑÑÑлаÑÑÑÑ Ð½Ð° неÑколÑко ÑÑолбÑов. ÐапÑимеÑ, еÑли Ð²Ñ Ñ ÑаниÑе обÑÑнÑÑ ÑÐµÐ½Ñ Ð¸ ÑÐµÐ½Ñ Ñо Ñкидкой, Ñак Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе гаÑанÑиÑоваÑÑ, ÑÑо Ñена Ñо Ñкидкой бÑÐ´ÐµÑ Ð²Ñегда менÑÑе обÑÑной:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0),
discounted_price numeric CHECK (discounted_price > 0),
CHECK (price > discounted_price)
);ÐеÑвÑе два огÑаниÑÐµÐ½Ð¸Ñ Ð¾Ð¿ÑеделÑÑÑÑÑ Ð¿Ð¾Ñ Ð¾Ð¶Ð¸Ð¼ обÑазом, но Ð´Ð»Ñ ÑÑеÑÑего иÑполÑзÑеÑÑÑ Ð½Ð¾Ð²Ñй ÑинÑакÑиÑ. Ðно не ÑвÑзано Ñ Ð¾Ð¿ÑеделÑннÑм ÑÑолбÑом, а пÑедÑÑавлено оÑделÑнÑм ÑлеменÑом в ÑпиÑке. ÐпÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÑÑолбÑов и Ñакие опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð³ÑаниÑений можно пеÑеÑÑавлÑÑÑ Ð² пÑоизволÑном поÑÑдке.
ÐÑо пеÑвÑе два огÑаниÑÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑказаÑÑ, ÑÑо ÑÑо огÑаниÑÐµÐ½Ð¸Ñ ÑÑолбÑов, Ñогда как ÑÑеÑÑе ÑвлÑеÑÑÑ Ð¾Ð³ÑаниÑением ÑаблиÑÑ, Ñак как оно напиÑано оÑделÑно Ð¾Ñ Ð¾Ð¿Ñеделений ÑÑолбÑов. ÐгÑаниÑÐµÐ½Ð¸Ñ ÑÑолбÑов Ñакже можно запиÑаÑÑ Ð² виде огÑаниÑений ÑаблиÑÑ, Ñогда как обÑаÑное не вÑегда возможно, Ñак как подÑазÑмеваеÑÑÑ, ÑÑо огÑаниÑение ÑÑолбÑа ÑÑÑлаеÑÑÑ ÑолÑко на ÑвÑзаннÑй ÑÑолбеÑ. (ХоÑÑ Postgres Pro ÑÑого не ÑÑебÑеÑ, но Ð´Ð»Ñ ÑовмеÑÑимоÑÑи Ñ Ð´ÑÑгими СУÐРлÑÑÑе ÑледоваÑÑ ÑÑÐ¾Ð¼Ñ Ð¿ÑавилÑ.) Ранее пÑиведÑннÑй пÑÐ¸Ð¼ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ пеÑепиÑаÑÑ Ð¸ Ñак:
CREATE TABLE products (
product_no integer,
name text,
price numeric,
CHECK (price > 0),
discounted_price numeric,
CHECK (discounted_price > 0),
CHECK (price > discounted_price)
);Ðли даже Ñак:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0),
discounted_price numeric,
CHECK (discounted_price > 0 AND price > discounted_price)
);ÐÑо дело вкÑÑа.
ÐгÑаниÑениÑм ÑаблиÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ пÑиÑваиваÑÑ Ð¸Ð¼ÐµÐ½Ð° Ñак же, как и огÑаниÑениÑм ÑÑолбÑов:
CREATE TABLE products (
product_no integer,
name text,
price numeric,
CHECK (price > 0),
discounted_price numeric,
CHECK (discounted_price > 0),
CONSTRAINT valid_discount CHECK (price > discounted_price)
);СледÑÐµÑ Ð·Ð°Ð¼ÐµÑиÑÑ, ÑÑо огÑаниÑение-пÑовеÑка ÑдовлеÑвоÑÑеÑÑÑ, еÑли вÑÑажение пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð·Ð½Ð°Ñение true или NULL. Так как ÑезÑлÑÑаÑом Ð¼Ð½Ð¾Ð³Ð¸Ñ Ð²ÑÑажений Ñ Ð¾Ð¿ÐµÑандами NULL бÑÐ´ÐµÑ Ð·Ð½Ð°Ñение NULL, Ñакие огÑаниÑÐµÐ½Ð¸Ñ Ð½Ðµ бÑдÑÑ Ð¿ÑепÑÑÑÑвоваÑÑ Ð·Ð°Ð¿Ð¸Ñи NULL в огÑаниÑиваемÑе ÑÑолбÑÑ. ЧÑÐ¾Ð±Ñ Ð³Ð°ÑанÑиÑоваÑÑ, ÑÑо ÑÑÐ¾Ð»Ð±ÐµÑ Ð½Ðµ ÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ NULL, можно иÑполÑзоваÑÑ Ð¾Ð³ÑаниÑение NOT NULL, опиÑанное в ÑледÑÑÑем Ñазделе.
ÐÑимеÑание
Postgres Pro не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ CHECK, коÑоÑÑе обÑаÑаÑÑÑÑ Ðº даннÑм, не оÑноÑÑÑимÑÑ Ðº новой или изменÑнной ÑÑÑоке. ХоÑÑ Ð¾Ð³ÑаниÑение CHECK, наÑÑÑаÑÑее ÑÑо пÑавило, Ð¼Ð¾Ð¶ÐµÑ ÑабоÑаÑÑ Ð² пÑоÑÑÑÑ
ÑлÑÑаÑÑ
, в обÑем ÑлÑÑае нелÑÐ·Ñ Ð³Ð°ÑанÑиÑоваÑÑ, ÑÑо база даннÑÑ
не пÑидÑÑ Ð² ÑоÑÑоÑние, когда ÑÑловие огÑаниÑÐµÐ½Ð¸Ñ Ð¾ÐºÐ°Ð¶ÐµÑÑÑ Ð»Ð¾Ð¶Ð½Ñм (вÑледÑÑвие поÑледÑÑÑиÑ
изменений дÑÑгиÑ
ÑÑаÑÑвÑÑÑиÑ
в его вÑÑиÑлении ÑÑÑок). Ð ÑезÑлÑÑаÑе воÑÑÑановление вÑгÑÑженнÑÑ
даннÑÑ
Ð¼Ð¾Ð¶ÐµÑ Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñм. Ðо вÑÐµÐ¼Ñ Ð²Ð¾ÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶ÐµÐ½ Ñбой, даже еÑли полное ÑоÑÑоÑние Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
ÑоглаÑÑеÑÑÑ Ñ ÑÑловием огÑаниÑениÑ, по пÑиÑине Ñого, ÑÑо ÑÑÑоки загÑÑжаÑÑÑÑ Ð½Ðµ в Ñом поÑÑдке, в коÑоÑом ÑÑо ÑÑловие бÑÐ´ÐµÑ ÑоблÑдаÑÑÑÑ. ÐоÑÑÐ¾Ð¼Ñ Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð³ÑаниÑений, заÑÑагиваÑÑиÑ
дÑÑгие ÑÑÑоки и дÑÑгие ÑаблиÑÑ, иÑполÑзÑйÑе огÑаниÑÐµÐ½Ð¸Ñ UNIQUE, EXCLUDE или FOREIGN KEY, еÑли ÑÑо возможно.
ÐÑли вам не нÑжна поÑÑоÑнно поддеÑÐ¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð³Ð°ÑанÑÐ¸Ñ ÑелоÑÑноÑÑи, а доÑÑаÑоÑно Ñазовой пÑовеÑки добавлÑемой ÑÑÑоки по оÑноÑÐµÐ½Ð¸Ñ Ðº дÑÑгим ÑÑÑокам, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе ÑеализоваÑÑ ÑÑÑ Ð¿ÑовеÑÐºÑ Ð² ÑобÑÑвенном ÑÑиггеÑе. (ÐÑÐ¾Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´ иÑклÑÑÐ°ÐµÑ Ð²ÑÑеопиÑаннÑе пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð¿Ñи воÑÑÑановлении, Ñак как в вÑгÑÑзке pg_dump ÑÑиггеÑÑ Ð²Ð¾ÑÑоздаÑÑÑÑ Ð¿Ð¾Ñле воÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ , и поÑÑÐ¾Ð¼Ñ ÑÑа пÑовеÑка не бÑÐ´ÐµÑ Ð´ÐµÐ¹ÑÑвоваÑÑ Ð² пÑоÑеÑÑе вÑгÑÑзки/воÑÑÑановлениÑ.)
ÐÑимеÑание
Ð Postgres Pro пÑедполагаеÑÑÑ, ÑÑо ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð³ÑаниÑений CHECK ÑвлÑÑÑÑÑ Ð¿Ð¾ÑÑоÑннÑми, Ñо еÑÑÑ Ð¿Ñи одинаковÑÑ
даннÑÑ
в ÑÑÑоке они вÑегда вÑдаÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñй ÑезÑлÑÑаÑ. Ðменно ÑÑим пÑедположением опÑавдÑваеÑÑÑ Ñо, ÑÑо огÑаниÑÐµÐ½Ð¸Ñ CHECK пÑовеÑÑÑÑÑÑ ÑолÑко пÑи добавлении или изменении ÑÑÑок, а не пÑи каждом обÑаÑении к ним. (ÐÑиведÑнное вÑÑе пÑедÑпÑеждение о недопÑÑÑимоÑÑи обÑаÑений к дÑÑгим ÑаблиÑам ÑвлÑеÑÑÑ ÑаÑÑнÑм ÑледÑÑвием ÑÑого пÑедположениÑ.)
Ðднако ÑÑо пÑедположение Ð¼Ð¾Ð¶ÐµÑ Ð½Ð°ÑÑÑаÑÑÑÑ, как ÑаÑÑо бÑваеÑ, когда в вÑÑажении CHECK иÑполÑзÑеÑÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑÐºÐ°Ñ ÑÑнкÑиÑ, поведение коÑоÑой впоÑледÑÑвии менÑеÑÑÑ. Postgres Pro не запÑеÑÐ°ÐµÑ ÑÑого, и еÑли ÑÑÑоки в ÑаблиÑе пеÑеÑÑанÑÑ ÑдовлеÑвоÑÑÑÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ CHECK, ÑÑо оÑÑанеÑÑÑ Ð½ÐµÐ·Ð°Ð¼ÐµÑеннÑм. РиÑоге пÑи попÑÑке загÑÑзиÑÑ Ð²ÑгÑÑженнÑе позже даннÑе могÑÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð¿ÑоблемÑ. ÐоÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ñе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑекомендÑеÑÑÑ Ð¾ÑÑÑеÑÑвлÑÑÑ ÑледÑÑÑим обÑазом: ÑдалиÑÑ Ð¾Ð³ÑаниÑение (иÑполÑзÑÑ ALTER TABLE), измениÑÑ Ð¾Ð¿Ñеделение ÑÑнкÑии, а заÑем пеÑеÑоздаÑÑ Ð¾Ð³ÑаниÑение Ñой же командой, коÑоÑÐ°Ñ Ð¿Ñи ÑÑом пеÑепÑовеÑÐ¸Ñ Ð²Ñе ÑÑÑоки ÑаблиÑÑ.
5.4.2. ÐгÑаниÑÐµÐ½Ð¸Ñ NOT NULL #
ÐгÑаниÑение NOT NULL пÑоÑÑо ÑказÑваеÑ, ÑÑо ÑÑолбÑÑ Ð½ÐµÐ»ÑÐ·Ñ Ð¿ÑиÑваиваÑÑ Ð·Ð½Ð°Ñение NULL. ÐÑÐ¸Ð¼ÐµÑ ÑинÑакÑиÑа:
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric
);ÐгÑаниÑение NOT NULL вÑегда запиÑÑваеÑÑÑ ÐºÐ°Ðº огÑаниÑение ÑÑолбÑа и ÑÑнкÑионалÑно ÑквиваленÑно огÑаниÑÐµÐ½Ð¸Ñ CHECK (, но в Postgres Pro Ñвное огÑаниÑение NOT NULL ÑабоÑÐ°ÐµÑ Ð±Ð¾Ð»ÐµÐµ ÑÑÑекÑивно. ХоÑÑ Ñ Ñакой запиÑи еÑÑÑ Ð½ÐµÐ´Ð¾ÑÑаÑок â назнаÑиÑÑ Ð¸Ð¼Ñ Ñаким огÑаниÑениÑм нелÑзÑ.имÑ_ÑÑолбÑа IS NOT NULL)
ÐÑÑеÑÑвенно, Ð´Ð»Ñ ÑÑолбÑа можно опÑеделиÑÑ Ð±Ð¾Ð»ÑÑе одного огÑаниÑениÑ. ÐÐ»Ñ ÑÑого Ð¸Ñ Ð½Ñжно пÑоÑÑо ÑказаÑÑ Ð¾Ð´Ð½Ð¾ за дÑÑгим:
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric NOT NULL CHECK (price > 0)
);ÐоÑÑдок здеÑÑ Ð½Ðµ Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑениÑ, он не обÑзаÑелÑно ÑооÑвеÑÑÑвÑÐµÑ Ð¿Ð¾ÑÑÐ´ÐºÑ Ð¿ÑовеÑки огÑаниÑений.
ÐÐ»Ñ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ NOT NULL еÑÑÑ Ð¸ обÑаÑное: огÑаниÑение NULL. Ðно не ознаÑаеÑ, ÑÑо ÑÑÐ¾Ð»Ð±ÐµÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ имеÑÑ ÑолÑко знаÑение NULL, ÑÑо конеÑно бÑло Ð±Ñ Ð±ÐµÑÑмÑÑленно. СÑÑÑ Ð¶Ðµ его в пÑоÑÑом Ñказании, ÑÑо ÑÑÐ¾Ð»Ð±ÐµÑ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð·Ð½Ð°Ñение NULL (ÑÑо поведение по ÑмолÑаниÑ). ÐгÑаниÑение NULL оÑÑÑÑÑÑвÑÐµÑ Ð² ÑÑандаÑÑе SQL и иÑполÑзоваÑÑ ÐµÐ³Ð¾ в пеÑеноÑимÑÑ
пÑиложениÑÑ
не ÑледÑеÑ. (Ðно бÑло добавлено в Postgres Pro ÑолÑко Ð´Ð»Ñ ÑовмеÑÑимоÑÑи Ñ Ð½ÐµÐºÐ¾ÑоÑÑми дÑÑгими СУÐÐ.) Ðднако некоÑоÑÑе полÑзоваÑели лÑбÑÑ ÐµÐ³Ð¾ иÑполÑзоваÑÑ, Ñак как оно позволÑÐµÑ Ð»ÐµÐ³ÐºÐ¾ пеÑеклÑÑаÑÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð² ÑкÑипÑе. ÐапÑимеÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе наÑаÑÑ Ñ:
CREATE TABLE products (
product_no integer NULL,
name text NULL,
price numeric NULL
); и заÑем вÑÑавиÑÑ ÐºÐ»ÑÑевое Ñлово NOT, где поÑÑебÑеÑÑÑ.
ÐодÑказка
ÐÑи пÑоекÑиÑовании баз даннÑÑ ÑаÑе вÑего болÑÑинÑÑво ÑÑолбÑов Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿Ð¾Ð¼ÐµÑÐµÐ½Ñ ÐºÐ°Ðº NOT NULL.
5.4.3. ÐгÑаниÑÐµÐ½Ð¸Ñ ÑникалÑноÑÑи #
ÐгÑаниÑÐµÐ½Ð¸Ñ ÑникалÑноÑÑи гаÑанÑиÑÑÑÑ, ÑÑо даннÑе в опÑеделÑнном ÑÑолбÑе или гÑÑппе ÑÑолбÑов ÑникалÑÐ½Ñ ÑÑеди вÑÐµÑ ÑÑÑок ÑаблиÑÑ. ÐгÑаниÑение запиÑÑваеÑÑÑ Ñак:
CREATE TABLE products (
product_no integer UNIQUE,
name text,
price numeric
);в виде огÑаниÑÐµÐ½Ð¸Ñ ÑÑолбÑа и Ñак:
CREATE TABLE products (
product_no integer,
name text,
price numeric,
UNIQUE (product_no)
);в виде огÑаниÑÐµÐ½Ð¸Ñ ÑаблиÑÑ.
ЧÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ Ð¾Ð³ÑаниÑение ÑникалÑноÑÑи Ð´Ð»Ñ Ð³ÑÑÐ¿Ð¿Ñ ÑÑолбÑов, запиÑиÑе его в виде огÑаниÑÐµÐ½Ð¸Ñ ÑаблиÑÑ, пеÑеÑиÑлив имена ÑÑолбÑов ÑеÑез запÑÑÑÑ:
CREATE TABLE example (
a integer,
b integer,
c integer,
UNIQUE (a, c)
);Такое огÑаниÑение ÑказÑваеÑ, ÑÑо ÑоÑеÑание знаÑений пеÑеÑиÑленнÑÑ ÑÑолбÑов должно бÑÑÑ ÑникалÑно во вÑей ÑаблиÑе, Ñогда как знаÑÐµÐ½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑÑолбÑа по оÑделÑноÑÑи не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ (и обÑÑно не бÑдÑÑ) ÑникалÑнÑми.
ÐÑ Ð¼Ð¾Ð¶ÐµÑе назнаÑиÑÑ ÑникалÑÐ½Ð¾Ð¼Ñ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð¸Ð¼Ñ Ð¾Ð±ÑÑнÑм обÑазом:
CREATE TABLE products (
product_no integer CONSTRAINT must_be_different UNIQUE,
name text,
price numeric
);ÐÑи добавлении огÑаниÑÐµÐ½Ð¸Ñ ÑникалÑноÑÑи бÑÐ´ÐµÑ Ð°Ð²ÑомаÑиÑеÑки Ñоздан ÑникалÑнÑй индекÑ-B-деÑево Ð´Ð»Ñ ÑÑолбÑа или гÑÑÐ¿Ð¿Ñ ÑÑолбÑов, пеÑеÑиÑленнÑÑ Ð² огÑаниÑении. УÑловие ÑникалÑноÑÑи, ÑаÑпÑоÑÑÑанÑÑÑееÑÑ ÑолÑко на некоÑоÑÑе ÑÑÑоки, нелÑÐ·Ñ Ð·Ð°Ð¿Ð¸ÑаÑÑ Ð² виде огÑаниÑÐµÐ½Ð¸Ñ ÑникалÑноÑÑи, однако Ñакое ÑÑловие можно ÑÑÑановиÑÑ, Ñоздав ÑникалÑнÑй ÑаÑÑиÑнÑй индекÑ.
Ðак пÑавило, огÑаниÑение ÑникалÑноÑÑи наÑÑÑаеÑÑÑ, еÑли в ÑаблиÑе оказÑваеÑÑÑ Ð½ÐµÑколÑко ÑÑÑок, Ñ ÐºÐ¾ÑоÑÑÑ
ÑовпадаÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð²ÑеÑ
ÑÑолбÑов, вклÑÑÑннÑÑ
в огÑаниÑение. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð´Ð²Ð° знаÑÐµÐ½Ð¸Ñ NULL пÑи Ñаком ÑÑавнении не ÑÑиÑаÑÑÑÑ ÑавнÑми. ÐÑо ознаÑаеÑ, ÑÑо даже пÑи налиÑии огÑаниÑÐµÐ½Ð¸Ñ ÑникалÑноÑÑи в ÑаблиÑе можно ÑоÑ
ÑаниÑÑ ÑÑÑоки Ñ Ð´ÑблиÑÑÑÑимиÑÑ Ð·Ð½Ð°ÑениÑми, еÑли они ÑодеÑÐ¶Ð°Ñ NULL в одном или неÑколÑкиÑ
огÑаниÑиваемÑÑ
ÑÑолбÑаÑ
. ÐÑо поведение можно измениÑÑ, добавив пÑедложение NULLS NOT DISTINCT, напÑимеÑ
CREATE TABLE products (
product_no integer UNIQUE NULLS NOT DISTINCT,
name text,
price numeric
);или
CREATE TABLE products (
product_no integer,
name text,
price numeric,
UNIQUE NULLS NOT DISTINCT (product_no)
); Ðоведение по ÑмолÑÐ°Ð½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ вÑбÑаÑÑ Ñвно, добавив NULLS DISTINCT. СоглаÑно ÑÑандаÑÑÑ SQL ваÑÐ¸Ð°Ð½Ñ Ð¾Ð±ÑабоÑки знаÑений NULL по ÑмолÑÐ°Ð½Ð¸Ñ Ð¾Ð¿ÑеделÑеÑÑÑ ÑеализаÑией, и в дÑÑгиÑ
СУÐРвÑÑÑеÑаеÑÑÑ Ð´ÑÑгое поведение. ÐÑо ÑледÑÐµÑ ÑÑиÑÑваÑÑ Ð¿Ñи ÑазÑабоÑке пеÑеноÑимÑÑ
пÑиложений.
5.4.4. ÐеÑвиÑнÑе клÑÑи #
ÐгÑаниÑение пеÑвиÑного клÑÑа ознаÑаеÑ, ÑÑо обÑазÑÑÑий его ÑÑÐ¾Ð»Ð±ÐµÑ Ð¸Ð»Ð¸ гÑÑппа ÑÑолбÑов Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑникалÑнÑм иденÑиÑикаÑоÑом ÑÑÑок в ÑаблиÑе. ÐÐ»Ñ ÑÑого ÑÑебÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð±Ñли одновÑеменно ÑникалÑнÑми и оÑлиÑнÑми Ð¾Ñ NULL. Таким обÑазом, ÑаблиÑÑ Ñо ÑледÑÑÑими двÑÐ¼Ñ Ð¾Ð¿ÑеделениÑми бÑдÑÑ Ð¿ÑинимаÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñе даннÑе:
CREATE TABLE products (
product_no integer UNIQUE NOT NULL,
name text,
price numeric
);CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);ÐеÑвиÑнÑе клÑÑи могÑÑ Ð²ÐºÐ»ÑÑаÑÑ Ð½ÐµÑколÑко ÑÑолбÑов; ÑинÑакÑÐ¸Ñ Ð¿Ð¾Ñ Ð¾Ð¶ на запиÑÑ Ð¾Ð³ÑаниÑений ÑникалÑноÑÑи:
CREATE TABLE example (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);ÐÑи добавлении пеÑвиÑного клÑÑа авÑомаÑиÑеÑки ÑоздаÑÑÑÑ ÑникалÑнÑй индекÑ-B-деÑево Ð´Ð»Ñ ÑÑолбÑа или гÑÑÐ¿Ð¿Ñ ÑÑолбÑов, пеÑеÑиÑленнÑÑ
в пеÑвиÑном клÑÑе, и даннÑе ÑÑолбÑÑ Ð¿Ð¾Ð¼ÐµÑаÑÑÑÑ ÐºÐ°Ðº NOT NULL.
ТаблиÑа Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¼Ð°ÐºÑимÑм один пеÑвиÑнÑй клÑÑ. (ÐгÑаниÑений ÑникалÑноÑÑи и огÑаниÑений NOT NULL, коÑоÑÑе ÑÑнкÑионалÑно поÑÑи ÑавнознаÑÐ½Ñ Ð¿ÐµÑвиÑнÑм клÑÑам, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑколÑко Ñгодно, но назнаÑиÑÑ Ð¾Ð³ÑаниÑением пеÑвиÑного клÑÑа можно ÑолÑко одно.) ТеоÑÐ¸Ñ ÑелÑÑионнÑÑ Ð±Ð°Ð· даннÑÑ Ð³Ð¾Ð²Ð¾ÑиÑ, ÑÑо пеÑвиÑнÑй клÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ Ð² каждой ÑаблиÑе. Ð Postgres Pro Ñакого жÑÑÑкого ÑÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÑ, но обÑÑно лÑÑÑе ÐµÐ¼Ñ ÑледоваÑÑ.
ÐеÑвиÑнÑе клÑÑи Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð¸ Ð´Ð»Ñ Ð´Ð¾ÐºÑменÑиÑованиÑ, и Ð´Ð»Ñ ÐºÐ»Ð¸ÐµÐ½ÑÑÐºÐ¸Ñ Ð¿Ñиложений. ÐапÑимеÑ, гÑаÑиÑеÑÐºÐ¾Ð¼Ñ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑми ÑедакÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑодеÑжимого ÑаблиÑÑ, веÑоÑÑно, поÑÑебÑеÑÑÑ Ð·Ð½Ð°ÑÑ Ð¿ÐµÑвиÑнÑй клÑÑ ÑаблиÑÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñно иденÑиÑиÑиÑоваÑÑ ÐµÑ ÑÑÑоки. ÐеÑвиÑнÑе клÑÑи Ð½Ð°Ñ Ð¾Ð´ÑÑ Ð¸ дÑÑгое пÑименение в СУÐÐ; в ÑаÑÑноÑÑи, пеÑвиÑнÑй клÑÑ Ð² ÑаблиÑе опÑеделÑÐµÑ ÑелевÑе ÑÑолбÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð´Ð»Ñ ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ ÐºÐ»ÑÑей, ÑÑÑлаÑÑÐ¸Ñ ÑÑ Ð½Ð° ÑÑÑ ÑаблиÑÑ.
5.4.5. ÐнеÑние клÑÑи #
ÐгÑаниÑение внеÑнего клÑÑа ÑказÑваеÑ, ÑÑо знаÑÐµÐ½Ð¸Ñ ÑÑолбÑа (или гÑÑÐ¿Ð¿Ñ ÑÑолбÑов) Ð´Ð¾Ð»Ð¶Ð½Ñ ÑооÑвеÑÑÑвоваÑÑ Ð·Ð½Ð°ÑениÑм в некоÑоÑой ÑÑÑоке дÑÑгой ÑаблиÑÑ. ÐÑо назÑваеÑÑÑ ÑÑÑлоÑной ÑелоÑÑноÑÑÑÑ Ð´Ð²ÑÑ ÑвÑзаннÑÑ ÑаблиÑ.
ÐÑÑÑÑ Ñ Ð²Ð°Ñ Ñже еÑÑÑ ÑаблиÑа пÑодÑкÑов, коÑоÑÑÑ Ð¼Ñ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑаÑно иÑполÑзовали Ñанее:
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);ÐавайÑе пÑедположим, ÑÑо Ñ Ð²Ð°Ñ ÐµÑÑÑ ÑаблиÑа Ñ Ð·Ð°ÐºÐ°Ð·Ð°Ð¼Ð¸ ÑÑÐ¸Ñ Ð¿ÑодÑкÑов. ÐÑ Ñ Ð¾Ñим, ÑÑÐ¾Ð±Ñ Ð² ÑаблиÑе заказов ÑодеÑжалиÑÑ ÑолÑко Ð·Ð°ÐºÐ°Ð·Ñ Ð´ÐµÐ¹ÑÑвиÑелÑно ÑÑÑеÑÑвÑÑÑÐ¸Ñ Ð¿ÑодÑкÑов. ÐоÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð¾Ð¿Ñеделим в ней огÑаниÑение внеÑнего клÑÑа, ÑÑÑлаÑÑееÑÑ Ð½Ð° ÑаблиÑÑ Ð¿ÑодÑкÑов:
CREATE TABLE orders (
order_id integer PRIMARY KEY,
product_no integer REFERENCES products (product_no),
quantity integer
); С Ñаким огÑаниÑением ÑоздаÑÑ Ð·Ð°ÐºÐ°Ð· Ñо знаÑением product_no, оÑÑÑÑÑÑвÑÑÑим в ÑаблиÑе products (и не ÑавнÑм NULL), бÑÐ´ÐµÑ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾.
Ð Ñакой ÑÑ ÐµÐ¼Ðµ ÑаблиÑÑ orders назÑваÑÑ Ð¿Ð¾Ð´ÑинÑнной ÑаблиÑей, а products â главной. СооÑвеÑÑÑвенно, ÑÑолбÑÑ Ð½Ð°Ð·ÑваÑÑ Ñак же подÑинÑннÑм и главнÑм (или ÑÑÑлаÑÑимÑÑ Ð¸ ÑелевÑм).
ÐÑедÑдÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑокÑаÑиÑÑ Ñак:
CREATE TABLE orders (
order_id integer PRIMARY KEY,
product_no integer REFERENCES products,
quantity integer
);Ñо еÑÑÑ, еÑли опÑÑÑиÑÑ ÑпиÑок ÑÑолбÑов, внеÑний клÑÑ Ð±ÑÐ´ÐµÑ Ð½ÐµÑвно ÑвÑзан Ñ Ð¿ÐµÑвиÑнÑм клÑÑом главной ÑаблиÑÑ.
ÐгÑаниÑÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑнего клÑÑа можно назнаÑиÑÑ Ð¸Ð¼Ñ ÑÑандаÑÑнÑм ÑпоÑобом.
ÐнеÑний клÑÑ Ñакже Ð¼Ð¾Ð¶ÐµÑ ÑÑÑлаÑÑÑÑ Ð½Ð° гÑÑÐ¿Ð¿Ñ ÑÑолбÑов. Ð ÑÑом ÑлÑÑае его нÑжно запиÑаÑÑ Ð² виде обÑÑного огÑаниÑÐµÐ½Ð¸Ñ ÑаблиÑÑ. ÐапÑимеÑ:
CREATE TABLE t1 (
a integer PRIMARY KEY,
b integer,
c integer,
FOREIGN KEY (b, c) REFERENCES other_table (c1, c2)
);ÐÑÑеÑÑвенно, ÑиÑло и ÑÐ¸Ð¿Ñ ÑÑолбÑов в огÑаниÑении Ð´Ð¾Ð»Ð¶Ð½Ñ ÑооÑвеÑÑÑвоваÑÑ ÑиÑÐ»Ñ Ð¸ Ñипам ÑелевÑÑ ÑÑолбÑов.
Ðногда Ð¸Ð¼ÐµÐµÑ ÑмÑÑл задаÑÑ Ð² огÑаниÑении внеÑнего клÑÑа в каÑеÑÑве «дÑÑгой ÑаблиÑÑ» ÑÑ Ð¶Ðµ ÑаблиÑÑ; Ñакой внеÑний клÑÑ Ð½Ð°Ð·ÑваеÑÑÑ ÑÑÑлаÑÑимÑÑ Ð½Ð° ÑебÑ. ÐапÑимеÑ, еÑли Ð²Ñ Ñ Ð¾ÑиÑе, ÑÑÐ¾Ð±Ñ ÑÑÑоки ÑаблиÑÑ Ð¿ÑедÑÑавлÑли ÑÐ·Ð»Ñ Ð´Ñевовидной ÑÑÑÑкÑÑÑÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе напиÑаÑÑ
CREATE TABLE tree (
node_id integer PRIMARY KEY,
parent_id integer REFERENCES tree,
name text,
...
); ÐÐ»Ñ Ñзла веÑÑ
него ÑÑÐ¾Ð²Ð½Ñ parent_id бÑÐ´ÐµÑ Ñавен NULL, пока запиÑи Ñ Ð¾ÑлиÑнÑм Ð¾Ñ NULL parent_id бÑдÑÑ ÑÑÑлаÑÑÑÑ ÑолÑко на ÑÑÑеÑÑвÑÑÑие ÑÑÑоки ÑаблиÑÑ.
ТаблиÑа Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð½ÐµÑколÑко огÑаниÑений внеÑнего клÑÑа. ÐÑо полезно Ð´Ð»Ñ ÑвÑзи ÑÐ°Ð±Ð»Ð¸Ñ Ð² оÑноÑении многие-ко-многим. Скажем, Ñ Ð²Ð°Ñ ÐµÑÑÑ ÑаблиÑÑ Ð¿ÑодÑкÑов и заказов, но Ð²Ñ Ñ Ð¾ÑиÑе, ÑÑÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð½ заказ мог ÑодеÑжаÑÑ Ð½ÐµÑколÑко пÑодÑкÑов (ÑÑо невозможно в пÑедÑдÑÑей ÑÑ ÐµÐ¼Ðµ). ÐÐ»Ñ ÑÑого Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ ÑакÑÑ ÑÑ ÐµÐ¼Ñ:
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);
CREATE TABLE orders (
order_id integer PRIMARY KEY,
shipping_address text,
...
);
CREATE TABLE order_items (
product_no integer REFERENCES products,
order_id integer REFERENCES orders,
quantity integer,
PRIMARY KEY (product_no, order_id)
);ÐамеÑÑÑе, ÑÑо в поÑледней ÑаблиÑе пеÑвиÑнÑй клÑÑ Ð¿Ð¾ÐºÑÑÐ²Ð°ÐµÑ Ð²Ð½ÐµÑние клÑÑи.
ÐÑ Ð·Ð½Ð°ÐµÐ¼, ÑÑо внеÑние клÑÑи запÑеÑаÑÑ Ñоздание заказов, не оÑноÑÑÑÐ¸Ñ ÑÑ Ð½Ð¸ к Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¿ÑодÑкÑÑ. Ðо ÑÑо делаÑÑ, еÑли поÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð·Ð°ÐºÐ°Ð·Ð¾Ð² Ñ Ð¾Ð¿ÑеделÑннÑм пÑодÑкÑом Ð¼Ñ Ð·Ð°Ñ Ð¾Ñим ÑдалиÑÑ ÐµÐ³Ð¾? SQL ÑпÑавиÑÑÑ Ñ ÑÑой ÑиÑÑаÑией. ÐнÑÑиÑÐ¸Ñ Ð¿Ð¾Ð´ÑказÑÐ²Ð°ÐµÑ ÑледÑÑÑие ваÑианÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ:
ÐапÑеÑиÑÑ Ñдаление пÑодÑкÑа
УдалиÑÑ Ñакже ÑвÑзаннÑе заказÑ
ЧÑо-Ñо еÑÑ?
ÐÐ»Ñ Ð¸Ð»Ð»ÑÑÑÑаÑии давайÑе ÑеализÑем ÑледÑÑÑее поведение в вÑÑепÑиведÑнном пÑимеÑе: пÑи попÑÑке ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¿ÑодÑкÑа, на коÑоÑÑй ÑÑÑлаÑÑÑÑ Ð·Ð°ÐºÐ°Ð·Ñ (ÑеÑез ÑаблиÑÑ order_items), Ð¼Ñ Ð·Ð°Ð¿ÑеÑаем ÑÑÑ Ð¾Ð¿ÐµÑаÑиÑ. ÐÑли же кÑо-Ñо попÑÑаеÑÑÑ ÑдалиÑÑ Ð·Ð°ÐºÐ°Ð·, Ñо ÑдалиÑÑÑ Ð¸ его ÑодеÑжимое:
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);
CREATE TABLE orders (
order_id integer PRIMARY KEY,
shipping_address text,
...
);
CREATE TABLE order_items (
product_no integer REFERENCES products ON DELETE RESTRICT,
order_id integer REFERENCES orders ON DELETE CASCADE,
quantity integer,
PRIMARY KEY (product_no, order_id)
);ÐгÑаниÑиваÑÑие и каÑкаднÑе ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ â два наиболее ÑаÑпÑоÑÑÑанÑннÑÑ
ваÑианÑа. RESTRICT пÑедоÑвÑаÑÐ°ÐµÑ Ñдаление ÑвÑзанной ÑÑÑоки. NO ACTION ознаÑаеÑ, ÑÑо еÑли завиÑимÑе ÑÑÑоки пÑодолжаÑÑ ÑÑÑеÑÑвоваÑÑ Ð¿Ñи пÑовеÑке огÑаниÑениÑ, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð¾Ñибка (ÑÑо поведение по ÑмолÑаниÑ). (ÐлавнÑм оÑлиÑием ÑÑиÑ
двÑÑ
ваÑианÑов ÑвлÑеÑÑÑ Ñо, ÑÑо NO ACTION позволÑÐµÑ Ð¾ÑложиÑÑ Ð¿ÑовеÑÐºÑ Ð² пÑоÑеÑÑе ÑÑанзакÑии, а RESTRICT â неÑ.) CASCADE ÑказÑваеÑ, ÑÑо пÑи Ñдалении ÑвÑзаннÑÑ
ÑÑÑок завиÑимÑе Ð¾Ñ Ð½Ð¸Ñ
бÑдÑÑ Ñак же авÑомаÑиÑеÑки ÑдаленÑ. ÐÑÑÑ ÐµÑÑ Ð´Ð²Ð° ваÑианÑа: SET NULL и SET DEFAULT. ÐÑи Ñдалении ÑвÑзаннÑÑ
ÑÑÑок они назнаÑаÑÑ Ð·Ð°Ð²Ð¸ÑимÑм ÑÑолбÑам в подÑинÑнной ÑаблиÑе знаÑÐµÐ½Ð¸Ñ NULL или знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑаниÑ, ÑооÑвеÑÑÑвенно. ÐамеÑÑÑе, ÑÑо ÑÑо не бÑÐ´ÐµÑ Ð¾Ñнованием Ð´Ð»Ñ Ð½Ð°ÑÑÑÐµÐ½Ð¸Ñ Ð¾Ð³ÑаниÑений. ÐапÑимеÑ, еÑли в каÑеÑÑве дейÑÑÐ²Ð¸Ñ Ð·Ð°Ð´Ð°Ð½Ð¾ SET DEFAULT, но знаÑение по ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ðµ ÑдовлеÑвоÑÑÐµÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑнего клÑÑа, опеÑаÑÐ¸Ñ Ð·Ð°ÐºÐ¾Ð½ÑиÑÑÑ Ð¾Ñибкой.
Ðакой ваÑÐ¸Ð°Ð½Ñ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ ON DELETE вÑбÑаÑÑ â завиÑÐ¸Ñ Ð¾Ñ Ñого, какие ÑÐ¸Ð¿Ñ Ð¾Ð±ÑекÑов пÑедÑÑавлÑÑÑÑÑ Ð² ÑвÑзаннÑÑ
ÑаблиÑаÑ
. Ðогда в подÑинÑнной ÑаблиÑе пÑедÑÑавлÑеÑÑÑ Ð¾Ð±ÑекÑ, коÑоÑÑй ÑвлÑеÑÑÑ ÑоÑÑавной ÑаÑÑÑÑ ÑÑÑноÑÑи, пÑедÑÑавленной в главной ÑаблиÑе, и не Ð¼Ð¾Ð¶ÐµÑ ÑÑÑеÑÑвоваÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо, ÑмеÑÑно вÑбÑаÑÑ Ð´ÐµÐ¹ÑÑвие CASCADE. ÐÑли две ÑаблиÑÑ Ð¿ÑедÑÑавлÑÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸ÑимÑе обÑекÑÑ, более подÑ
одÑÑим дейÑÑвием бÑÐ´ÐµÑ RESTRICT или NO ACTION; Ñогда пÑиложениÑ, коÑоÑÐ¾Ð¼Ñ Ð´ÐµÐ¹ÑÑвиÑелÑно нÑжно ÑдалиÑÑ Ð¾Ð±Ð° обÑекÑа, поÑÑебÑеÑÑÑ ÑделаÑÑ ÑÑо Ñвно и вÑполниÑÑ Ð´Ð²Ðµ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ÑдалениÑ. РпÑиведÑнном вÑÑе пÑимеÑе позиÑии заказа ÑвлÑÑÑÑÑ ÑаÑÑÑÑ Ð·Ð°ÐºÐ°Ð·Ð°, и бÑÐ´ÐµÑ Ñдобно, еÑли они ÑдалÑÑÑÑ Ð°Ð²ÑомаÑиÑеÑки пÑи Ñдалении заказа. Ðо пÑодÑкÑÑ Ð¸ Ð·Ð°ÐºÐ°Ð·Ñ â ÑазнÑе веÑи, поÑÑÐ¾Ð¼Ñ Ð°Ð²ÑомаÑиÑеÑкое Ñдаление некоÑоÑÑÑ
позиÑий заказов пÑи Ñдалении пÑодÑкÑов Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÐ¿ÑиемлемÑм. ÐÑли же оÑноÑение внеÑнего клÑÑа пÑедÑÑавлÑÐµÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑиÑ, подÑ
одÑÑим Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð´ÐµÐ¹ÑÑвие SET NULL или SET DEFAULT. ÐапÑимеÑ, еÑли в ÑаблиÑе пÑодÑкÑов ÑодеÑжиÑÑÑ ÑÑÑлка на менеджеÑа пÑодÑкÑа, и запиÑÑ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑа ÑдалÑеÑÑÑ, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñм ÑÑÑановиÑÑ Ð² поле менеджеÑа пÑодÑкÑа знаÑение NULL или знаÑение по ÑмолÑаниÑ.
ÐейÑÑÐ²Ð¸Ñ SET NULL и SET DEFAULT могÑÑ Ð¿ÑинимаÑÑ ÑпиÑок ÑÑолбÑов, коÑоÑÑе полÑÑÐ°Ñ ÑооÑвеÑÑÑвÑÑÑие знаÑениÑ. ÐбÑÑно знаÑÐµÐ½Ð¸Ñ Ð¿ÑиÑваиваÑÑÑÑ Ð²Ñем ÑÑолбÑам огÑаниÑÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑнего клÑÑа; пÑиÑвоение Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¼Ð½Ð¾Ð¶ÐµÑÑва ÑÑолбÑов полезно ÑолÑко в некоÑоÑÑÑ
оÑобÑÑ
ÑлÑÑаÑÑ
. РаÑÑмоÑÑиÑе ÑледÑÑÑий пÑимеÑ:
CREATE TABLE tenants (
tenant_id integer PRIMARY KEY
);
CREATE TABLE users (
tenant_id integer REFERENCES tenants ON DELETE CASCADE,
user_id integer NOT NULL,
PRIMARY KEY (tenant_id, user_id)
);
CREATE TABLE posts (
tenant_id integer REFERENCES tenants ON DELETE CASCADE,
post_id integer NOT NULL,
author_id integer,
PRIMARY KEY (tenant_id, post_id),
FOREIGN KEY (tenant_id, author_id) REFERENCES users ON DELETE SET NULL (author_id)
); Ðез ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ ÑÑолбÑа внеÑний клÑÑ Ñакже ÑÑÑановил Ð±Ñ Ð·Ð½Ð°Ñение NULL Ð´Ð»Ñ ÑÑолбÑа tenant_id, но ÑÑÐ¾Ñ ÑÑÐ¾Ð»Ð±ÐµÑ ÑвлÑеÑÑÑ ÑаÑÑÑÑ Ð¿ÐµÑвиÑного клÑÑа.
ÐналогиÑно ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ ON DELETE ÑÑÑеÑÑвÑÐµÑ ON UPDATE, коÑоÑое ÑÑабаÑÑÐ²Ð°ÐµÑ Ð¿Ñи изменении заданного ÑÑолбÑа. ÐÑи ÑÑом возможнÑе дейÑÑÐ²Ð¸Ñ Ñе же, за иÑклÑÑением Ñого, ÑÑо Ð´Ð»Ñ SET NULL и SET DEFAULT нелÑÐ·Ñ Ð·Ð°Ð´Ð°ÑÑ ÑпиÑки ÑÑолбÑов. CASCADE в данном ÑлÑÑае ознаÑаеÑ, ÑÑо изменÑннÑе знаÑÐµÐ½Ð¸Ñ ÑвÑзаннÑÑ
ÑÑолбÑов бÑдÑÑ ÑкопиÑÐ¾Ð²Ð°Ð½Ñ Ð² завиÑимÑе ÑÑÑоки.
ÐбÑÑно завиÑÐ¸Ð¼Ð°Ñ ÑÑÑока не должна ÑдовлеÑвоÑÑÑÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑнего клÑÑа, еÑли один из ÑвÑзаннÑÑ
ÑÑолбÑов ÑодеÑÐ¶Ð¸Ñ NULL. ÐÑли в обÑÑвление внеÑнего клÑÑа добавлено MATCH FULL, ÑÑÑока бÑÐ´ÐµÑ ÑдовлеÑвоÑÑÑÑ Ð¾Ð³ÑаниÑениÑ, ÑолÑко еÑли вÑе ÑвÑзаннÑе ÑÑолбÑÑ ÑÐ°Ð²Ð½Ñ NULL (Ñо еÑÑÑ Ð¿Ñи ÑазнÑÑ
знаÑениÑÑ
(NULL и не NULL) гаÑанÑиÑÑеÑÑÑ Ð½ÐµÐ²Ñполнение огÑаниÑÐµÐ½Ð¸Ñ MATCH FULL). ÐÑли Ð²Ñ Ñ
оÑиÑе, ÑÑÐ¾Ð±Ñ Ð·Ð°Ð²Ð¸ÑимÑе ÑÑÑоки не могли избежаÑÑ Ð¸ ÑÑого огÑаниÑениÑ, обÑÑвиÑе ÑвÑзаннÑе ÑÑолбÑÑ ÐºÐ°Ðº NOT NULL.
ÐнеÑний клÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ ÑÑÑлаÑÑÑÑ Ð½Ð° ÑÑолбÑÑ, либо ÑвлÑÑÑиеÑÑ Ð¿ÐµÑвиÑнÑм клÑÑом, либо обÑазÑÑÑие огÑаниÑение ÑникалÑноÑÑи, либо ÑвлÑÑÑиеÑÑ ÑÑолбÑами из неÑаÑÑиÑного ÑникалÑного индекÑа. Таким обÑазом, Ð´Ð»Ñ ÑвÑзаннÑÑ
ÑÑолбÑов вÑегда бÑÐ´ÐµÑ ÑÑÑеÑÑвоваÑÑ Ð¸Ð½Ð´ÐµÐºÑ, а знаÑÐ¸Ñ Ð¿ÑовеÑки налиÑÐ¸Ñ ÑооÑвеÑÑÑÐ²Ð¸Ñ Ð´Ð»Ñ ÑвÑзанной ÑÑÑоки бÑдÑÑ Ð²ÑполнÑÑÑÑÑ ÑÑÑекÑивно. Так как ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ DELETE Ð´Ð»Ñ ÑÑÑок главной ÑаблиÑÑ Ð¸Ð»Ð¸ UPDATE Ð´Ð»Ñ Ð·Ð°Ð²Ð¸ÑимÑÑ
ÑÑолбÑов поÑÑебÑÑÑ Ð¿ÑоÑканиÑоваÑÑ Ð¿Ð¾Ð´ÑинÑннÑÑ ÑаблиÑÑ Ð¸ найÑи ÑÑÑоки, ÑÑÑлаÑÑиеÑÑ Ð½Ð° ÑÑаÑÑе знаÑениÑ, полезно бÑÐ´ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¸Ð½Ð´ÐµÐºÑ Ð¸ Ð´Ð»Ñ Ð¿Ð¾Ð´ÑинÑннÑÑ
ÑÑолбÑов. Ðо ÑÑо нÑжно не вÑегда, и ÑоздаÑÑ ÑооÑвеÑÑÑвÑÑÑий Ð¸Ð½Ð´ÐµÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ по-ÑазномÑ, поÑÑÐ¾Ð¼Ñ Ð¾Ð±ÑÑвление внеÑнего клÑÑа не ÑоздаÑÑ Ð°Ð²ÑомаÑиÑеÑки Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ð¾ ÑвÑзаннÑм ÑÑолбÑам.
ÐодÑобнее об изменении и Ñдалении даннÑÑ ÑаÑÑказÑваеÑÑÑ Ð² Ðлаве 6. ÐÑ Ñакже можеÑе подÑобнее ÑзнаÑÑ Ð¾ ÑинÑакÑиÑе огÑаниÑений внеÑнего клÑÑа в ÑпÑавке CREATE TABLE.
5.4.6. ÐгÑаниÑениÑ-иÑклÑÑÐµÐ½Ð¸Ñ #
ÐгÑаниÑениÑ-иÑклÑÑÐµÐ½Ð¸Ñ Ð³Ð°ÑанÑиÑÑÑÑ, ÑÑо пÑи ÑÑавнении лÑбÑÑ Ð´Ð²ÑÑ ÑÑÑок по ÑказаннÑм ÑÑолбÑам или вÑÑажениÑм Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð·Ð°Ð´Ð°Ð½Ð½ÑÑ Ð¾Ð¿ÐµÑаÑоÑов, минимÑм одно из ÑÑÐ¸Ñ ÑÑавнений возвÑаÑÐ¸Ñ false или NULL. ÐапиÑÑваеÑÑÑ ÑÑо Ñак:
CREATE TABLE circles (
c circle,
EXCLUDE USING gist (c WITH &&)
);ÐодÑобнее об ÑÑом Ñм. CREATE TABLE ... CONSTRAINT ... EXCLUDE.
ÐÑи добавлении огÑаниÑениÑ-иÑклÑÑÐµÐ½Ð¸Ñ Ð±ÑÐ´ÐµÑ Ð°Ð²ÑомаÑиÑеÑки Ñоздан Ð¸Ð½Ð´ÐµÐºÑ Ñого Ñипа, коÑоÑÑй Ñказан в обÑÑвлении огÑаниÑениÑ.