SQL Updates (SQL နဲ့ ဒေတာ ပြင်ဆင်ခြင်း)
A3.3.3: Explain how SQL can be used to update data in a database (INSERT INTO, UPDATE SET, DELETE), including the performance implications of updating data in indexed columns, and how indexes might need to be rebuilt or reorganized following significant data modifications.
မြန်မာလို: A3.3.3: database ထဲက ဒေတာကို update (ပြင်ဆင်ပြောင်းလဲ) လုပ်ဖို့ SQL ကို ဘယ်လို သုံးနိုင်လဲ (INSERT INTO, UPDATE SET, DELETE) ဆိုတာကို explain (ရှင်းပြ) လုပ်နိုင်ရပါမယ်။ Index (ရှာတာ မြန်အောင် လုပ်ထားတဲ့ ညွှန်းစာရင်း) လုပ်ထားတဲ့ column တွေထဲက ဒေတာကို update လုပ်ရင် မြန်နှုန်းအပေါ် ဘယ်လို သက်ရောက်လဲ၊ ဒေတာ အများကြီး ပြောင်းပြီးရင် index တွေကို ပြန်တည်ဆောက်တာ ဒါမှမဟုတ် ပြန်စီစဉ်တာ လိုနိုင်တယ် ဆိုတာလည်း ပါပါတယ်။ A3.3.3 က IB Computer Science (နိုင်ငံတကာ ကျောင်းတွေမှာ သင်တဲ့ ကွန်ပျူတာသိပ္ပံ သင်ရိုး) ရဲ့ သင်ရိုးထဲက အပိုင်း နံပါတ်ပါ။
အဓိက အယူအဆများ
ဒေတာကို ပြောင်းတဲ့ DML Command သုံးခု
Database ထဲမှာ ဒေတာ ရှိလာပြီဆိုရင် နေ့စဉ် အလုပ် အများစုမှာ Data Manipulation Language (DML) command သုံးခုကို သုံးပါတယ်။ DML command တွေဆိုတာ table (database ထဲက ဇယား) တွေထဲက row (အလျားလိုက် အတန်း) တွေနဲ့ အလုပ်လုပ်တဲ့ SQL command (ကွန်ပျူတာကို ပေးတဲ့ ညွှန်ကြားချက်) တွေပါ:
| Command | ဘာလုပ်လဲ |
|---|---|
INSERT INTO | Table တစ်ခုထဲကို row အသစ် တစ်ခု ဒါမှမဟုတ် ပိုများများ ထည့်ပါတယ်။ |
UPDATE ... SET ... | ရှိပြီးသား row တွေထဲက တန်ဖိုးတွေကို ပြောင်းပါတယ်။ |
DELETE FROM | Table ထဲက ရှိပြီးသား row တွေကို ဖယ်ရှားပါတယ်။ |
SELECT (SQL Queries မှာ လေ့လာခဲ့ပြီးပါပြီ) က စတုတ္ထ DML command ပါ: ဒေတာကို မပြောင်းဘဲ ဖတ်ပါတယ်။ ဒီစာမျက်နှာက command သုံးခုကတော့ သိမ်းထားတဲ့ ဒေတာကို ပြောင်း ပါတယ်။
UPDATE နဲ့ DELETE မှာ WHERE clause (keyword တစ်ခုနဲ့ စတဲ့ statement ရဲ့ အပိုင်း) က ပြောင်းမယ့် ဒါမှမဟုတ် ဖယ်မယ့် row တွေကို ရွေးပါတယ်။ WHERE clause မပါရင် statement (code ထဲက ညွှန်ကြားချက်) က table ထဲက row တိုင်းအပေါ် သက်ရောက်ပါတယ်။
INSERT INTO (row အသစ် ထည့်ခြင်း)
INSERT INTO က row အသစ် တစ်ခု ထည့်ပါတယ်။ အသုံးများတဲ့ ပုံစံ နှစ်မျိုး ရှိပါတယ်။
Column စာရင်းကို ထင်ရှားအောင် ရေးတဲ့ ပုံစံ (ဒါကို သုံးဖို့ အကြံပြုပါတယ်):
INSERT INTO Member (MemberID, FirstName, Surname, DateOfBirth, Tier)
VALUES (1005, 'Lila', 'Okafor', '1989-02-11', 'Premium');
Column စာရင်းက တန်ဖိုး တစ်ခုစီ ဘယ် column (ဒေါင်လိုက် ကော်လံ) ထဲ ဝင်မလဲ ဆိုတာကို ပြပါတယ်။ ဒီပုံစံက table ပြောင်းသွားရင်လည်း ဆက်အလုပ်လုပ်ပါတယ်: column အသစ် တစ်ခု ထည့်လိုက်လည်း ရှိပြီးသား INSERT statement တွေ ပျက်မသွားပါဘူး၊ column အသစ်မှာ default value (သတ်မှတ်မထားရင် သုံးတဲ့ တန်ဖိုး) ရှိရင် ဒါမှမဟုတ် NULL (တန်ဖိုး မရှိခြင်း) ကို ခွင့်ပြုထားရင်ပေါ့။
နေရာအလိုက် ပုံစံ (ပိုတိုပေမယ့် ပျက်လွယ်ပါတယ်):
INSERT INTO Member
VALUES (1005, 'Lila', 'Okafor', '1989-02-11', 'Premium');
Column တိုင်းအတွက် တန်ဖိုး ပေးရပြီး table ကို ဖန်တီးတုန်းက column တွေကို ကြေညာခဲ့တဲ့ အစဉ်အတိုင်း ပေးရပါမယ်။ နောက်မှ table ထဲ column တစ်ခု ထပ်ထည့်ရင် DBMS (database management system: ဒေတာကို သိမ်းပြီး statement တွေကို run ပေးတဲ့ software) က ဒီ statement ကို လက်မခံတော့ပါဘူး၊ ဘာလို့လဲဆိုတော့ column တိုင်းအတွက် တန်ဖိုး မရှိတော့လို့ပါ။ တကယ် သုံးမယ့် code မှာ column စာရင်း ပါတဲ့ ပုံစံကို သုံးပါ။
Row အများကို တစ်ပြိုင်နက် ထည့်ခြင်း:
INSERT INTO Member (MemberID, FirstName, Surname, DateOfBirth, Tier) VALUES
(1006, 'Daniel', 'Park', '1978-09-04', 'Standard'),
(1007, 'Hiroshi', 'Tanaka', '1992-06-21', 'Premium'),
(1008, 'Mei', 'Wong', '2001-11-17', 'Standard');
တခြား query (database ထဲက ဒေတာကို ရှာ၊ ပြင်ဖို့ ပေးတဲ့ အမိန့်) တစ်ခုကနေ ထည့်ခြင်း:
INSERT INTO PremiumMailing (MemberID, FirstName, Surname)
SELECT MemberID, FirstName, Surname
FROM Member
WHERE Tier = 'Premium';
PremiumMailing က MemberID, FirstName နဲ့ Surname column တွေ ပါတဲ့ ဒုတိယ table တစ်ခုပါ။ ဒီ statement တစ်ခုတည်းက Premium အသင်းဝင် အားလုံးကို အဲဒီ table ထဲ ကူးထည့်ပါတယ်: SELECT က row တွေကို ရှာပြီး INSERT INTO က သူတို့ကို ထည့်ပါတယ်။
INSERT ကို DBMS က ငြင်းနိုင်တဲ့ အခြေအနေများ:
- Table ထဲမှာ ရှိပြီးသား primary key (row တစ်ခုချင်းကို ခွဲခြားပေးတဲ့ key) တန်ဖိုး (မထပ်ရဘူး ဆိုတဲ့ စည်းမျဉ်းကို ချိုးဖောက်ခြင်း)။
- ညွှန်းထားတဲ့ table ထဲမှာ ကိုက်ညီတဲ့ row မရှိတဲ့ foreign key (တခြား table ရဲ့ primary key ကို ညွှန်းတဲ့ column) တန်ဖိုး။ ဒါက referential integrity (foreign key တွေ မှန်ကန်စွာ ချိတ်ထားရမယ့် စည်းမျဉ်း) ကို ချိုးဖောက်ပါတယ်: foreign key တန်ဖိုး တိုင်းက ရှိပြီးသား row တစ်ခုနဲ့ ကိုက်ရမယ် ဆိုတဲ့ စည်းမျဉ်းပါ။
- Column အတွက် data type (ဒေတာ အမျိုးအစား) မှားနေတဲ့ တန်ဖိုး၊ ဒါမှမဟုတ် constraint (column ပေါ်မှာ သတ်မှတ်ထားတဲ့ စည်းမျဉ်း) ကို ချိုးဖောက်တဲ့ တန်ဖိုး (data integrity (ဒေတာ မှန်ကန်ပြီး မပျက်စီးဘဲ ရှိနေခြင်း) ကို ချိုးဖောက်ခြင်း)။
- Default value မရှိတဲ့
NOT NULLcolumn အတွက် တန်ဖိုး မပေးခြင်း (NULL)။
ငြင်းတိုင်း ဒေတာကို ကာကွယ်ပေးပါတယ်: table ရဲ့ စည်းမျဉ်းတွေကို ချိုးဖောက်မယ့် row တွေကို DBMS က ဝင်ခွင့် မပေးပါဘူး။
UPDATE … SET (ရှိပြီးသား row တွေကို ပြင်ခြင်း)
UPDATE က ရှိပြီးသား row တွေကို ပြောင်းပါတယ်။ ရေးပုံ ဖွဲ့စည်းပုံက ဒီလိုပါ:
UPDATE table
SET column1 = value1,
column2 = value2
WHERE condition;
ဒီမှာ table နေရာမှာ table နာမည်၊ column1, column2 နေရာမှာ ပြောင်းမယ့် column နာမည်တွေ၊ value1, value2 နေရာမှာ တန်ဖိုး အသစ်တွေ၊ condition နေရာမှာ ပြောင်းမယ့် row တွေကို ရွေးတဲ့ condition (မှန်လား မှားလား စစ်တဲ့ အခြေအနေ) ကို ထည့်ရေးရပါတယ်။
Row တစ်ခုကို update လုပ်ခြင်း:
UPDATE Member
SET Tier = 'Premium'
WHERE MemberID = 1001;
Condition နဲ့ ကိုက်တဲ့ row အများကို update လုပ်ခြင်း:
UPDATE Member
SET Tier = 'Premium'
WHERE DateOfBirth < '1980-01-01' AND Tier = 'Standard';
Column ကို သူ့ရဲ့ လက်ရှိ တန်ဖိုးကို သုံးပြီး update လုပ်ခြင်း:
UPDATE Class
SET Capacity = Capacity + 5
WHERE Title LIKE '%Sunrise%';
WHERE clause ကို စစ်ပါ။ WHERE မပါရင် UPDATE Member SET Tier = 'Premium' က အသင်းဝင် အားလုံး ကို Premium ဖြစ်သွားစေပါတယ်။ လုံခြုံတဲ့ အကျင့်က UPDATE ရဲ့ ကျန်တဲ့ အပိုင်းကို မရေးခင် WHERE line ကို အရင် ရိုက်ထားတာပါ။
UPDATE ကို DBMS က ငြင်းနိုင်တဲ့ အခြေအနေများ: INSERT ကို ကာကွယ်တဲ့ စည်းမျဉ်းတွေက UPDATE ကိုလည်း ကာကွယ်ပါတယ်။ Column ကို data type မှားတဲ့ တန်ဖိုး ပေးတဲ့ update၊ မထပ်ရမယ့် တန်ဖိုး (primary key လို) ကို ထပ်သွားစေတဲ့ update၊ ဒါမှမဟုတ် foreign key ကို ကိုက်ညီတဲ့ row မရှိတဲ့ တန်ဖိုး ပေးတဲ့ update ကို DBMS က ငြင်းနိုင်ပါတယ်။
DELETE FROM (row တွေကို ဖျက်ခြင်း)
DELETE FROM က row တွေကို ဖယ်ရှားပါတယ်။ UPDATE လိုပဲ WHERE clause နဲ့ ကိုက်တဲ့ row တွေပေါ်မှာပဲ အလုပ်လုပ်ပါတယ်:
DELETE FROM Booking
WHERE Status = 'cancelled' AND BookedOn < '2024-01-01';
Table ထဲက အရာအားလုံးကို ဖျက်ခြင်း:
DELETE FROM Booking; -- removes every row, table still exists
(Code ထဲက comment ရဲ့ အဓိပ္ပာယ်: row တိုင်းကို ဖယ်ရှားပေမယ့် table ကတော့ ဆက်ရှိနေပါတယ်။)
တစ်ခါတလေ ဒါက လိုချင်တာ ဖြစ်နိုင်ပါတယ်၊ ဒါပေမယ့် DELETE ဒါမှမဟုတ် UPDATE ကနေ WHERE ကို မတော်တဆ ချန်ခဲ့မိတာက လွယ်လွယ်နဲ့ ဖြစ်တတ်ပြီး ဆုံးရှုံးမှု ကြီးတဲ့ အမှားပါ။ ဒီလို statement ကို မ run ခင် စစ်ပါ: mysql လို command-line tool (command တွေကို စာရိုက်ပြီး သုံးရတဲ့ program) တွေက ပုံမှန် setting အတိုင်းဆိုရင် အတည်ပြုခိုင်းတာ မရှိဘဲ ချက်ချင်း run ပါတယ်။
DBMS တော်တော်များများမှာ TRUNCATE TABLE Booking; လည်း ရှိပါတယ်။ ဒါက row တွေကို တစ်ခုချင်း မဖယ်လို့ table တစ်ခုလုံးကို DELETE ထက် ပိုမြန်မြန် ရှင်းပေးပါတယ်။ WHERE clause ထည့်လို့ မရပါဘူး၊ ပြီးတော့ တခြား table ရဲ့ foreign key က ညွှန်းထားတဲ့ table ပေါ်မှာ DBMS အများစုက ဒါကို လက်မခံပါဘူး (PostgreSQL ကတော့ ညွှန်းထားတဲ့ table တွေကိုပါ command တစ်ခုတည်းမှာ ရှင်းရင်၊ ဒါမှမဟုတ် CASCADE နဲ့ ဆိုရင်ပဲ ခွင့်ပြုပါတယ်)။ SQLite မှာ TRUNCATE command မရှိပါဘူး။
Referential integrity ကာကွယ်မှု။ Booking.MemberID မှာ FOREIGN KEY ... REFERENCES Member(MemberID) ရှိရင် booking (class တက်ဖို့ ကြိုတင် စာရင်းသွင်းမှု) တွေ ရှိတဲ့ အသင်းဝင်ကို ဖျက်တဲ့အခါ foreign key ပေါ်မှာ သတ်မှတ်ထားတဲ့ စည်းမျဉ်းပေါ် မူတည်ပြီး အောက်က သုံးမျိုးထဲက တစ်မျိုး ဖြစ်ပါတယ်:
- Delete မအောင်မြင်ပါဘူး (
ON DELETE RESTRICT၊ ဒါမှမဟုတ် default ဖြစ်တဲ့NO ACTION၊DELETEတစ်ခုတည်းအတွက်ဆိုရင် ရလဒ် တူတူပါပဲ)။ - Cascade (ဆက်စပ် row တွေကိုပါ ဆင့်ကဲ ဖျက်ခြင်း) ဖြစ်ပါတယ် (
ON DELETE CASCADE): အသင်းဝင်နဲ့ အတူ သူ့ booking တွေကိုလည်း အလိုအလျောက် ဖျက်ပါတယ်။ - Foreign key ကို NULL လို့ သတ်မှတ်ပါတယ် (
ON DELETE SET NULL): booking တွေ ကျန်နေပေမယ့် MemberID မရှိတော့ပါဘူး။ Foreign key column ကNULLကို ခွင့်ပြုမှပဲ ဒါ အလုပ်လုပ်ပါတယ်။
Foreign key တစ်ခုစီအတွက် စည်းမျဉ်းကို database ဒီဇိုင်းဆွဲသူက ရွေးပါတယ်။ ဒီစည်းမျဉ်းတွေကို Data Types and Keys မှာ ပိုအသေးစိတ် လေ့လာနိုင်ပါတယ်။
Index တွေက Update ကို ဘယ်လို သက်ရောက်လဲ
Index (column တစ်ခုရဲ့ တန်ဖိုးတွေကို စီထားပြီး တန်ဖိုး တစ်ခုစီက သူ့ row ကို ညွှန်းပေးတဲ့ စာရင်း) က ဒေတာ ဖတ်တာကို ပိုမြန်စေပေမယ့် ဒေတာ ပြောင်းတိုင်း အလုပ် ပိုလုပ်ရပါတယ်။ ဒါက effect of indexed columns on update performance (index လုပ်ထားတဲ့ column တွေက update မြန်နှုန်းအပေါ် သက်ရောက်ပုံ) ပါ:
- Index တွေက SELECT တွေကို ပိုမြန်စေပါတယ်။
Surnameပေါ်မှာ index ရှိရင် DBMS က row တိုင်းကို စစ်စရာ မလိုဘဲ သတ်မှတ်ထားတဲ့ မျိုးရိုး နာမည် ရှိတဲ့ အသင်းဝင်တွေကိုO(log n)အဆင့် (row အရေအတွက် n ကြီးလာရင် log n နှုန်းနဲ့ပဲ တိုးတဲ့ အဆင့်အရေအတွက်) နဲ့ ရှာနိုင်ပါတယ်။ - Index တွေက INSERT၊ UPDATE နဲ့ DELETE တွေကို နှေးစေပါတယ်။
INSERTနဲ့DELETEတိုင်းက table ပေါ်က index တိုင်းကိုပါ update လုပ်ရပြီးUPDATEကတော့ သူပြောင်းတဲ့ column ပါတဲ့ index တိုင်းကို update လုပ်ရပါတယ်။ Table မှာ index များလေ၊ write (ဒေတာ ရေးခြင်း) တစ်ခါစီမှာ အလုပ် ပိုလုပ်ရလေ ဖြစ်ပါတယ်။
Workload (database က ကိုင်တွယ်ရတဲ့ ဖတ်တာနဲ့ ရေးတာ ရောစပ်ပုံ) အမျိုးမျိုးအတွက် ဒါက ဘာကို ဆိုလိုလဲ:
| Workload | Index ထားပုံ နည်းဗျူဟာ |
|---|---|
| Read-heavy (ဖတ်တာ များတဲ့၊ report ထုတ်တာ၊ dashboard (ကိန်းဂဏန်းတွေကို တစ်နေရာတည်းမှာ စုပြတဲ့ စာမျက်နှာ) လို) | WHERE, JOIN ဒါမှမဟုတ် ORDER BY မှာ မကြာခဏ သုံးတဲ့ column တိုင်းမှာ index ထည့်ပါ။ |
| Write-heavy (ရေးတာ များတဲ့၊ event log (ဖြစ်ရပ်တွေကို အစဉ်လိုက် မှတ်ထားတဲ့ မှတ်တမ်း) လို row အသစ်တွေ အဆက်မပြတ် ဝင်လာတာမျိုး) | အရေးအကြီးဆုံး query တွေ လိုအပ်တဲ့ အနည်းဆုံး index တွေပဲ ထားပါ။ |
| Mixed (ရောစပ်) | ဘယ် query တွေ မကြာခဏ run လဲ၊ ဘယ်ဟာတွေ နှေးလဲ တိုင်းတာပါ။ ဘယ် query ကမှ မသုံးတဲ့ index တွေကို ဖယ်ပါ။ |
Indexed column (index လုပ်ထားတဲ့ column) ကို ပြောင်းတဲ့ UPDATE က index မလုပ်ထားတဲ့ column ကို ပြောင်းတာထက် ကုန်ကျမှု ပိုများပါတယ်: index ထဲက entry (မှတ်တမ်း တစ်ခု) အဟောင်းကို ဖယ်ပြီး အသစ်ကို ထည့်ရလို့ပါ။ Index မလုပ်ထားတဲ့ column ကို ပြောင်းရင်တော့ row ကိုပဲ ပြန်ရေးရပါတယ်။
Trade-off (တစ်ခု ရဖို့ တစ်ခု အလျှော့ပေးရတာ) ကို ရှင်းပြခြင်း။ Index များတဲ့ table မှာ insert တွေ ဘာကြောင့် နှေးလဲ ဆိုတာကို ပြည့်ပြည့်စုံစုံ ရှင်းပြရင် ဒီအချက်တွေ ပါရပါမယ်:
- Index တိုင်းက table နဲ့ အမြဲ ကိုက်ညီနေရမယ့် သီးခြား data structure (ဒေတာ သိမ်းဆည်းပုံ) တစ်ခုပါ။
INSERTတိုင်းက table ထဲ ထည့်ရုံတင် မကဘဲ index တိုင်းထဲကိုလည်း entry တစ်ခုစီ ထည့်ရပါတယ်။- ပိုလုပ်ရတဲ့ အလုပ်က index အရေအတွက်နဲ့အမျှ တိုးလာပါတယ်။
- ဒါကြောင့် index တစ်ခုစီက trade-off တစ်ခုပါ: တကယ့် query တွေက လိုအပ်မှပဲ ထည့်ပါ။
ပြောင်းလဲမှု အများကြီး လုပ်ပြီးနောက် Index တွေကို ပြန်တည်ဆောက်ခြင်း
Write တိုင်းပြီးနောက် index က မှန်ကန်နေဆဲ ဖြစ်ပေမယ့် အမြဲ ကျစ်ကျစ်လျစ်လျစ် ရှိမနေပါဘူး။ Delete ဒါမှမဟုတ် update အများကြီးကို တစ်ပြိုင်နက် လုပ်ပြီးနောက် index မှာ တစ်စိတ်တစ်ပိုင်း လွတ်နေတဲ့ page (index ကို သိမ်းထားတဲ့ storage အကွက်) တွေ အများကြီး ကျန်နိုင်ပြီး database file ကလည်း သူ့ဘာသာ မကျုံ့သွားပါဘူး။ အဲဒီအခါ index က လိုတာထက် နေရာ ပိုယူပြီး ရှာတဲ့အခါ အရင်ကထက် page ပိုများများ ဖတ်ရနိုင်ပါတယ်။
ပြီးခဲ့တဲ့ နှစ်တွေက booking အများစုကို ဖျက်တာလို ပြောင်းလဲမှု အများကြီး လုပ်ပြီးနောက် database administrator (database ကို run ပြီး ထိန်းသိမ်း စောင့်ရှောက်တဲ့ သူ) က index တွေကို rebuild (ပြန်တည်ဆောက်) ဒါမှမဟုတ် reorganise (ပြန်စီစဉ်) လုပ်နိုင်ပါတယ်:
| DBMS | Command |
|---|---|
| SQLite | REINDEX; က index တွေကို ပြန်တည်ဆောက်ပါတယ်။ VACUUM; က database file တစ်ခုလုံးကို ပြန်တည်ဆောက်ပြီး နေရာကို ပြန်ပေးပါတယ် |
| MySQL | OPTIMIZE TABLE Booking; က table နဲ့ သူ့ index တွေကို ပြန်တည်ဆောက်ပါတယ် |
| PostgreSQL | REINDEX TABLE Booking; က table ရဲ့ index တွေကို ပြန်တည်ဆောက်ပါတယ် |
| SQL Server | ALTER INDEX ALL ON Booking REBUILD; ဒါမှမဟုတ် REORGANIZE၊ REORGANIZE က index ကို အသစ် ပြန်မဆောက်ဘဲ ရှိပြီးသား page တွေကို ကျစ်လျစ်အောင် စုပေးပါတယ် |
Rebuild လုပ်တာ အချိန်ယူပြီး run နေစဉ် table ကို သုံးနေတဲ့ တခြားသူတွေကို နှေးစေတာ ဒါမှမဟုတ် ခဏ ပိတ်ဆို့ထားတာ ဖြစ်နိုင်လို့ များသောအားဖြင့် သုံးသူ နည်းတဲ့ အချိန်မှာ run ပါတယ်။
Denormalised Table ထဲက Update Anomaly (update ပြီးနောက် ဒေတာ မကိုက်ညီတော့ခြင်း) များ
အချက်အလက် တစ်ခုတည်းကို နေရာ တစ်ခုထက် ပိုပြီး သိမ်းထားရင် ပြောင်းလဲမှု တစ်ခုအတွက် update အများ လုပ်ရပါတယ်။ Developer (software ရေးသူ) တွေက denormalised BookingLog table (တခြားနေရာမှာ သိမ်းပြီးသား ဒေတာကို ထပ်သိမ်းထားတဲ့ table) တစ်ခု ထည့်ခဲ့တယ်လို့ ယူဆကြည့်ပါ။ အဲဒီ table က row တိုင်းမှာ အသင်းဝင်ရဲ့ နာမည်ကို သိမ်းထားပါတယ်:
BookingLog(BookingID, MemberName, ClassTitle, BookedOn)
Aroha က သူမရဲ့ မျိုးရိုး နာမည်ကို ပြောင်းတဲ့အခါ UPDATE Member တစ်ခုတည်း မလုံလောက်တော့ပါဘူး: BookingLog row တွေကိုလည်း ပြောင်းရပါမယ်။
UPDATE Member
SET Surname = 'Te Whetu'
WHERE MemberID = 1001;
UPDATE BookingLog
SET MemberName = 'Aroha Te Whetu'
WHERE MemberName = 'Aroha Kahurangi';
ဒုတိယ statement ကို ချန်ခဲ့ရင် table နှစ်ခုက Aroha ရဲ့ မျိုးရိုး နာမည်ကို မတူတဲ့ တန်ဖိုး ပြကြပါလိမ့်မယ်။ ဒါကို update anomaly (update လုပ်ပြီးနောက် ဒေတာ အချင်းချင်း မကိုက်ညီတော့ခြင်း) လို့ ခေါ်ပြီး normalisation (ဒေတာ ထပ်မနေအောင် table တွေကို စီစဉ်ခြင်း) က ဖယ်ရှားပေးတဲ့ ပြဿနာပါ။ Denormalised table မှာဆိုရင် ဒေတာကို ပြောင်းတဲ့ program တိုင်းက copy တွေကို တူအောင် ထိန်းထားရပါတယ်။
Transaction များ: ကြိုတင် မိတ်ဆက်
INSERT, UPDATE နဲ့ DELETE statement အများက အတူတူ အောင်မြင်ရမယ် ဒါမှမဟုတ် အတူတူ မအောင်မြင်ရမယ် ဆိုရင် သူတို့ကို transaction (အကုန်ဖြစ် ဒါမှမဟုတ် ဘာမှမဖြစ်တဲ့ database လုပ်ဆောင်ချက် အစု) တစ်ခုထဲမှာ run ပါ (BEGIN TRANSACTION ... COMMIT; ဒါမှမဟုတ် ROLLBACK;): COMMIT က ပြောင်းလဲမှု အားလုံးကို သိမ်းထားပြီး ROLLBACK က အားလုံးကို ပြန်ဖျက်ပါတယ်။ Transaction တွေကို HL (Higher Level: IB သင်တန်းမှာ ပိုနက်နက်ရှိုင်းရှိုင်း လေ့လာရတဲ့ အဆင့်) စာမျက်နှာ Transactions and Views မှာ အသေးစိတ် လေ့လာရပါမယ်။ SL (Standard Level: IB သင်တန်းရဲ့ အခြေခံ အဆင့်) အတွက်တော့ အဓိက အယူအဆက transaction ဆိုတာ “ဒီပြောင်းလဲမှု အားလုံး၊ ဒါမှမဟုတ် တစ်ခုမှ မဟုတ်” လို့ ဆိုလိုတာပါ။
အဆင့်ဆင့် ရှင်းပြထားတဲ့ ဥပမာများ
ဥပမာ 1: အသင်းဝင် အသစ် ထည့်ခြင်း
အသင်းဝင် အသစ် Lila Okafor က Harbour Run အသင်းကို ဝင်ပါတယ်။ သူမရဲ့ ID က 1005 ဖြစ်ပြီး 1989 ဖေဖော်ဝါရီ 11 ရက်မှာ မွေးပါတယ်၊ Premium tier (အသင်းဝင် အဆင့်) အတွက် စာရင်းသွင်းပါတယ်။
INSERT INTO Member (MemberID, FirstName, Surname, DateOfBirth, Tier)
VALUES (1005, 'Lila', 'Okafor', '1989-02-11', 'Premium');
ဒါ run ပြီးနောက် SELECT တစ်ခုနဲ့ row အသစ်ကို အတည်ပြုနိုင်ပါတယ်:
SELECT * FROM Member WHERE MemberID = 1005;
-- 1005 | Lila | Okafor | 1989-02-11 | Premium
ဥပမာ 2: အသင်းဝင် အုပ်စု တစ်စုကို အဆင့်မြှင့်ခြင်း
အသင်းက promotion (အထူး အစီအစဉ်) တစ်ခု လုပ်ပါတယ်: 2026 မှာ ဖျက်သိမ်းမထားတဲ့ booking ငါးခု ဒါမှမဟုတ် ပိုများတဲ့ Standard tier အသင်းဝင် တိုင်းကို Premium အဖြစ် အဆင့်မြှင့်ပေးပါတယ်။ ကွင်းထဲက query က အဲဒီ အသင်းဝင်တွေကို ရှာပြီး update က သူတို့ရဲ့ tier ကို ပြောင်းပါတယ်:
UPDATE Member
SET Tier = 'Premium'
WHERE Tier = 'Standard'
AND MemberID IN (
SELECT MemberID
FROM Booking
WHERE BookedOn BETWEEN '2026-01-01' AND '2026-12-31'
AND Status <> 'cancelled'
GROUP BY MemberID
HAVING COUNT(*) >= 5
);
(ကွင်းထဲက query က subquery (query တစ်ခုထဲမှာ ထည့်ရေးထားတဲ့ query) ပါ။ Subquery တွေက ဒီစာမျက်နှာရဲ့ အတိုင်းအတာကို ကျော်လွန်ပါတယ်၊ သူ့ပတ်လည်က UPDATE ... SET ... WHERE ကို အာရုံစိုက်ပါ။)
ဥပမာ 3: ဖျက်သိမ်းထားတဲ့ Booking တွေကို ဖယ်ရှားခြင်း
အသင်းက နှစ်နှစ်ထက် ပိုကြာတဲ့ ဖျက်သိမ်းထားတဲ့ (cancelled) booking တွေကို ဖယ်ရှားပါတယ်။ ဒီနေ့က 2026 မေ 22 ရက် ဆိုရင် ဖြတ်မှတ် ရက်စွဲက 2024 မေ 22 ရက်ပါ:
DELETE FROM Booking
WHERE Status = 'cancelled'
AND BookedOn < '2024-05-22';
Condition နှစ်ခုလုံးနဲ့ ကိုက်တဲ့ row တွေကိုပဲ ဖျက်ပါတယ်၊ တခြား booking အားလုံး ကျန်ပါတယ်။
ဥပမာ 4: Index လုပ်ထားတဲ့ Column ကို Update လုပ်ရတဲ့ ကုန်ကျမှု
Member မှာ index သုံးခု ရှိတယ်လို့ ယူဆပါ: MemberID ပေါ်က index (DBMS က အလိုအလျောက် ဖန်တီးပေးတဲ့ primary key index)၊ Surname ပေါ်က index နဲ့ (Tier, DateOfBirth) ပေါ်က composite index (column နှစ်ခုကို တွဲထားတဲ့ index တစ်ခု)။
| Statement | Index ထိန်းသိမ်းရတဲ့ ကုန်ကျမှု |
|---|---|
UPDATE Member SET FirstName = 'Ari' WHERE MemberID = 1001; | Index ပြောင်းစရာ မရှိပါဘူး၊ row ကိုပဲ ပြန်ရေးပါတယ်။ FirstName က ဘယ် index ထဲမှာမှ မပါပါဘူး။ |
UPDATE Member SET Surname = 'Te Whetu' WHERE MemberID = 1001; | DBMS က Surname index ထဲက entry အဟောင်းကို ဖယ်ပြီး အသစ်ကို ထည့်ရပါတယ်။ |
UPDATE Member SET Tier = 'Standard', DateOfBirth = '1989-12-02' WHERE MemberID = 1005; | DBMS က (Tier, DateOfBirth) index ထဲက Lila ရဲ့ entry အဟောင်းကို ဖယ်ပြီး အသစ် တစ်ခု ထည့်ရပါတယ်: အဲဒီ index ရဲ့ column နှစ်ခုလုံး ပြောင်းလို့ပါ။ |
အခြေခံ စည်းမျဉ်း: UPDATE ရဲ့ ကုန်ကျမှုက row ဘယ်နှစ်ခု ပြောင်းလဲ ဆိုတာတင် မဟုတ်ဘဲ ဘယ် column တွေ ပြောင်းလဲ ဆိုတာပေါ်မှာလည်း မူတည်ပါတယ်။ Index မလုပ်ထားတဲ့ column ကို update လုပ်တာက index လုပ်ထားတဲ့ column ကို update လုပ်တာထက် ကုန်ကျမှု နည်းပါတယ်။
Quick Check (အမြန် စစ်ဆေးမေးခွန်း)
Q1. Table တစ်ခုထဲကို row အသစ် ထည့်တဲ့ SQL command က ဘယ်ဟာလဲ။
Q2. WHERE clause မပါဘဲ UPDATE Member SET Tier = 'Premium'; ကို run ရင် ဘာဖြစ်မလဲ။
Q3. အောက်ပါတွေထဲက ဘယ်ဟာကြောင့် DBMS က INSERT statement ကို လက်မခံသလဲ။
Q4. Table တစ်ခုမှာ index အများကြီး ရှိပါတယ်။ ဒါက INSERT, UPDATE နဲ့ DELETE ရဲ့ မြန်နှုန်းကို ဘယ်လို သက်ရောက်သလဲ။
Q5. Booking.MemberID က Member.MemberID ကို ညွှန်းတဲ့ foreign key ဖြစ်ပြီး ON DELETE CASCADE ပါပါတယ်။ အသင်းဝင် 1001 အတွက် booking 5 ခု ရှိနေချိန်မှာ DELETE FROM Member WHERE MemberID = 1001; ကို run ရင် ဘာဖြစ်မလဲ။
Trace the Statement (statement ကို တစ်ဆင့်ချင်း လိုက်ကြည့်ခြင်း)
နမူနာ Member table ကနေ စပါ။ ဒါကို သီးခြား table တစ်ခုလို သဘောထားပါ: ဒီမှာရော အောက်က Predict the Result မှာပါ ဒီ အသင်းဝင်တွေကို ညွှန်းထားတဲ့ booking မရှိဘူးလို့ ယူဆပါ။
Member
| MemberID | FirstName | Surname | DateOfBirth | Tier |
|---|---|---|---|---|
| 1001 | Aroha | Kahurangi | 2008-03-14 | Standard |
| 1002 | Marlon | Tan | 1995-07-22 | Premium |
| 1003 | Sebastián | Quispe | 1980-11-02 | Standard |
| 1004 | Priya | Nair | 2003-05-30 | Premium |
Statement တစ်ခုစီအတွက် table ထဲက row ဘယ်နှစ်ခု ပြောင်းသွားလဲ (ထည့်၊ update ဒါမှမဟုတ် ဖျက်) ဆိုတာကို ကြိုခန့်မှန်းပါ။ Statement တိုင်းက အပေါ်က row လေးခုကနေ စတာပါ: statement တွေကို တစ်ခုပြီး တစ်ခု ဆက်တိုက် run တာ မဟုတ်ပါဘူး။
အဖြေကို integer (ကိန်းပြည့်) တစ်ခုတည်းအဖြစ် ရိုက်ထည့်ပါ။
| Statement | ပြောင်းသွားတဲ့ row အရေအတွက် |
|---|---|
INSERT INTO Member VALUES (1005, 'Lila', 'Okafor', '1989-02-11', 'Premium'); | |
UPDATE Member SET Tier = 'Premium' WHERE Tier = 'Standard'; | |
UPDATE Member SET Surname = 'Te Whetu' WHERE MemberID = 1001; | |
DELETE FROM Member WHERE DateOfBirth < '1990-01-01'; | |
UPDATE Member SET Tier = 'Premium' WHERE 1=0; |
Fill in the Blanks (ကွက်လပ် ဖြည့်ခြင်း)
DML statement သုံးခုကို ပြည့်စုံအောင် ဖြည့်ပါ။ ကွက်လပ်တွေမှာ SQL keyword (programming language မှာ အထူး အဓိပ္ပာယ်ရှိတဲ့ စကားလုံး) တွေကို English လို ရိုက်ထည့်ပါ။ -- နဲ့ စတဲ့ comment တွေက statement တစ်ခုစီ ဘာလုပ်လဲ ပြပါတယ်: booking အသစ် တစ်ခု ထည့်တာ၊ 1990 မတိုင်ခင် မွေးတဲ့ Standard အသင်းဝင် တိုင်းကို Premium ပြောင်းတာ၊ 2024 အစ မတိုင်ခင်က ဖျက်သိမ်းထားတဲ့ booking တွေကို ဖယ်ရှားတာ။
-- Add a new booking
Booking (BookingID, MemberID, ClassID, BookedOn, Status)
VALUES ('B9005', 1003, 'C402', '2026-05-31', 'confirmed');
-- Change every Standard member born before 1990 to Premium
Member
Tier = 'Premium'
WHERE Tier = 'Standard' AND DateOfBirth < '1990-01-01';
-- Remove cancelled bookings older than the start of 2024
DELETE Booking
WHERE Status = 'cancelled' AND BookedOn < '2024-01-01';
Spot the Error (အမှား ရှာခြင်း)
Developer တစ်ယောက်က အသင်းဝင် တစ်ယောက်တည်းကို Premium tier အဖြစ် အဆင့်မြှင့်ဖို့ ကြိုးစားနေပါတယ်။ Line တစ်ကြောင်းမှာ အမှား ရှိပါတယ်။ အမှားပါတဲ့ line ကို ရွေးပါ၊ ပြီးရင် မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ။
Line 2 အတွက် မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
Predict the Result (ရလဒ်ကို ကြိုခန့်မှန်းခြင်း)
အပေါ်က နမူနာ Member table ကနေ စရင် အောက်က statement က row ဘယ်နှစ်ခုကို ပြောင်းမလဲ:
UPDATE Member SET Tier = 'Premium' WHERE Tier = 'Standard' AND DateOfBirth < '2000-01-01';အဖြေကို integer တစ်ခုတည်းအဖြစ် ရိုက်ထည့်ပါ။
အပေါ်က နမူနာ Member table ကနေ စရင် အောက်က statement က row ဘယ်နှစ်ခုကို ဖျက်မလဲ:
DELETE FROM Member WHERE Tier = 'Premium' OR Surname = 'Quispe';အဖြေကို integer တစ်ခုတည်းအဖြစ် ရိုက်ထည့်ပါ။
Practice Exercises (လေ့ကျင့်ခန်းများ)
မေးခွန်းတိုင်းမှာ ပါတဲ့ [3 marks] လို mark allocation (မေးခွန်း တစ်ခုစီအတွက် ပေးတဲ့ အမှတ်) တွေက IB စာမေးပွဲ ပုံစံအတိုင်း ပေးထားတာပါ။
Core (အခြေခံ အဆင့်)
-
[Core]SQL: DML[3 marks]ဒေတာကို ပြင်ဆင်ပြောင်းလဲဖို့ သုံးတဲ့ SQL DML command သုံးခုကို State (ဖော်ပြပါ)၊ ပြီးရင် တစ်ခုစီ ဘာလုပ်လဲ ဆိုတာကို စာကြောင်း တိုတို တစ်ကြောင်းစီနဲ့ describe (ဖော်ပြရှင်းပြပါ)။ [Core]SQL: DML[3 marks]Harbour RunClasstable ထဲကို class (အားကစား လေ့ကျင့်ရေး သင်တန်း) အသစ် တစ်ခု ထည့်တဲ့ SQL statement ကို Write (ရေးပါ):ClassID = 'C404',Title = 'Evening Trail',Coach = 'Daniel Park',StartsAt = '2026-07-01 18:30',Capacity = 25.
-
[Core]SQL: DML[3 marks]2024 ခုနှစ် ဇန်နဝါရီ 1 ရက် မတိုင်ခင် လုပ်ခဲ့တဲ့ booking တိုင်းရဲ့ status (အခြေအနေ) ကို'archived'လို့ ပြောင်းတဲ့ SQL statement ကို Write လုပ်ပါ။ [Core]SQL: DML[3 marks]ClassC302ကို အချိန်ဇယားကနေ ဖယ်လိုက်ပြီး သူ့ booking တွေကို မလိုတော့ပါဘူး။ ClassC302အတွက် booking တိုင်းကို ဖယ်ရှားတဲ့ SQL statement ကို Write လုပ်ပါ။
Extension (တိုးချဲ့ အဆင့်)
-
[Extension]SQL: DML[3 marks]Developer တစ်ယောက်ကWHEREclause မပါဘဲDELETE FROM Booking;ကို run ရင် ဘာဖြစ်မလဲ ဆိုတာကို Explain (ရှင်းပြပါ)၊ ပြီးရင် တကယ့် စနစ်တွေမှာ row အများကြီးကို မတော်တဆ ဖျက်မိတာကနေ ကာကွယ်ပေးတဲ့ အလေ့အကျင့် နှစ်ခုကို outline (အကျဉ်းချုပ် ဖော်ပြပါ)။ [Extension]SQL: DML[4 marks]Classtable မှာClassID(primary key) နဲ့Coachပေါ်မှာ index တွေ ရှိပါတယ်။ အောက်က update နှစ်ခုထဲက ဘယ်ဟာက ပိုမြန်လဲ၊ ဘာကြောင့်လဲ ဆိုတာကို Explain လုပ်ပါ:- (a)
UPDATE Class SET Capacity = 30 WHERE ClassID = 'C401'; - (b)
UPDATE Class SET Coach = 'Daniel Park' WHERE ClassID = 'C401';
- (a)
[Extension]SQL: DML[3 marks]နှစ်တိုင်း အဆုံးမှာ အသင်းကBookingထဲက row အဟောင်း အများစုကို ဖျက်ပါတယ်။BookingမှာMemberIDနဲ့BookedOnပေါ်မှာ index တွေ ရှိပါတယ်။ ဖျက်ပြီးနောက် database administrator က ဒီ index တွေကို ဘာကြောင့် rebuild လုပ်ချင်နိုင်လဲ ဆိုတာကို Explain လုပ်ပါ။
Challenge (စိန်ခေါ်မှု အဆင့်)
[Challenge]SQL: DML[5 marks]Booking.MemberIDcolumn ကMember.MemberIDကို ညွှန်းတဲ့ foreign key ပါ။ Foreign key မှာON DELETE RESTRICTနဲ့ON UPDATE RESTRICTရှိတယ်လို့ ယူဆပြီး အောက်က အခြေအနေ တစ်ခုစီမှာ ဘာဖြစ်မလဲ ဆိုတာကို Explain လုပ်ပါ:- (a)
Memberထဲမှာ မရှိတဲ့MemberIDပါတဲ့ booking ကို ထည့်ခြင်း။ - (b) ရှိပြီးသား booking သုံးခု ရှိတဲ့ အသင်းဝင်ကို ဖျက်ခြင်း။
- (c) Booking တွေ ရှိတဲ့ အသင်းဝင် တစ်ယောက်ရဲ့
MemberIDကို1001ကနေ9999ကို ပြောင်းခြင်း။
- (a)
[Challenge]SQL: DML[6 marks]Table တစ်ခုမှာ index အများကြီး ထည့်တာနဲ့ write မြန်နှုန်းကို မြန်အောင် ထိန်းထားတာကြားက trade-off ကို Discuss (အမြင် အမျိုးမျိုးကို ချိန်ဆပြီး ဆွေးနွေးပါ)။ Read-heavy နဲ့ write-heavy workload တွေကို ထည့်ပြောပြီး နည်းဗျူဟာ တစ်ခုစီ သင့်တော်တဲ့ workload ဥပမာ တစ်ခုစီ ပေးပါ။
Exam-Style (စာမေးပွဲ ပုံစံ မေးခွန်း)
[Exam-Style]SQL: DML[6 marks]Harbour Run schema (database ဖွဲ့စည်းပုံ ဖော်ပြချက်) အတွက် အောက်ပါ လုပ်ဆောင်ချက် တစ်ခုစီကို လုပ်ပေးတဲ့ SQL statement တွေကို construct (ကိုယ်တိုင် တည်ဆောက်ပါ)။ လုပ်ဆောင်ချက် တစ်ခုကို statement တစ်ခုစီ သုံးပါ။ (တစ်ခုကို 2 marks စီ)- (a)
MemberID = 1099နဲ့ အသင်းဝင် အသစ် တစ်ယောက် ထည့်ပါ၊ ကျန်တဲ့ column တွေအတွက် ကိုယ်တိုင် စိတ်ကူးထားတဲ့ ဒါပေမယ့် မှန်ကန်တဲ့ တန်ဖိုးတွေကို သုံးပါ။ - (b) အသင်းဝင်
1002ရဲ့ မျိုးရိုး နာမည်ကို'Tan-Lopez'လို့ ပြောင်းပါ။ - (c) 2024 မေလက
Status = 'no-show'ဖြစ်တဲ့ booking တိုင်းကို ဖျက်ပါ။
- (a)
IB CS ကို လေ့လာသူတွေအတွက် မှတ်ချက်: A3.3.3 မှာ INSERT INTO, UPDATE SET နဲ့ DELETE ပါပါတယ်။ ပြည့်စုံတဲ့ statement မှာ မှန်တဲ့ command ကို သုံးရပြီး table နဲ့ column တွေရဲ့ နာမည်ကို ရေးရကာ ရည်ရွယ်ထားတဲ့ row တွေကို အတိအကျ ရွေးတဲ့ WHERE clause ပါရပါမယ်။ Index က ဖတ်တာကို ဘာကြောင့် မြန်စေပြီး ရေးတာကို ဘာကြောင့် နှေးစေလဲ ဆိုတာကို ရှင်းပြနိုင်အောင် ပြင်ဆင်ထားပါ: insert ဒါမှမဟုတ် delete တိုင်း၊ index လုပ်ထားတဲ့ column ကို update လုပ်တိုင်း index ကိုလည်း update လုပ်ရလို့ပါ။ ပြောင်းလဲမှု အများကြီး လုပ်ပြီးနောက် index ကို ဘာကြောင့် rebuild လုပ်ဖို့ လိုနိုင်လဲ ဆိုတာကိုလည်း ရှင်းပြနိုင်အောင် ပြင်ဆင်ထားပါ။
ဆက်စပ် ခေါင်းစဉ်များ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: SQL Queries။
SELECTက ဒေတာကို ဖတ်တဲ့ DML command ပါ၊ INSERT, UPDATE နဲ့ DELETE ကတော့ ဒေတာကို ပြောင်းတဲ့ command တွေပါ။ - ဆက်စပ် ခေါင်းစဉ်: Data Types and Keys။ INSERT, UPDATE ဒါမှမဟုတ် DELETE မှာ foreign key ပါလာရင် ဘာဖြစ်မလဲ ဆိုတာကို foreign key စည်းမျဉ်းတွေ (CASCADE, RESTRICT, SET NULL) က ဆုံးဖြတ်ပါတယ်။
- ဆက်စပ် ခေါင်းစဉ်: Normalisation။ Normalise လုပ်ထားတဲ့ ဒီဇိုင်းမှာ အချက်အလက် တစ်ခုစီကို နေရာ တစ်ခုတည်းမှာ သိမ်းလို့ အဲဒါကို ပြောင်းရင် table တစ်ခုထဲက row တစ်ခုကိုပဲ update လုပ်ရပါတယ်။
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ် (HL): Transactions and Views။ Transaction က INSERT, UPDATE နဲ့ DELETE statement အများကို စုပေးလို့ အားလုံး အကျိုးသက်ရောက်တာ ဒါမှမဟုတ် တစ်ခုမှ အကျိုးမသက်ရောက်တာ ဖြစ်စေပါတယ်။ ဒါက အဆင့်အများနဲ့ လုပ်တဲ့ ပြောင်းလဲမှုအတွင်း ဒေတာကို မှန်ကန်အောင် ထိန်းထားပေးပါတယ်။