Ачааллж байна...
Бүлэг 1-ээс хойш бидний бүх хүснэгтийн эхний багана нэг ижил хэлбэртэй байсан: id INTEGER PRIMARY KEY. Бид түүнийг "мөр бүрийн давтагдашгүй дугаар" гэж товч тайлбарлаж, Бүлэг 3-т UPDATE, DELETE хийхдээ нэр биш id-аар шүүх нь хамгийн найдвартай гэдгийг удирдамжтай дасгал дээр харсан. Гэвч яагаад? Нэг мөрийг бусдаас ялгах ийм дугаар яагаад заавал хэрэгтэй, тэр нь хаанаас ирдэг, ямар байх ёстой вэ?
Энэ хичээлд PRIMARY KEY-ийг бүхэлд нь задална. Эхлээд түүний мөн чанар — мөрийн хэн болохыг (identity) тодорхойлох — гэдгийг ойлгоно. Дараа нь SQLite-ийн автомат дугаарлалт хэрхэн ажилладгийг, тэр дундаа олон хүнийг гайхшруулдаг нэг зан — устгасан дугаарыг дахин ашиглах — гэдгийг өөрийн нүдээр харна. Үүний дараа хүснэгт зохиогч бүрийн өмнө тулгардаг сонголтыг харна: бодит ертөнцөөс ирсэн утгыг (ISBN, имэйл) түлхүүр болгох уу, эсвэл утга агуулаагүй тусгай дугаар үүсгэх үү.
Хамгийн сүүлд нэг бодит жишээ үзнэ: таны одоо уншиж буй энэ сургалтын платформ мөрүүдээ энгийн 1, 2, 3 гэсэн тоогоор биш, урт санамсаргүй тэмдэгтүүдээр дугаарладаг. Яагаад ингэдгийг ойлгосноор түлхүүр сонгох нь техникийн бус, харин зохион байгуулалтын шийдвэр гэдгийг мэдрэх болно.
PRIMARY KEY бол иргэний бүртгэлийн дугаар юм. Нэг улсад ижил нэртэй мянга мянган хүн байж болно, ижил хотод төрсөн, ижил оны хүн ч олон. Нэр, хот, он нь хүнийг тайлбарладаг ч хэн болохыг нь баталдаггүй. Харин бүртгэлийн дугаар нь нэг хүнд нэг удаа олгогдож, өөр хэнд ч давхардахгүй, амьдралынх нь туршид өөрчлөгддөггүй. Аль нэг байгууллага "энэ хүн мөн үү" гэж эргэлзвэл нэрээр биш, дугаараар шалгадаг.
Хүснэгтийн мөр бүр ийм дугаартай байх ёстой. Хоёр гишүүн хоёулаа "Бат" нэртэй, хоёулаа Улаанбаатарт амьдардаг байж болно. Хэрэв бид "Бат"-ын имэйлийг засах гэвэл аль Бат вэ? Нэрээр нь UPDATE хийвэл хоёулангийнх нь засагдана — Бүлэг 3-ын удирдамжтай дасгалд Inception болон Inceptoin-ий жишээнд яг үүнтэй төстэй аюулыг харсан. PRIMARY KEY нь энэ асуултад үргэлж ганц хариулт өгдөг: “id нь 1 байгаа Бат.” Дараагийн бүлэгт хүснэгтүүдийг хооронд нь холбож эхлэхэд энэ дугаар бүр ч чухал болно — нэг хүснэгт өөр хүснэгтийн мөр рүү яг энэ дугаараар заадаг.
PRIMARY KEY нь өмнөх хичээлийн constraint-уудын нэгэн төрөл боловч онцгой үүрэгтэй. Энэ нь хоёр зүйлийг баталдаг: багана дахь утга бүр давхардахгүй (UNIQUE), мөн утга заавал байх ёстой (NOT NULL) — дугааргүй мөр гэж байх ёсгүй. Нэг хүснэгт ганц л PRIMARY KEY-тэй байж болно, учир нь мөр бүр нэг л "хэн болохыг" тодорхойлох дугаартай. Харин тэр түлхүүр нэгээс олон баганаас бүрдэж болох бөгөөд үүнийг Бүлэг 5-д хүснэгтүүдийг холбох тусгай хүснэгттэй танилцахдаа харна.
SQLite-ийн тухай шударга нэг анхааруулга: түүхэн шалтгаанаар SQLite нь INTEGER PRIMARY KEY-ээс бусад төрлийн PRIMARY KEY-д NOT NULL-ийг автоматаар мөрдүүлдэггүй. Энэ нь SQLite-ийн эхний хувилбаруудын алдаа байсан бөгөөд хуучин програмуудыг эвдэхгүйн тулд засаагүй үлдээсэн. Үр дагаврыг нь доорх жишээнд өөрийн нүдээр харна.
Номын сангийн тавиурын шошгыг бүртгэх энгийн хүснэгт үүсгэе. library.db-г нээгээд ажиллуулаарай (энэ хичээлийн турш Write Changes дарахгүй):
sql
CREATE TABLE shelves (
id INTEGER PRIMARY KEY,
label TEXT NOT NULL
);
INSERT INTO shelves (label)
VALUES ('Түүх'), ('Уран зохиол'), ('Програмчлал');Хүснэгт:
id | label
---+------------
1 | Түүх
2 | Уран зохиол
3 | ПрограмчлалЭнэ тушаал юу гэж хэлж байна вэ гэвэл: “shelves хүснэгт үүсгэ — id нь бүхэл тоон түлхүүр, label нь хоосон байж болохгүй текст; дараа нь гурван тавиурыг зөвхөн label-тайгаар нэм.” Бид id-ийг нэг ч удаа дурдаагүй ч SQLite 1, 2, 3 гэж дараалуулан олгосон. Энэ нь SQLite-д INTEGER PRIMARY KEY гэсэн яг энэ хоёр үгийн хослолын онцгой зан юм: ийм багана нь SQLite-ийн мөр бүрт дотроо хадгалдаг дугаартай (rowid) нэг зүйл болдог бөгөөд утга өгөөгүй бол хүснэгтийн хамгийн их дугаар дээр нэгийг нэмж олгодог.
Мөн энэ баганад SQLite-ийн сул төрөл үйлчилдэггүй. Өмнөх хичээлүүдэд бүхэл тоон баганад текст чимээгүй хадгалагдаж байсныг санаарай. Энд оролдож үзье:
sql
INSERT INTO shelves (id, label) VALUES ('гурав', 'Хүүхдийн ном');Үр дүн:
datatype mismatchЭнэ мессеж юу гэж хэлж байна вэ гэвэл: "өгөгдлийн төрөл таарахгүй байна." INTEGER PRIMARY KEY нь SQLite-д жинхэнэ хатуу төрөлтэй цорын ганц багана — заавал бүхэл тоо байх ёстой. Мөрийн дугаар бол хүснэгтийн суурь тул SQLite энд л зөвлөмжийг хууль болгосон.
Жишээ 1: устгасан дугаарыг дахин ашиглах
Одоо SQLite-ийн автомат дугаарлалтын олон хүнийг гайхшруулдаг занг харъя. Хамгийн их дугаартай тавиурыг (3) устгаад, шинэ тавиур нэмье. Query:
sql
DELETE FROM shelves WHERE id = 3;
INSERT INTO shelves (label) VALUES ('Хүүхдийн ном');Хүснэгт:
id | label
---+-------------
1 | Түүх
2 | Уран зохиол
3 | Хүүхдийн номЭнэ хоёр тушаал юу гэж хэлж байна вэ гэвэл: “id нь 3 байгаа тавиурыг устга, дараа нь Хүүхдийн номын тавиурыг нэм.” Шинэ тавиур 3 гэсэн дугаартай болжээ — саяхан устгагдсан Програмчлалын тавиурын дугаар. SQLite "хамгийн их дугаар дээр нэгийг нэм" гэдэг дүрмээ дагасан: устгасны дараа хамгийн их нь 2 болсон тул шинэ мөр 3 авсан.
Одоо дундах тавиурыг устгаад дахин нэмье:
sql
DELETE FROM shelves WHERE id = 2;
INSERT INTO shelves (label) VALUES ('Шинжлэх ухаан');Хүснэгт:
id | label
---+--------------
1 | Түүх
3 | Хүүхдийн ном
4 | Шинжлэх ухаанЭнэ удаад шинэ мөр 4 авсан бөгөөд 2 гэсэн цоорхой үлдсэн. Хамгийн их дугаар (3) хэвээр байсан тул дүрэм 4 гэж өгсөн. Өөрөөр хэлбэл SQLite зөвхөн төгсгөлийн дугаарыг дахин ашиглаж болох бөгөөд дундах цоорхойг хэзээ ч нөхдөггүй.
Энэ яагаад аюултай байж болох вэ? "Програмчлал" тавиурыг устгахаас өмнө хэн нэгэн “3-р тавиураас Clean Code-ийг авах” гэсэн тэмдэглэл хөтөлсөн гэж бодъё — эсвэл вэб сайтад /shelves/3 гэсэн холбоос хадгалагдсан байж болно. Одоо тэр тэмдэглэл, холбоос хоёулаа Хүүхдийн номын тавиур руу заах болсон. Хэн ч алдааны мессеж харахгүй, зүгээр л буруу газар очно. Иргэний бүртгэлийн дугаарын зүйрлэлээр бол нас барсан хүний дугаарыг шинэ төрсөн хүүхдэд олгосонтой адил — хуучин баримт бичгүүд шинэ хүн рүү заах болно.
Жишээ 2: AUTOINCREMENT — дугаарыг хэзээ ч дахин ашиглахгүй
Хэрэв дугаар дахин ашиглагдах нь таны хувьд хүлээн зөвшөөрөгдөхгүй бол SQLite-д AUTOINCREMENT гэсэн нэмэлт түлхүүр үг бий. Query:
sql
CREATE TABLE rooms (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
);
INSERT INTO rooms (name)
VALUES ('Уншлагын танхим'), ('Хурлын өрөө'), ('Хүүхдийн булан');
DELETE FROM rooms WHERE id = 3;
INSERT INTO rooms (name) VALUES ('Компьютерийн өрөө');Хүснэгт:
id | name
---+------------------
1 | Уншлагын танхим
2 | Хурлын өрөө
4 | Компьютерийн өрөөЭнэ тушаал юу гэж хэлж байна вэ гэвэл: “rooms хүснэгтийг дугаараа хэзээ ч дахин ашигладаггүй автомат дугаарлалттайгаар үүсгэ; гурван өрөө нэм; 3-р өрөөг устга; шинэ өрөө нэм.” Энэ удаад шинэ мөр 4 авсан — 3 устгагдсан ч SQLite түүнийг дахин олгосонгүй. AUTOINCREMENT нь хүснэгт бүрийн урьд нь олгосон хамгийн их дугаарыг тусдаа газар тэмдэглэж, түүнээс бага дугаарыг хэзээ ч ашигладаггүй.
Тэгвэл яагаад үргэлж AUTOINCREMENT ашиглаж болохгүй гэж? SQLite-ийн албан ёсны баримт бичиг өөрөө үүнийг шаардлагагүй бол бүү ашигла гэж зөвлөдөг, учир нь мөр нэмэх бүрт тэр тусдаа тэмдэглэлийг шинэчлэх нэмэлт ажил гардаг. Практик дүрэм: устгасан мөрийн дугаар гаднах ертөнцөд (холбоос, баримт, өөр системд) үлдэх магадлалтай бол AUTOINCREMENT тавь, үгүй бол энгийн INTEGER PRIMARY KEY хангалттай. PostgreSQL-д автомат дугаарлалт анхдагчаар дугаарыг дахин ашигладаггүй тул тэнд энэ асуудал гарахгүй — Бүлэг 10-д үүнийг харна.
Жишээ 3: байгалийн түлхүүр ба SQLite-ийн NULL урхи
Одоо огт өөр төрлийн түлхүүрийг харъя. Ном бүр ISBN гэсэн олон улсын давтагдашгүй дугаартай байдаг. Тэгвэл тусдаа id үүсгэхийн оронд ISBN-ийг өөрийг нь PRIMARY KEY болгож болохгүй гэж үү? Бодит ертөнцөд аль хэдийн байгаа, утга агуулсан ийм түлхүүрийг байгалийн түлхүүр (natural key) гэдэг. Query:
sql
CREATE TABLE editions (
isbn TEXT PRIMARY KEY,
title TEXT NOT NULL
);
INSERT INTO editions (isbn, title)
VALUES
('978-0132350884', 'Clean Code'),
('978-1593276034', 'Python Crash Course');Хүснэгт:
isbn | title
---------------+--------------------
978-0132350884 | Clean Code
978-1593276034 | Python Crash CourseЭнэ тушаал юу гэж хэлж байна вэ гэвэл: “editions хүснэгтийг ISBN-ийг түлхүүр болгон үүсгэ, дараа нь хоёр номыг ISBN-тай нь нэм.” Давхардал хориглогдож байгааг шалгая:
sql
INSERT INTO editions (isbn, title) VALUES ('978-0132350884', 'Clean Code (хуулбар)');Үр дүн:
UNIQUE constraint failed: editions.isbnЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “editions хүснэгтийн isbn баганын давхардахгүй байх дүрэм зөрчигдлөө.” PRIMARY KEY нь UNIQUE-ийг баталж байна. Одоо "Монголын нууц товчоо"-г нэмэх гэж оролдъё — XIII зууны бүтээлд ISBN гэж байхгүй:
sql
INSERT INTO editions (isbn, title) VALUES (NULL, 'Монголын нууц товчоо');
INSERT INTO editions (isbn, title) VALUES (NULL, 'Учиртай гурван толгой');Мессеж: хоёр удаа 1 rows affected. Хүснэгт:
isbn | title
---------------+----------------------
978-0132350884 | Clean Code
978-1593276034 | Python Crash Course
NULL | Монголын нууц товчоо
NULL | Учиртай гурван толгойЭнэ хоёр тушаал юу гэж хэлж байна вэ гэвэл: “ISBN-гүйгээр хоёр ном нэм.” Хоёулаа нэвтэрчихлээ. Энэ бол дээр анхааруулсан SQLite-ийн түүхэн урхи юм: TEXT PRIMARY KEY нь NULL-ийг хориглодоггүй, мөн өмнөх хичээлд сурсанчлан UNIQUE нь олон NULL-ийг зөвшөөрдөг. Үр дүнд нь хоёр мөр "дугааргүй" боллоо — тэдгээрийг бие биенээсээ PRIMARY KEY-ээр ялгах боломжгүй, WHERE isbn = ... гэж аль нэгийг нь онилж засах аргагүй. Хэрэв SQLite-д бүхэл тооноос өөр PRIMARY KEY ашиглах бол заавал NOT NULL-ийг ил тод нэмэх хэрэгтэй: isbn TEXT NOT NULL PRIMARY KEY. PostgreSQL-д PRIMARY KEY үргэлж NOT NULL-ийг агуулдаг тул тэнд энэ урхи байхгүй.
Жишээ 3 нь илүү том асуултыг дэвшүүлж байна. NOT NULL нэмбэл SQLite-ийн урхи арилна, гэвч асуудал үлдэнэ: ISBN-гүй номыг одоо огт бүртгэх боломжгүй. Энэ бол байгалийн түлхүүрийн гол сул тал юм — бодит ертөнц бидний хүсэж байгаа шиг цэгцтэй байдаггүй. ISBN 1970-аад оноос өмнөх номонд байдаггүй, нэг ном өөр өөр хэвлэлдээ өөр ISBN-тэй байдаг, заримдаа хэвлэлийн газар алдаатай дугаар хэвлэдэг. Имэйлийг гишүүний түлхүүр болговол гишүүн имэйлээ солиход түүний "хэн болох" өөрчлөгдөнө. Бодит ертөнцийн утга өөрчлөгдөж, алга болж, давхцаж болдог.
Үүний эсрэг шийдэл бол орлуулагч түлхүүр (surrogate key) — ямар ч бодит утга агуулаагүй, зөвхөн мөрийг тодорхойлох зорилгоор үүсгэсэн дугаар. Бидний id INTEGER PRIMARY KEY яг ийм түлхүүр. 7 гэсэн дугаар номын талаар юу ч хэлдэггүй, тиймээс номын талаарх ямар ч мэдээлэл өөрчлөгдсөн ч дугаар нь өөрчлөгдөх шалтгаангүй. ISBN, имэйл зэрэг бодит утгууд энгийн багана болж үлдэх бөгөөд тэдгээрийн давхардлыг хориглох шаардлагатай бол UNIQUE тавина. Ингэснээр бид хоёр давуу талыг хоёуланг нь авна: тогтвортой түлхүүр болон бодит утгын давхардлын хамгаалалт.
Иргэний бүртгэлийн дугаарын зүйрлэл руу буцаж харвал нэг сонирхолтой нарийн зүйл бий. Монгол улсын регистрийн дугаар төрсөн он, сар, өдрийг агуулдаг — өөрөөр хэлбэл бүрэн орлуулагч биш, хагас байгалийн түлхүүр юм. Тиймээс түүнийг өгөгдлийн сангийн PRIMARY KEY болгох нь ихэвчлэн зохимжгүй: хэн нэгний регистрийн дугаар алдаатай бүртгэгдсэн бол засахад бүх холбоос эвдэрнэ, мөн мөр бүрийн дугаар хувийн мэдээллийг ил гаргана. Ихэнх систем хүмүүсийг өөрийн орлуулагч дугаараар таньж, регистрийн дугаарыг хамгаалагдсан тусдаа баганад хадгалдаг. Ерөнхий дүрэм: эргэлзвэл орлуулагч түлхүүр сонго. Байгалийн түлхүүр нь утга нь хэзээ ч өөрчлөгдөхгүй, хэзээ ч дутахгүй гэдэгт үнэхээр итгэлтэй үед л тохиромжтой.
Таны одоо уншиж буй энэ сургалтын платформ мөрүүдээ 1, 2, 3 гэх мэт тоогоор биш, a169d224-... гэж эхэлдэг 36 тэмдэгттэй урт мөрөөр дугаарладаг. Ийм дугаарыг UUID (Universally Unique Identifier — нийтээр давтагдашгүй тодорхойлогч) гэдэг бөгөөд санамсаргүй байдлаар үүсгэгддэг ч давхцах магадлал нь бодит амьдралд тэгтэй тэнцүү. Энэ нь мөн орлуулагч түлхүүр — утга агуулдаггүй — гэхдээ автомат тооноос гурван давуу талтай. Нэгдүгээрт, өгөгдлийн сангаас "дараагийн дугаар хэд вэ" гэж асуулгүйгээр хаана ч, хэзээ ч үүсгэж болно; олон server зэрэг ажиллах үед энэ нь чухал. Хоёрдугаарт, таахын аргагүй: вэб хаягт /courses/7 гэж байвал хэн ч /courses/8-ийг оролдож, сайтад хэдэн сургалт байгааг тооцоолж чадна, харин UUID ийм мэдээлэл задруулдаггүй. Гуравдугаарт, хоёр өөр системийн өгөгдлийг нэгтгэхэд дугаар мөргөлдөхгүй. Мэдээж үнэ бий: UUID нь урт, хүнд уншигдахад хэцүү, хадгалахад илүү зай эзэлдэг. Энэ сургалтын хүснэгтүүдэд бид энгийн бүхэл тоог хэрэглэх бөгөөд энэ нь суралцах үед хамгийн тохиромжтой. Гол санаа нь энгийн: түлхүүрийн төрлийг сонгох нь систем хэрхэн ашиглагдахаас хамаарсан зохион байгуулалтын шийдвэр юм.
Бид Write Changes дараагүй тул Revert Changes дарахад shelves, rooms, editions хүснэгтүүд алга болно. Database Structure табд зөвхөн books, members үлдсэн эсэхийг шалгаарай.
Хэрэв сонирхож байвал rooms хүснэгтийг (AUTOINCREMENT-тэй) дахин үүсгэж, өрөө нэмж, устгаж байгаад Database Structure табыг хараарай — sqlite_sequence гэсэн шинэ хүснэгт гарч ирсэн байх ба SELECT * FROM sqlite_sequence; нь AUTOINCREMENT-ийн "урьд нь олгосон хамгийн их дугаар"-ыг хаана тэмдэглэдгийг харуулна. Мөн editions хүснэгтийг isbn TEXT NOT NULL PRIMARY KEY гэж үүсгээд ISBN-гүй ном нэмэхийг оролдож, ямар алдааны мессеж гарахыг уншаарай. Дуусаад Revert Changes дарна. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Байгаа дугаарыг дахин оруулах. INSERT INTO books (id, title) VALUES (1, 'Шинэ ном'); гэж бичвэл UNIQUE constraint failed: books.id гарна. Энэ алдааг Бүлэг 3-т анх харсан бөгөөд одоо шалтгааныг нь бүрэн ойлгож байна: PRIMARY KEY нь UNIQUE-ийг агуулдаг. Ихэнх тохиолдолд шийдэл нь id-ийг огт бичихгүй, SQLite-д олгуулах юм.
INT болон INTEGER-ийг андуурах. Энэ бол SQLite-ийн хамгийн нууцлаг урхины нэг. Автомат дугаарлалт зөвхөн INTEGER PRIMARY KEY гэсэн яг энэ үгээр бичсэн үед л ажилладаг. Хэрэв та id INT PRIMARY KEY гэж товчилж бичвэл багана энгийн түлхүүр болж, автомат дугаар олгогдохгүй — харин дээр үзсэн NULL урхины улмаас id-гүй INSERT нь NULL дугаартай мөр үүсгэнэ. Алдааны мессеж гарахгүй. Өмнөх хичээлд “INT” агуулсан төрлийн нэр бүхэл тоон хандлагатай болдог гэж сурсан ч мөрийн дугаарын онцгой зан зөвхөн бүтэн INTEGER үгэнд л хамаарна.
Хоёр PRIMARY KEY зарлах. Хоёр баганад тус бүрд нь PRIMARY KEY бичвэл table "editions" has more than one primary key гарна. Энэ мессеж юу гэж хэлж байна вэ гэвэл: “editions хүснэгт нэгээс олон үндсэн түлхүүртэй байна.” Нэг хүснэгт нэг л "хэн болох" дугаартай. Хэрэв хоёр баганын хослол мөрийг тодорхойлдог бол хүснэгтийн түвшинд PRIMARY KEY (a, b) гэж нэг түлхүүр болгон бичнэ — Бүлэг 5-д үүнийг ашиглана. Хэрэв хоёр дахь багана зөвхөн давхардах ёсгүй бол түүнд UNIQUE тавина.
Мөрийн дугаарыг өөрчлөх. UPDATE books SET id = 100 WHERE id = 1; нь техникийн хувьд ажиллана, гэвч дугаарыг өөрчлөх нь иргэний бүртгэлийн дугаарыг солихтой адил: тэр дугаар руу заасан бүх зүйл эвдэрнэ. Одоогоор бидний хүснэгтүүд бие бие рүүгээ заадаггүй тул хор хөнөөл харагдахгүй ч дараагийн бүлэгт хүснэгтүүдийг холбосны дараа энэ нь ноцтой асуудал болно. Дүрэм: PRIMARY KEY-ийн утгыг нэг удаа олгоод хэзээ ч бүү өөрчил.
Цоорхойг нөхөх гэж оролдох. Жишээ 1-ийн дараа 2 гэсэн цоорхойг хараад олон хүн дугааруудыг "цэгцлэх" гэж UPDATE хийхийг хүсдэг. Үүнийг бүү хий. Дугаар нь мөрийн хэн болохыг тодорхойлдог, дарааллыг нь биш — цоорхой нь зүгээр л "энд нэг мөр байсан, одоо байхгүй" гэсэн үнэн. Иргэний бүртгэлд ч цоорхойтой дугаарууд бий.
Энэ хичээлд та PRIMARY KEY-ийг мөр бүрийн хэн болохыг тодорхойлох давтагдашгүй, заавал байх, хүснэгтэд ганцхан байх дугаар гэж ойлголоо. SQLite-д INTEGER PRIMARY KEY нь автоматаар дугаар олгодог, бүхэл тооноос өөр утгыг хүлээн авдаггүй бөгөөд хамгийн их дугаарыг устгавал түүнийг дахин ашиглаж болох юм; үүнийг хориглохыг хүсвэл AUTOINCREMENT нэмнэ. Бүхэл тооноос өөр PRIMARY KEY-д SQLite NOT NULL-ийг мөрдүүлдэггүй тул ил тод нэмэх хэрэгтэй, мөн INT PRIMARY KEY нь INTEGER PRIMARY KEY-тэй адилгүй. Байгалийн түлхүүр (ISBN, имэйл) нь бодит ертөнцийн өөрчлөлт, дутагдалд эмзэг тул ихэнх тохиолдолд утга агуулаагүй орлуулагч түлхүүр илүү найдвартай, бодит утгуудыг UNIQUE-ээр хамгаална. UUID бол олон системд хэрэглэгддэг орлуулагч түлхүүрийн өөр нэг хэлбэр юм.
Дараагийн хичээлээр Бүлэг 4 дуусна. Хүснэгтийг үүсгэсний дараа түүнийг хэрхэн өөрчлөх вэ — шинэ багана нэмэх, нэр солих — гэдгийг ALTER TABLE-ээр сурна. Мөн SQLite-д байгаа хүснэгтийг өөрчлөх боломж хэр хязгаарлагдмал болохыг, яагаад бодит төслүүд хүснэгтийн бүтцийн өөрчлөлтийг тусгай аргаар — migration-аар — удирддагийг шударгаар харуулна.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.