Tuesday, August 12, 2008

ေကာ္လံ အပို ထပ္ထည့္ျခင္း

(Computer Programming Post ျဖစ္ပါတယ္။)

Database သံုးတဲ့ Application ေတြမွာ Database Schema ေျပာင္းတိုင္း Application ရဲ႕ Code ေတြကို လိုက္ေျပာင္းရႏိုင္ပါတယ္။ ဒီလို ေျပာင္းတဲ့ အခါ ႏွစ္ေနရာမွာ ေျပာင္းရႏိုင္ပါတယ္။ ကိုယ့္ ျပင္ခ်င္တဲ့ ေနရာမွာေတာ့ ေျပာင္းရပါတယ္။ တစ္ခါတစ္ေလက်ရင္ ကိုယ္ေျပာင္းလိုက္တာေၾကာင့္ တျခားေနရာေတြမွာပါ သက္ေရာက္မႈ ႐ွိၿပီး လိုက္ေျပာင္းရပါတယ္။ ကိုယ္ျပင္ခ်င္ရာ ျပင္ၿပီး တျခားေနရာေတြကို လိုက္မစစ္ရင္ Production က်မွ ဒုကၡ လွလွေတြ႕ရပါမည္။

Table တစ္ခုမွာ Column တစ္ခု ျဖဳတ္လိုက္ရင္ ဘာျဖစ္သြားမလဲ ေမးရင္ ေမးတဲ့ လူကိုေတာင္ ေၾကာင္ေနလား ဒီေကာ္လံကို သံုးထားတဲ့ ေနရာေတြမွာ Error ေတြ တက္လာမွာေပါ့လို႔ ခ်က္ခ်င္း ျပန္ေျဖမွာပဲ။ ေကာ္လံ တစ္ခု ထပ္ထည့္လိုက္ရင္ေရာ ဘာျဖစ္မလဲ ေမးရင္ အေတြ႔အႀကံဳ နည္းေသးတဲ့ သူေတြကေတာ့ ဘာမွ မျဖစ္ေလာက္ပါဘူးလို႔ ေျဖမွာပါ။

တကယ္ေတာ့ အေသအခ်ာ မေရးထားတဲ့ Application တစ္ခုမွာ ေကာ္လံ တစ္ခု ထပ္ထည့္ရင္လည္း Error တက္ႏိုင္ပါတယ္။ ဘယ္လို ေနရာမွာ တက္ေလ့ ႐ွိသလဲ ဆိုေတာ့ အရင္ ႐ွိထားတဲ့ Insert Statement မွာ တက္တတ္ပါတယ္။ ဥပမာ Emp Table ပဲ ဆိုပါေတာ့ အရင္တုန္းက ေကာ္လံ ၂ ခု ႐ွိတယ္။ EmpId နဲ႔ Name နဲ႔။ အဲဒါကို Database မွာ DOB ဆိုတဲ့ ေကာ္လံ ထပ္ထည့္လိုက္တယ္။ Application Code ကို ဘာမွ မေျပာင္းဘူးဆိုေပမည့္ အရင္တုန္းက ေရးတဲ့သူက Insert Statement ကို ဒီလိုမ်ိဳး ေရးခဲ့မည္ဆိုရင္ Error တက္မွာပါ။

INSERT INTO Emp VALUES (1,'John');

ဆိုၿပီး Column ကို မေၾကညာတဲ့ Insert Statement ေတြဟာ Table ထဲမွာ ေနာက္ထပ္ ေကာ္လံ တစ္ခု အပို ပါသြားရင္ Parameter အေရအတြက္နဲ႔ ေကာ္လံ အေရအတြက္ မတူတဲ့ အတြက္ Execute လုပ္လို႔ မရေတာ့ပါဘူး။ အဲဒီေတာ့ Database မွာ ေကာ္လံ တစ္ခု ထပ္ထည့္မည္ဆိုရင္ Application Code ထဲမွာ ဒီလို Insert Statement ေတြ ႐ွိမ႐ွိ အရင္ "Find" နဲ႔ Table Name သံုးၿပီး အလြယ္တကူ ႐ွာၾကည့္ရပါတယ္။ ေတြ႕ရင္ ဒီလိုမ်ိဳး ျပင္လိုက္ရပါမည္။

