Ачааллж байна...
Өмнөх хичээлийг нэгэн тааламжгүй дүгнэлтээр дуусгасан: SQLite-ийн баганын төрөл нь хууль биш, зөвлөмж юм. Бүхэл тоон баганад "үнэгүй" гэдэг үг чимээгүйхэн хадгалагдаж, хэдэн query-ний дараа "үнэгүй арга хэмжээ 10000 төгрөгөөс үнэтэй" гэсэн худал үр дүн гарч ирсэн. Тэгвэл буруу өгөгдлийг хүснэгтэд орохоос нь өмнө зогсоох арга бий юу? Бий — тэдгээрийг constraint гэж нэрлэдэг.
Constraint бол баганад эсвэл хүснэгтэд тавьсан дүрэм бөгөөд SQLite түүнийг төрлөөс ялгаатай нь жинхэнэ хууль шиг мөрдүүлдэг. Дүрэм зөрчсөн INSERT эсвэл UPDATE тэр даруй алдаа өгч, өгөгдөл огт өөрчлөгдөхгүй. Та эдгээр алдаануудын хоёртой нь аль хэдийн уулзсан: Бүлэг 3-ын INSERT хичээлд NOT NULL constraint failed болон UNIQUE constraint failed гэсэн мессежүүдийг "Бүлэг 4-т тайлбарлана" гэж хойшлуулсан. Одоо тэдний ээлж ирлээ.
Энэ хичээлд дөрвөн constraint-ыг сурна: NOT NULL (хоосон байж болохгүй), UNIQUE (давхардаж болохгүй), DEFAULT (утга өгөөгүй бол юу бичих), CHECK (ямар ч нөхцлийг шаардах). Дүрэм бүрийг санаатайгаар зөрчиж, алдааны мессежийг монголоор уншиж, дараа нь дүрэмд нийцүүлнэ. Төгсгөлд нь constraint-ууд юуг барьж чадахгүйг шударгаар харуулна — тэдгээр нь хүчтэй ч бүхнийг чадагч биш.
Өмнөх хичээлд баганын төрлийг харандаагаар бичсэн зөвлөмжтэй зүйрлэсэн. Constraint бол түүнээс огт өөр зүйл — хүснэгтийн үүдэнд суусан хатуу нягтлан, гартаа батлагдсан журамтай. Мөр бүр хүснэгтэд орохын өмнө нягтлангийн ширээн дээгүүр өнгөрөх ёстой. Журмын нэг заалт зөрчигдвөл маягт буцаагдана, тэр мөр хүснэгтэд орохгүй.
Энэ журам нэг онцгой чанартай: хүснэгтэд бичих гэж буй хэн бүхэнд адилхан үйлчилнэ. DB Browser-оос гараар бичсэн INSERT, таны Python програм, ирээдүйд таны хамт олны бичих өөр програм — бүгд нэг нягтлангаар дамжина. Хэрэв дүрэм таны програмын кодонд л байсан бол өөр програм түүнийг мэдэхгүй өнгөрч болох байсан. Харин хүснэгтийн бүтцэд бичигдсэн дүрэм бол бүх програмын хувьд нэгэн зэрэг хүчинтэй хууль юм. Өгөгдлийн сангийн мэргэжилтнүүд "дүрмийг өгөгдөлд аль болох ойр тавь" гэж хэлдэг нь энэ санаа.
Өмнөх хичээлийн library_events хүснэгтийг энэ удаад журамтай нь дахин зохиоё. library.db-г нээгээд Execute SQL табд ажиллуулаарай (энэ хичээлийн турш Write Changes дарахгүй):
sql
CREATE TABLE library_events (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
fee INTEGER NOT NULL DEFAULT 0
CONSTRAINT fee_not_negative CHECK (fee >= 0),
duration_hours REAL
CHECK (duration_hours > 0 AND duration_hours <= 8),
event_date TEXT NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
UNIQUE (title, event_date)
);Энэ тушаал юу гэж хэлж байна вэ гэвэл: “library_events хүснэгт үүсгэ. title нь хоосон байж болохгүй текст. fee нь хоосон байж болохгүй бүхэл тоо; утга өгөөгүй бол 0 байна; мөн сөрөг байж болохгүй, энэ дүрмийг fee_not_negative гэж нэрлэ. duration_hours нь бутархай тоо бөгөөд 0-ээс их, 8-аас хэтрэхгүй байх ёстой. event_date нь хоосон байж болохгүй текст. created_at нь утга өгөөгүй бол бичигдсэн мөчийн цагийг авна. Мөн нэг өдөр нэг нэртэй хоёр арга хэмжээ байж болохгүй.”
Бүтцийг ажиглая. Ихэнх constraint баганын тодорхойлолтод, төрлийн араас шууд бичигдсэн: fee INTEGER NOT NULL DEFAULT 0 CHECK (...). Нэг баганад хэдэн ч дүрэм зэрэгцүүлэн бичиж болох бөгөөд тэдгээрийг таслалаар биш, зүгээр зайгаар тусгаарладаг. Урт тодорхойлолтыг уншихад хялбар болгохын тулд fee болон duration_hours-ийн CHECK-ийг дараагийн мөрөнд догол мөртэйгөөр шилжүүлсэн — SQL мөр шилжилтийг тоодоггүйг Бүлэг 1-д сурсан. Харин хамгийн сүүлийн мөр UNIQUE (title, event_date) нь аль нэг баганад хамаарахгүй, хүснэгт бүхэлдээ хамаарах дүрэм тул баганын тодорхойлолтуудын араас тусдаа, таслалаар тусгаарлагдан бичигдсэн. Ийм дүрмийг хүснэгтийн түвшний constraint гэдэг бөгөөд нэгээс олон баганыг хамарсан дүрэмд заавал ийм хэлбэр хэрэгтэй.
Одоо нэг хэвийн арга хэмжээ нэмж, бүх дүрмийг давж гарахыг харъя:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('SQL-ийн анхан шат', 15000, 2.0, '2026-11-14');Мессеж: 1 rows affected. Хүснэгт:
id | title | fee | duration_hours | event_date | created_at
---+-------------------+-------+----------------+------------+--------------------
1 | SQL-ийн анхан шат | 15000 | 2.0 | 2026-11-14 | 2026-10-10 08:35:12Энэ query юу гэж хэлж байна вэ гэвэл: “library_events хүснэгтэд SQL-ийн анхан шат арга хэмжээг 15000 төгрөгийн төлбөр, 2 цагийн үргэлжлэх хугацаатай, 11-р сарын 14-нд гэж нэм.” Нягтлан маягтыг шалгаад бүх журамд нийцсэн тул хүлээж авчээ. created_at-ийг бид огт дурдаагүй ч утга нь бөглөгдсөн байна — DEFAULT-ийн ажил. Таны created_at өөр цаг харуулах нь мэдээж, гэхдээ тэр цаг таны компьютерийн цагаас 8 цагаар хоцорч байгааг анзаарч магадгүй. CURRENT_TIMESTAMP нь Улаанбаатарын цагаар бус, дэлхийн стандарт цаг (UTC)-аар бичигддэг. Мэргэжлийн системүүд өгөгдлийн санд цагийг UTC-ээр хадгалж, хэрэглэгчид харуулахдаа орон нутгийн цаг руу хөрвүүлдэг нь тогтсон дадал юм.
Жишээ 1: NOT NULL
Арга хэмжээний огноог мартсан INSERT. Query:
sql
INSERT INTO library_events (title, fee, duration_hours)
VALUES ('Python уншлагын клуб', 0, 1.5);Үр дүн:
NOT NULL constraint failed: library_events.event_dateЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “library_events хүснэгтийн event_date баганад хоосон утга хориглосон дүрэм зөрчигдлөө.” Бид баганын жагсаалтаас event_date-ийг орхисон тул SQLite түүнд NULL оноох гэж оролдсон, гэтэл NOT NULL дүрэм үүнийг хориглосон. Мессеж нь хүснэгт болон баганын нэрийг цэгээр холбож яг таг заадгийг анзаараарай — урт хүснэгттэй ажиллахад энэ нь алдааны эх сурвалжийг шууд олоход тусалдаг. Хүснэгт өөрчлөгдөөгүй, мэссежийн талбарт “rows affected” гэсэн мөр огт гараагүй.
NOT NULL-ийг хэзээ тавих вэ гэдэг бол зохион байгуулалтын шийдвэр юм. Бүлэг 2-ын NULL-ийн хичээлд бид NULL нь "мэдэгдэхгүй" гэсэн утгатай гэж сурсан. Тэгвэл асуулт нь: энэ баганын утга мэдэгдэхгүй байхад мөр утга учиртай хэвээр байх уу? Огноогүй арга хэмжээ гэж байхгүй — хэзээ болохыг нь мэдэхгүй бол зар тараах, танхим захиалах боломжгүй. Тиймээс event_date-д NOT NULL. Харин duration_hours-д тавиагүй: арга хэмжээ хэр удаан үргэлжлэхийг урьдчилж мэдэхгүй байж болох бөгөөд энэ нь арга хэмжээг бүртгэхэд саад болохгүй. Огноогоо нэмээд дахин оролдвол:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Python уншлагын клуб', 0, 1.5, '2026-11-07');Мессеж: 1 rows affected. Хүснэгт одоо хоёр мөртэй.
Жишээ 2: DEFAULT ба түүний хязгаар
Төлбөрийг огт дурдалгүйгээр арга хэмжээ нэмье. Query:
sql
INSERT INTO library_events (title, duration_hours, event_date)
VALUES ('Хүүхдийн үлгэрийн цаг', 1.0, '2026-12-05');Мессеж: 1 rows affected. Шинэ мөр:
id | title | fee | duration_hours | event_date | created_at
---+-----------------------+-----+----------------+------------+--------------------
3 | Хүүхдийн үлгэрийн цаг | 0 | 1.0 | 2026-12-05 | 2026-10-10 08:37:40Энэ query юу гэж хэлж байна вэ гэвэл: “library_events хүснэгтэд Хүүхдийн үлгэрийн цагийг 1 цагийн хугацаатай, 12-р сарын 5-нд гэж нэм.” fee багана NOT NULL боловч алдаа гараагүй, учир нь баганын жагсаалтаас орхигдсон үед SQLite DEFAULT-ийн 0-ийг бичсэн. Өмнөх хичээлд "үнэгүй" гэсэн үгээр бичигдэж байсан арга хэмжээ одоо зөв бүхэл тоо 0-тэй боллоо. DEFAULT ба NOT NULL хоёр хамтдаа маш түгээмэл хослол юм: "энэ утга заавал байх ёстой, гэхдээ ихэнх тохиолдолд ердийн утга нь тодорхой."
Одоо DEFAULT-ийн нэг нарийн хязгаарыг харъя. Хэрэв fee-г баганын жагсаалтад нэрлээд, утгад нь NULL-ийг ил тод өгвөл:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Шатрын тэмцээн', NULL, 3.0, '2026-11-28');Үр дүн:
NOT NULL constraint failed: library_events.feeЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “library_events хүснэгтийн fee баганад хоосон утга хориглосон дүрэм зөрчигдлөө.” DEFAULT яагаад 0-ийг бичсэнгүй вэ? Учир нь DEFAULT зөвхөн багана огт дурдагдаагүй үед л ажилладаг. Та NULL гэж ил тод хэлсэн бол SQLite таныг "энэ баганад NULL бичмээр байна" гэж хүссэн гэж ойлгодог — тэгээд NOT NULL дүрэм түүнийг зогсоосон. Хэрэв fee дээр NOT NULL байгаагүй бол NULL чимээгүйхэн хадгалагдах байсан. Энэ ялгаа Python-оос өгөгдөл илгээх үед чухал болдог: хоосон талбарыг None болгон илгээдэг код DEFAULT-ийг тойрч гардаг.
Жишээ 3: UNIQUE
Python уншлагын клубыг санамсаргүйгээр хоёр дахь удаа, ижил өдөр бүртгэх гэж оролдъё. Query:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Python уншлагын клуб', 0, 1.5, '2026-11-07');Үр дүн:
UNIQUE constraint failed: library_events.title, library_events.event_dateЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “library_events хүснэгтэд title ба event_date-ийн хослол давхардахгүй байх дүрэм зөрчигдлөө.” 11-р сарын 7-нд “Python уншлагын клуб” аль хэдийн бүртгэгдсэн тул хоёр дахь нь татгалзагдсан. Мессеж хоёр баганыг хоёуланг нь нэрлэж байгаа нь дүрэм тэдгээрийн хослолд хамаарч байгааг харуулж байна.
Одоо ижил клубыг дараагийн долоо хоногт бүртгэе:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Python уншлагын клуб', 0, 1.5, '2026-11-14');Мессеж: 1 rows affected. Нэр нь ижил, огноо нь өөр — хослол нь шинэ тул зөвшөөрөгдсөн. Энэ бол яг бидний хүссэн зүйл: уншлагын клуб долоо хоног бүр болдог тул нэр давтагдах нь хэвийн, харин нэг өдөр хоёр удаа бүртгэгдэх нь алдаа. Хэрэв бид зөвхөн title TEXT UNIQUE гэж тавьсан бол давтагдах арга хэмжээ огт бүртгэгдэх боломжгүй болох байсан. UNIQUE тавихын өмнө "яг юу давхардаж болохгүй вэ" гэдгийг нарийн бодох хэрэгтэй гэдгийг энэ жишээ харуулж байна. Гишүүний имэйл (нэг имэйл — нэг гишүүн) бол ганц баганын UNIQUE-ийн сонгодог жишээ.
Жишээ 4: CHECK
Сөрөг төлбөр бүхий арга хэмжээ — магадгүй хөнгөлөлтийг буруу оруулсан. Query:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Монгол түүхийн яриа', -5000, 1.25, '2026-11-21');Үр дүн:
CHECK constraint failed: fee_not_negativeЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “fee_not_negative гэж нэрлэсэн шалгах дүрэм зөрчигдлөө.” CHECK нь хаалт доторх нөхцлийг мөр бүрт шалгадаг — WHERE-ийн нөхцөлтэй яг ижил хэлбэртэй — бөгөөд нөхцөл худал гарвал мөрийг татгалздаг. Бид энэ дүрэмд CONSTRAINT түлхүүр үгээр нэр өгсөн тул мессеж тэр нэрийг харуулж, юу буруу болсныг шууд ойлгомжтой болгосон.
Нэргүй CHECK-ийн үед юу болохыг харъя. Хугацааг 0 гэж бичье:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Монгол түүхийн яриа', 5000, 0, '2026-11-21');Үр дүн:
CHECK constraint failed: duration_hours > 0 AND duration_hours <= 8Энэ мессеж юу гэж хэлж байна вэ гэвэл: “duration_hours нь 0-ээс их бөгөөд 8-аас хэтрэхгүй байх шалгалт зөрчигдлөө.” Нэргүй үед SQLite нөхцлийн текстийг өөрийг нь харуулдаг. Энэ ч мөн ойлгомжтой, гэвч нөхцөл урт, төвөгтэй болох тусам нэр нь илүү хурдан уншигддаг. Олон багтай төсөлд CHECK-д нэр өгөх нь сайн дадал юм. Хоёр утгыг засаад дахин оролдвол:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Монгол түүхийн яриа', 5000, 1.25, '2026-11-21');Мессеж: 1 rows affected. Хүснэгт одоо таван мөртэй:
id | title | fee | duration_hours | event_date
---+-----------------------+-------+----------------+-----------
1 | SQL-ийн анхан шат | 15000 | 2.0 | 2026-11-14
2 | Python уншлагын клуб | 0 | 1.5 | 2026-11-07
3 | Хүүхдийн үлгэрийн цаг | 0 | 1.0 | 2026-12-05
4 | Python уншлагын клуб | 0 | 1.5 | 2026-11-14
5 | Монгол түүхийн яриа | 5000 | 1.25 | 2026-11-21(created_at баганыг товчлох үүднээс орхисон.) Татгалзагдсан оролдлогууд нэг ч ул мөр үлдээгээгүйг анзаараарай — тэдгээр нь id ч эзлээгүй. Мөн Бүлэг 3-т сурсанчлан олон мөртэй INSERT-ийн нэг мөр нь дүрэм зөрчвөл бүх мөр хамт татгалзагддаг. Нягтлан багц маягтыг бүхэлд нь буцаадаг.
Жишээ 5: constraint-уудын шударга хязгаар
Constraint-ууд хүчтэй боловч NULL-ийн тухай Бүлэг 2-т сурсан гурван утгат логик тэдгээрт ч үйлчилдэг бөгөөд энэ нь хоёр гайхмаар үр дагавартай. Нэгдүгээрт, CHECK нь нөхцөл "худал" гарсан үед л татгалздаг — "мэдэхгүй" гарвал зөвшөөрдөг. Хэрэв duration_hours-ийг NULL гэж өгвөл NULL > 0 нь "мэдэхгүй" болж, CHECK нэвтрүүлнэ. Энэ нь ихэнхдээ бидний хүссэн зүйл: "хугацаа нь мэдэгдэж байвал 0-8 цагийн хооронд байх ёстой, мэдэгдэхгүй бол зүгээр." Хэрэв утга заавал байх ёстой бол CHECK дээр нэмээд NOT NULL тавих хэрэгтэй — fee-д бид яг тэгж хийсэн. Хоёрдугаарт, UNIQUE нь олон NULL-ийг зөвшөөрдөг: хоёр NULL "тэнцүү" гэж батлагдаагүй тул давхардал гэж тооцогддоггүй. Хэрэв гишүүний имэйлд UNIQUE тавьсан бол имэйлгүй (NULL) олон гишүүн хамт бүртгэгдэж чадна — энэ нь бас ихэнхдээ зөв.
Гурав дахь хязгаар нь өмнөх хичээлтэй холбоотой. Төлбөрт "үнэгүй" гэдэг текстийг бичихийг оролдвол юу болох вэ? Query:
sql
INSERT INTO library_events (title, fee, duration_hours, event_date)
VALUES ('Шатрын тэмцээн', 'үнэгүй', 3.0, '2026-11-28');Мессеж: 1 rows affected. Энэ query юу гэж хэлж байна вэ гэвэл: “library_events хүснэгтэд Шатрын тэмцээнийг 'үнэгүй' гэсэн төлбөртэйгөөр нэм.” Нэвтэрчихлээ. NOT NULL саатуулсангүй, учир нь 'үнэгүй' нь NULL биш. CHECK саатуулсангүй, учир нь өмнөх хичээлд харсанчлан SQLite-д текст бүх тооноос их гэж тооцогддог — 'үнэгүй' >= 0 нь үнэн. Бидний дүрэм "сөрөг биш байх" гэж хэлсэн, "тоо байх" гэж хэлээгүй. Хэрэв SQLite дээр үүнийг ч хориглохыг хүсвэл CHECK (typeof(fee) = 'integer') гэсэн нэмэлт дүрэм тавьж болно — энэ нь өмнөх хичээлийн typeof() функцийг нягтлангийн журамд оруулах арга юм. PostgreSQL-д энэ шаардлагагүй, учир нь тэнд төрөл өөрөө хууль. Эндээс гарах сургамж: constraint тавихдаа "энэ дүрэм юуг хориглож байна" гэж бодохоос гадна "юуг хориглохгүй байна вэ" гэж асуух хэрэгтэй.
Одоо Бүлэг 1-ийн бэлтгэлийн скриптийг шинэ нүдээр уншиж болно. books хүснэгтийн title TEXT NOT NULL нь нэргүй ном бүртгэхийг хориглосон хууль байсан бөгөөд Бүлэг 3-ын INSERT хичээлд та түүнийг зөрчиж үзсэн. id INTEGER PRIMARY KEY нь өөртөө UNIQUE ба автомат дугаарлалтыг агуулсан тусгай дүрэм бөгөөд дараагийн хичээлийн сэдэв юм. Харин copies INTEGER дээр ямар ч дүрэм байгаагүй — өөрөөр хэлбэл хэн нэгэн -3 хувь бүртгэхэд нягтлан саатуулахгүй. Хэрэв таны хүснэгт зохиох байсан бол copies INTEGER NOT NULL DEFAULT 1 CHECK (copies >= 0) гэж бичих байсан болов уу. Түвшин 2-ын удирдамжтай дасгалд бид номын сангийн бүтцийг яг ийм дүрмүүдтэйгээр шинээр зохионо.
Бид Write Changes дараагүй тул Revert Changes дарахад library_events хүснэгт алга болно. Database Structure табд зөвхөн books, members үлдсэн эсэхийг шалгаарай.
Хэрэв сонирхож байвал гишүүдийн хүснэгтийн журамтай хувилбарыг зохиож үзээрэй: нэр NOT NULL, имэйл UNIQUE, элссэн он нь 2000-аас багагүй байх CHECK, хот нь утга өгөөгүй бол 'Улаанбаатар' гэсэн DEFAULT. Дараа нь дүрэм бүрийг нэг нэгээр нь санаатайгаар зөрчиж, алдааны мессеж бүрийг монголоор чангаар уншаарай. Мөн имэйлгүй хоёр гишүүн нэмж, UNIQUE олон NULL-ийг зөвшөөрдгийг өөрийн нүдээр шалгаж болно. Дуусаад Revert Changes дарна. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Энэ хичээлийн гол алдааны мессежүүдийг (NOT NULL constraint failed, UNIQUE constraint failed, CHECK constraint failed) дээрх жишээнүүдэд нарийвчлан уншсан. Энд constraint бичих үеийн алдаануудыг харъя.
CHECK-ийн хаалтыг мартах. CHECK fee >= 0 гэж хаалтгүй бичвэл near "fee": syntax error гарна. Энэ мессеж юу гэж хэлж байна вэ гэвэл: “fee гэдэг үгийн ойролцоо SQL-ийн дүрэм зөрчигдлөө.” CHECK-ийн нөхцөл заавал хаалтанд байх ёстой: CHECK (fee >= 0). Энэ нь IN-ий жагсаалтын хаалттай адил албан ёсны шаардлага.
Хүснэгтийн түвшний constraint-ыг баганын хооронд бичих. UNIQUE (title, event_date) мөрийг баганын тодорхойлолтуудын дунд бичвэл зарим тохиолдолд SQLite хүлээн авдаг ч олон өгөгдлийн санд алдаа өгдөг бөгөөд уншихад төөрөгдүүлдэг. Хүснэгтийн түвшний дүрмүүдийг бүх баганын дараа, хаах хаалтын өмнө бичих нь стандарт дадал юм.
DEFAULT-ийн утгыг буруу төрлөөр өгөх. fee INTEGER DEFAULT 'үнэгүй' гэж бичвэл SQLite хүснэгтийг үүсгэж, утга өгөөгүй мөр бүрт текстийг чимээгүйхэн бичнэ — өмнөх хичээлийн асуудлыг өөрийн гараар буцаан авчирна. DEFAULT-ийн утга баганын төрөлд нийцэх ёстой.
Байгаа өгөгдөлтэй хүснэгтэд дүрэм нэмэх гэж оролдох. SQLite байгаа хүснэгтэд CHECK, NOT NULL, UNIQUE-ийг дараа нь нэмэх энгийн аргагүй. Энэ хязгаарыг Бүлэг 4-ийн сүүлийн хичээлд ALTER-ийн тухай ярихдаа шударгаар харуулах бөгөөд яг ийм хязгаарлалтууд нь Бүлэг 13-ын migration-ий хэрэгцээг тайлбарлана. Тиймээс дүрмүүдийг хүснэгт зохиох үед, анхнаасаа бодох нь хамгийн хялбар.
Constraint-ыг хэт хатуу тавих. title TEXT UNIQUE гэж тавьсан бол Python уншлагын клуб долоо хоног бүр бүртгэгдэх боломжгүй болох байсан. Хэт хатуу дүрэм нь хэт сул дүрмээс дутахгүй асуудал үүсгэдэг: хэрэглэгчид хууль ёсны өгөгдлөө оруулж чадахгүй болж, дүрмийг тойрох арга хайж эхэлнэ (жишээ нь нэрийн араас “(2)” гэж нэмэх). Дүрэм бүрийг бодит амьдралын жишээгээр шалгаарай.
Энэ хичээлд та баганын төрлөөс ялгаатай нь жинхэнэ хууль шиг мөрдөгддөг дөрвөн constraint-ыг сурлаа. NOT NULL нь хоосон утгыг хориглодог; түүнийг "энэ утгагүйгээр мөр утга учиргүй болох уу" гэсэн асуултаар сонгоно. DEFAULT нь багана огт дурдагдаагүй үед утга бөглөдөг, харин ил тод өгсөн NULL-ийг орлохгүй. UNIQUE нь нэг баганын эсвэл хэд хэдэн баганын хослолын давхардлыг хориглодог; "яг юу давхардаж болохгүй вэ" гэдгийг нарийн бодох хэрэгтэй. CHECK нь дурын нөхцлийг шаарддаг бөгөөд нэр өгөхөд алдааны мессеж илүү ойлгомжтой болно. Дүрэм зөрчсөн мөр хүснэгтэд огт орохгүй. Мөн constraint-ууд NULL-ийн гурван утгат логикийг дагадаг тул CHECK "мэдэхгүй"-г нэвтрүүлж, UNIQUE олон NULL-ийг зөвшөөрдгийг, SQLite дээр CHECK (fee >= 0) текстийг барьж чадахгүйг шударгаар харлаа.
Дараагийн хичээлд бид бүх хүснэгтийн суурь болсон, бусдаас онцгой нэгэн constraint — PRIMARY KEY-г гүнзгий судална. Мөр бүрийн давтагдашгүй дугаар яагаад хэрэгтэй, автомат дугаарлалт хэрхэн ажилладаг, байгалийн ба орлуулагч түлхүүр гэж юу вэ, мөн зарим системүүд яагаад энгийн тооны оронд урт санамсаргүй тэмдэгт мөрийг дугаар болгон ашигладаг вэ гэдгийг харна.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.