INSERT INTO Emp (EMPID,NAME) VALUES (1,'John');

အခုေနာက္ပိုင္းေတာ့ ဘယ္သူမွ Application Code ထဲမွာ SQL Statement ေတြကို ဒီအတိုင္း မေရးေတာ့ပါဘူး။ Hibernate တို႔ Oracle က Toplink တို႔လိုမ်ိဳးေတြ သံုးတဲ့ အတြက္ ဒီလိုမ်ိဳးေတြ မ႐ွိသေလာက္ပါပဲ။

ဒါေပမယ့္ Database အထဲကမွ ဒီ Table ကို သံုးထားတဲ့ View ေတြ Stored Procedure မွာ ဒီလို Insert Statement ေတြ ႐ွိႏိုင္ပါေသးတယ္။ အဲဒါေတြကိုေတာ့ ကိုယ္ျပင့္မည့္ Table (Emp) မွာပဲ Dependency ေတြကို ႐ွာၾကည့္ၿပီး Depend လုပ္ထားသမွ် View လိုမ်ိဳး Stored Procedure လိုမ်ိဳး Function လိုမ်ိဳး Database Object ေတြမွာ လိုက္စစ္ေပးရပါတယ္။ ႐ွိရင္ ျပင္ေပးရပါတယ္။

အဲဒီလို ျပင္ေပးတဲ့ အခါမွာ Insert Statement ေတြ သာမက Union သံုးထားတဲ့ Select Statement ေတြမွာပါ စစ္ေပးရပါတယ္။ ထားပါေတာ့ Emp Table နဲ႔ Emp_Arcihve ဆိုတဲ့ Table ႏွစ္ခုဟာ ေကာ္လံေတြ တူေနခဲ့လို႔ ဒီလို Union လုပ္ထားတယ္ ဆိုရင္

SELECT * FROM EMP
UNION
SELECT * FROM EMP_ARCHIVE

Emp Table မွာပဲ ေကာ္လံ ထပ္ထည့္ၿပီး Emp_Archive Table မွာ မထည့္ရင္ ဒီ SQL ဟာ အလုပ္ လုပ္ေတာ့မွာ မဟုတ္ပါဘူး။ အဲဒါေၾကာင့္ ဒီလုိ Statement ေတြကို ႐ွာၿပီး ျပင္သင့္ရင္ ျပင္ေပးရပါတယ္။

ဒီလိုမ်ိဳး မျမင္သာဘဲ ဒုကၡ ေပးႏိုင္တဲ့ SQL ေတြလည္း ႐ွိပါေသးတယ္။ ဆုိပါေတာ့ Customer ဆိုတဲ့ Table ႐ွိၿပီး အဲဒီမွာ DOB ဆိုတဲ့ ေကာ္လံက ပါၿပီးသား၊ EmpId = 1 ရဲ႕ Customer Demographic level အတြက္ ေနာက္ထပ္ ServedBy ဆိုတဲ့ EmpId နဲ႔ CustomerID ေကာ္လံေတြ ပါတဲ့ ၾကားခံ Table တစ္ခု သံုးထားတဲ့ Query နဲ႔ ႐ွာတယ္ ဆိုပါေတာ့

SELECT e.EmpId, c.CustomerID, DOB
FROM Emp e,
Customer c,
ServedBy m
where m.EmpId = e.EmpId
and m.CustomerId = c.CustomerId
where e.EmpID = 1

ဒီ SQL ေရးတုန္းက DOB ဆုိတဲ့ ေကာ္လံက Customer ထဲမွာပဲ ပါလို႔ ဘယ္ Table က ယူမည္ဆိုတာကို မေျပာလည္း ရတဲ့ အတြက္ ဘာမွ Specify မလုပ္ထားေပမယ့္ Emp Table ထဲမွာ DOB ထပ္ထည့္လိုက္ၿပီး ေနာက္မွာ ဒီ SQL ဟာ Run လို႔ မရေတာ့ပါဘူး။ ဘာေၾကာင့္လည္း ဆိုေတာ့ Ambiguous column ျဖစ္သြားလို႔ပါ။ အဲဒါေၾကာင့္ ဒီလို SQL မ်ိဳးေတြကိုလည္း ဒီလို လိုက္ျပင္ရပါမည္။

SELECT e.EmpId, c.CustomerID, c.DOB
FROM Emp e,
Customer c,
ServedBy m
where m.EmpId = e.EmpId
and m.CustomerId = c.CustomerId
where e.EmpID = 1

ဒီေလာက္ လိုက္ျပင္တာေတာင္ ကိုယ္မျမင္လိုက္တာေတြ ႐ွိႏိုင္ပါေသးတယ္။ အဲဒါေၾကာင့္ Unit Testing က အေရးပါလာပါတယ္။ (Unit Testing အေၾကာင္း ေနာက္ေရးပါမည္။) Program Unit တိုင္းအတြက္ Test လုပ္ဖို႔ Unit Test Case ေတြကို ေရးထားမည္ဆို System မွာ (Databaseမွာ ျဖစ္ျဖစ္ ၊ Application ျဖစ္ျဖစ္၊ Configuration ျဖစ္ျဖစ္) တစ္ခု ေျပာင္းလိုက္တိုင္း Unit Test Cases ေတြကို Run ၾကည့္ၿပီး Effect ႐ွိမ႐ွိ သိႏိုင္ပါတယ္။

Unit Test ေတြ မ႐ွိလိုပဲ ျဖစ္ျဖစ္ Legacy Application ျဖစ္ေနလို႔ ကိုယ့္စီမွာ ျပင္ေပးမည့္ သူ မ႐ွိလို႔ပဲ ျဖစ္ျဖစ္၊ Application ရဲ႔ Source Code ေတြ မ႐ွိလိုပဲ ျဖစ္ျဖစ္ Side Effect မ႐ွိေစခ်င္လိုပဲ ျဖစ္ျဖစ္ Database ကို ျပင္ခ်င္တယ္ ေကာ္လံ ထပ္ထည့္ခ်င္တယ္ဆိုရင္ေတာ့ လံုး၀ ထပ္ထည့္လို႔ မရဘဲ ဒီေကာ္လံ အတြက္ ေနာက္ထပ္ Table တစ္ခု ထပ္တိုးမွ ရပါမည္။ ဥပမာ Emp Table ထဲမွာ DOB ေကာ္လံ ထပ္ထည့္ဖို႔ EMP_DOB ဆိုတဲ့ EmpId ေကာ္လံနဲ႔ DOB ေကာ္လံပဲ ပါတဲ့ Table တစ္ခု ထပ္ထည့္ေပးျခင္းျဖင့္ ေျဖ႐ွင္းႏိုင္ပါတယ္။ ဒီေနရာမွာေတာ့ EmpId နဲ႕ DOB ဟာ One-To-Many ျဖစ္သြားတတ္တာကို သတိထားရပါမည္။ ေနာက္ၿပီး ဒီလို မလိုအပ္ဘဲ Higly Normalise လုပ္ထားတာဟာ မေကာင္းဘူးဆိုတာကိုလည္း သတိထားရပါမည္။ မတတ္သာတဲ့ အဆံုးမွပဲ ဒီလို လုပ္သင့္ပါတယ္။

Good Practice ေတြကေတာ့
  • Insert Statement ေတြမွာ Column ေတြကို ေၾကညာပါ။
  • Union မွာ Select * မလုပ္ပါနဲ႔
  • Table တစ္ခုထက္ ပိုတာကို Join ထားမည္ဆို ေကာ္လံတိုင္းဟာ ဘယ္ Table ကလည္း ဆိုတာကို ေၾကညာပါ။
  • Program Unit တိုင္းအတြက္ Unit Test Case ေတြ ႐ွိပါေစ။
တျခားဖတ္ရန္-SQL Injection

7 comments:

KhinLayThant - 8/13/08, 1:47 AM

Thanks for your useful post in IT. plz post more , Ko Andy !

gulu - 8/13/08, 12:52 PM

ဟုတ္တယ္ဗ်။ new column ထဲ့မယ္ဆိုရင္ ဘာမွ မျဖစ္ဘူးလို႔ပဲေတြးၾကတာမ်ားမယ္ထင္တယ္ (က်ေနာ္ေတာ့ အဲ့လိုေတြးခဲ့တယ္ :D )

အခုလိုေရးျပတာ ေက်းဇူးပါ :) ေနာက္လည္း ဒါမ်ိဳး အမွတ္တမဲ့ သတိမထားျဖစ္တဲ့ IT Knowledge ေလးေတြ အဆင္ေျပတိုင္းေရးေပးပါ :)

khaingzm - 8/13/08, 3:47 PM

Looking forward to your coming post about unit testing ..

ပီတိ - 8/14/08, 10:30 AM

Database မွာေျပာင္းလိုက္တာနဲ႔ ေသခ်ာေအာင္ Unit test ကျပန္လုပ္ရတာပဲေနာ္။ Programmer ေတြကေတာ့ unit test ကိုလည္းလုပ္ဖုိ႔ အင္မတန္ပ်င္းပါတယ္။ ေနာက္ၿပီး ကိုယ္ေရးတဲ့ program အျမဲမွန္တယ္ ထင္တတ္ရဲ႕…

သဥၨာ - Thinzar - 8/14/08, 11:56 AM

Good practice ေတြကေတာ့ မွတ္သားစရာပါဘဲ။ အခုလို အေတြ႔ အၾကဳံေတြ ဖလွယ္ေပးတာ သဥၹာတို႔လို ခုမွ စျပီး အိုင္တီေလာကထဲ ၀င္ခါစအတြက္ေတာ့ တကယ္ကို တန္ဖိုးရွိပါတယ္။ တစ္ခ်ိဳ႕အရာေတြက စာက မသင္ေပးဘဲ အေတြ႕အၾကဳံက သင္သြားေပးတာဆိုေတာ့ေလ။ ကိုပီတိေျပာသလိုဘဲ သဥၹာလည္း unit test လုပ္ဖို႔ အရမ္းပ်င္းပါတယ္။ အခ်ိန္ရရင္ unit test ကို ဘယ္လို အေကာင္းဆုံးနဲ႔ အလြယ္ဆုံး လုပ္ႏိုင္မလဲ ဆိုတာလဲ ေရးေပးပါဦး။ testing ကလည္း ပညာ တစ္ခုဘဲေနာ္။ အခုေလာေလာဆယ္ေတာ့ ကိုယ္ဘဲ programmer ကိုယ္ဘဲ DBA ကိုယ္ဘဲ tester ဆိုေတာ့ testing ကို လုံး၀ ဂရုမစုိက္ႏိုင္ဘူး ျဖစ္ေနလို႔။

Andy Myint - 8/14/08, 9:47 PM
Thanks for reading...Ma Khin Lay Thant

ကၽြန္ေတာ္လည္း ထင္ခဲ့တာပါပဲ Gulu

I will try to write about Unit Testing soon Ma Khaing Z M

မွန္လိုက္ေလ ကိုပီတိေရ... ေနာက္ပိုင္းေတာ့ ကိုယ္ေရးတာေတြက အကုန္ မမွန္ဘူးဆိုတာ သိလာေပမယ့္ ဘယ္နား မွားေနသလဲ ဆိုတာေတာ့ မသိေသးတာ ခက္တယ္

ဟုတ္တယ္ ညီမ သဥၨာ ဒီလို အေတြ႔အႀကံဳေတြကို မ်ားမ်ား ေရးသြားပါမယ့္။ သီအိုရီနဲ႔ How to ေတြကေတာ့ စာအုပ္ဖတ္ အင္တာနက္မွာ ႐ွာႏိုင္တာပဲ။

Unit Test လုပ္ဖို႔ ပ်င္းတယ္လို႔ ေျပာတာ ကၽြန္ေတာ့္အတြက္ စဥ္းစားစရာ ျဖစ္ေစတယ္။ ဘာျဖစ္လို႔လဲ ဆိုေတာ့ ကၽြန္ေတာ္တို႔က Unit Test ကို Automate လုပ္ထားတာ ဆိုေတာ့ အစအဆံုး နီးပါး သူ႔ဘာသူ Run ၿပီး စစ္သြားေပးတာပဲ။ ဒီအေၾကာင္းေတာ့ အျမန္ေရးဖို႔ လိုၿပီ ထင္တယ္။
ပီတိ - 8/15/08, 2:23 AM

ဟုတ္ကဲ့ ကိုအန္ဒီ… automated unit testing အခ်ိန္ရရင္ ေရးေပးပါဦး…ေက်းဇူး

Post a Comment

Many thanks for dropping a comment…

Film


Files