วันศุกร์ที่ 10 สิงหาคม พ.ศ. 2561

วันอาทิตย์ที่ 27 พฤษภาคม พ.ศ. 2561

MiniProject - WebAPP " We Can Eat "






https://www.youtube.com/watch?v=V1SZDit-7CM&feature=youtu.be

วิดีโอนี้ เป็นส่วนหนึ่งในรายวิชา Database System 2/2560

คณะผู้จัดทำ


57-010126-2003-9 สุภาภรณ์ ปู่แก้ว

58-010126-1016-4 สาริกข์ คำปาน

58-010126-1013-0 นิธิกานต์ เสนีวงศ์ ณ อยุธยา

58-010126-1004-1 ตระการศักดิ์ จึงตระการ

58-010126-3011-4 บุณยกร ชาตะสิงห์

คลิป อธิบาย ER ของกลุ่ม แบบ ชัดกว่าใน Youtube แบ่งเป็น2 part จากข้อกำหนด
การใช้งานฟรีของเว็ปที่ใช้ในการใช้งาน
** part 1



* part 2


วันอาทิตย์ที่ 1 เมษายน พ.ศ. 2561

Database System - work 9 Normal Form 1NF , 2NF , 3NF

*a prime attribute of R if it is a member of some candidate key of R

1/4/2561 update

First Normal Form - 1NF

- ใน 1 Attribute ห้าม มี หลายค่า ห้ามเป็น set ห้ามเป็น tuple

ตัวอย่างปัญหา 1


ไม่ใช่ 1 NF เพราะ มี SET ของค่าใน Dlocations row 1



 งั้นก็แยกมันออกมาสิ ? แต่หากทำแบบนั้นก็จะเกิดการซ้ำซ้อนของข้อมูลใน Attribute อื่นที่ไม่ใช่ Dlocation ดังภาพ [ row 1 - 3 ]


หรือ จะแยก Dlocation เป็น Dlocation 1 2 3 ?  แต่ก็เท่ากับว่าเราจะไปทำการ Fix ให้มัน ต้องมีไม่เกิน 3 ที่  เท่านั้นนะสิ ? แล้ว ตัวที่ มีมากกว่า 3 ที่หรือน้อยกว่าจะจัดการยัง ไง ?

ตัวอย่างปัญหา 2


Pnumber และ Hour มากกว่า 1 ค่า

ทำการแยกออกมาเป็น2 Table แทน  โดย Ssn ของEMP_PROJ2 คาดว่าน่าจะ เป็น FK ชี้ไป EMP_PROJ1 และ ใน EMP_PROJ1 นั้นจะไม่มีการที่ ใน attribute ใดๆมีค่ามากกว่า 1 อีกแล้ว จึงตรงตามเงื่อนไข และใน EMP_PROJ2 นั้น ก็ เช่นกัน เนื่องจากใช้ { Ssn , Pnumber } เป็น PK  จึงจะไม่มีการที่ ใน attribute ใดๆมีค่ามากกว่า 1 อีกแล้ว  เพราะใน ผู้ถูกจ้าง และ เบอร์ นี้ ถูกโทรนั้นจะถูกบันทึกใน row เดียวกัน  หากเปลี่ยนเบอร์ ก็จะเป็นอีก row นึงไป


Second Normal Form - 2NF


 - Based on concept of full functional dependency

full functional dependency - >

X → Y จะ  full functional dependency  ก็ต่อเมื่อ หากมีการนำ Attribute ใน X ใดๆออกไป จะไม่เป็น dependency   หรือ  X → Y อีกต่อไป ( X → Y หมายถึง  Y ขึ้นอยู่กับ X หรือ หาก รู้ X จะได้ค่า Y ที่แน่นอนออกมา หรือมีเพียงชุดคำตอบเดียวเท่านั้น )

เช่น

{Ssn, Pnumber} → Hours

ใน ผู้ใช้งาน 1 คนใน เบอร์ หนึ่งๆ นั้นจะมีชั่วโมงการใช้งานได้ค่าเดียว

Neither 
Ssn → Hours
nor
Pnumber → Hours
holds

หากแยกออกมา เป็นดังข้างบน จะไม่ใช่ dependency อีกต่อไป เพราะ ใน Ssn 1 คนอาจมีได้หลายเบอร์ จึงไม่สามารถ ระบุ ชั่วโมงที่แน่นอนได้ และ เบอร์ ใดๆ อาจจะถูกใช้โดยหลายคนได้ จึงไม่สามารถ ระบุ ชั่วโมงการใช้งานหรือถูกโทรได้อย่างแน่นอนเช่นกัน

ดังนั้น เมื่อแยกไม่ได้  {Ssn, Pnumber} → Hours
จึงเป็น  {Ssn, Pnumber} → Hours

---------------------------------------

A relation schema R is in 2NF if  every non-prime attribute A in R
is fully functionally dependent on the  primary key of R

หาก ทุกๆ ตัวที่ไม่ใช่ prime attribute ในความสัมพันธ์ใดๆ เป็น fully funtionally dependent กับ primary key ก็จะเป็น 2 NF

{Ssn, Pnumber} → Hours

ในที่นี้ Hours ไม่เป็น prime attribute  และ มีความสัมพันธ์แบบ  fully funtionally dependent  จึงเป็น 2NF

------------------------------------------


ตัวอย่างปัญหา 1


เริ่มจากการไล่เช็คไปเรื่อยๆ { Ssn , Pnumber } --> ?  โดย ? หมายถึง Hours, Ename, Pname , Plocation ไล่ไปจนครบ


ไม่ใช่ 2NF !! เพราะ ใน FD 2 นั้นจะเห็นได้ว่าใช้ แค่ Ssn --> Ename ได้ ไม่จำเป็นต้องเป็น { Ssn, Pnumber } --> Ename อีกต่อไปแล้ว จึงหมายความว่ามันไม่ใช่
fully functionally dependent เมื่อไม่ใช่ fully functionally dependent ก็ไม่เป็น 2NF อีกต่อไป รวมถึง FD3 ด้วยเหตุผลในทำนองเดียวกัน

แล้วจะแก้ยังไง ?


ทำการแยก ส่วนที่ไม่ใช่   fully functionally dependent  ออกไปเป็น table ใหม่ แยกกัน ซะ แล้วทั้งหมดก็จะเป็น 2NF !

ตัวอย่างปัญหา 2

เนื่องจากใน Text book ไม่แสดงตัวอย่างให้เห็นมากกว่า1 ปัญหา ดังนั้นจึงไปหา จากข้องนอก Text book มาเสริม
http://www.gitta.info/LogicModelin/en/html/DataConsiten_Norm2NF.html


จากภาพ ความสัมพันธ์ในตอนแรกนั้น 
IDSt, IDProf --> Grade ---(3)
IDProf --> ProfessorName ---(1)
IDSt --> StudentName  ---(2)

จะเห็นได้ว่า (1)(2) นั้น จะมี มีตัว สำหรับอ้างไปยัง ผลลัพธ์แค่ตัวเดียวในขณะที่ Grade นั้นจำเป็นต้องใช้ 2 ตัว เลย จึงกล่าวได้ว่า  IDSt, IDProf ยังไม่เป็น
fully functionally dependent 

จึงยังไม่ใช่ 2NF ดังนั้น จึงแยกเป็นหลาย ตารางได้ตามภาพ โดยแยก ตาม dependent (1)(2)(3) ออกมาได้ 3 ตารางดังภาพ

Third Normal Form - 3NF
- Based on concept of transitive dependency  a relation schema R is in 3NF if it satisfies  2NF and   no non-prime attribute of R is transitively
dependent on the primary key

เงื่อนไขคือ เป็น 2NF และ  ไม่มี  non-prime attribute ที่เป็น  transitively
dependent กับ primary key หรือ ก็คือ มี ค่าที่ไม่ใช่ PK ที่ สามารถ กำหนด ค่าของ Attribute อื่นได้ หรือช่วยในการระบุได้


ตัวอย่างปัญหา 1


จากภาพ จะเห็นได้ว่า ในตารางนี้ PK หลัก ก็คือ Ssn ซึ่งมี ความสัมพัน dependent 
ที่ { Ssn } ---> ? โดยให้ ? เป็น Attribute อื่นได้ทุกตัว เช่น Ename,Dnumber, Dname เป็นต้น ซึ่งแน่นอนว่า ในเมื่อมี PK ตัวเดียว ย่อม ต้องเป็น 2NF แน่ๆ ดังนั้นเงื่อนไข แรก ผ่าน ต่อมา คือเงื่อนไขที่ว่า ต้องไม่มี ? ใดๆ ที่สามารถ กำหนด ? ตัวอื่นๆได้ แต่ในที่นี้ นั้น ปรากฏ ว่า Dnumber นั้นมีความสามารถ ที่กำหนดค่าของ Dname , Dmgr_ssn ได้ ( เนื่องจาก Dnumber จะหมายถึง Department ใดๆที่มี ชื่อเพียงชื่อเดียวและ มี department_ssn เพียงหนึ่งเดียวเท่านั้น ได้ )

จึงทำให้ไม่เข้าเงื่อนไข 3NF โดยปริยาย

แก้โดย


แยกมันออกมาจากกันซะ ก็เป็นอันจบ โดยยังเหลือ Dnumber ที่สามารถกำหนดค่า
ดังนี้ได้เอาไว้
 Ssn --> Dnumber
และในอีก ตารางนึงก็ มี ตัวที่ใช้ชี้ได้ กับ ตัวที่ถูกชี้ได้ เอาไว้ด้วยกันซะ
Dnumber --->  Dname หรือ Dmgr_ssn

ตัวอย่างปัญหา 2
เงื่อนไขแรกคือ 2NF?
มี PK ตัวเดียว = 2NF เงื่อนไขแรก ผ่าน เงื่อนไข ต่อไป transitive dependency ?
ในภาพ FD แรกที FD3 , FD 4  พบปัญหา ?
County_name สามารถกำหนดค่าของ Tax_Rate ได้ เพราะ ในเมืองเดียวกันย่อมมีภาษีเท่ากัน

แยกออกมาก่อน

 เมื่อแยกออกไปแล้ว ก็มาดู FD4 ก็พบว่า ในพื้นที่หนึ่งๆ ย่อมมีราคาเดียว เช่นกัน ดังนั้น Area สามารถกำหนด Price ได้โดยไม่ต้องพึ่ง Property_id


และที่นี้ ก็เท่ากับว่า เงื่อนไข ทุกอย่างครบถ้วนแล้ว เพราะไม่สามารถ แยก  Attribute ใดๆ ออกไปได้แล้ว หรือไม่มี Attribute ตัวใดที่สามารถอ้างอิงไปยัง non-prime key ได้แล้ว

ก็เป็นอันเสร็จ


----------

ref - fundamentals of database systems 6th edition elmasri navathe
http://iips.icci.edu.iq/images/exam/databases-ramaz.pdf







วันอาทิตย์ที่ 25 มีนาคม พ.ศ. 2561

Database System - work 8 Informal Design Guidelines for Relation Schemas

ref - fundamentals of database systems 6th edition elmasri navathe
http://iips.icci.edu.iq/images/exam/databases-ramaz.pdf
page -  532

25/3/2561 update 1
1/4/2561 update 2

Informal Design Guidelines  for Relation Schemas

Guideline 1 - ออกแบบ ความสัมพันธ์ ให้ สามารถอธิบายความหมายของมันได้ง่าย และ ไม่รวม attributes จากหลายๆ entity และ relationship มาไว้ใน ตัวเดียว

ซึ่ง หาก ไม่ทำตามแล้ว อาจจะเกิดผลเสีย


ตัวอย่าง การ ที่ นำหลายๆ attributes จากหลายๆ entity และ relationship มาไว้ใน ตัวเดียว ในที่นี้คือสามารถ แยก Dname , Dmgr_ssn  ออกไปได้ เนื่องจาก เรามีการใช้ Dnumber ในการอ้างอิงข้อมูลไปยัง tables ที่มีข้อมูลเหล่านั้นอยู่แล้ว ( หากทำแยกตาราง )

ซึ่ง จะสังเกตุได้ว่า เวลานำไปใช้งานจริงจะเกิดส่วนที่มีการซ้ำซ้อนกัน จำนวนมาก ในส่วนของ Dname, Dmgr_ssn ทั้งยังไม่จำเป็นต้องใช้งานอีกด้วย ถึงต่อให้จำเป็นต้องใช้ก็สามารถใช้ Dnumber อ้างอิงไปดึงข้อมูลมาใช้งานได้อยู่แล้ว  ( หากทำแยกตาราง )

consistent ! หากต้องการ เพิ่มข้อมูลเข้าไปใน Table นี้ โดย Dnumber = 5 แล้ว ข้อมูล ของ Dname , Dmgr_ssn นั้น ก็ยังต้องเหมือนกันตลอดด้วย ในขณะที่ถ้าเราแยก ตาราง ออกจากกันแล้ว เราต้องกำหนดเพียงแค่ Dnumber ให้ถูกเท่านั้น


การลบข้อมูล นั้น หากเราไปลบ ข้อมูลบางตัวแล้ว ข้อมูล อาจจะหายไปเลยก็ได้ เช่นการลบ ข้อมูล ของ Dnumber 1 ออกไป จะกลายเป็นว่าไม่มี Dnumber 1 อยู่เลย ทั้งๆ ที Department นี้อาจจะมีตัวตนแต่ไม่มี คนคอยควมคุมอยู่เท่านั้น แต่ถ้าหาก แยกตารางแล้ว ต่อให้ลบ คนงานคนนี้ออก แต่ ข้อมูลในตารางของ department ก็จะยังคงอยู่ โดยช่อง Dmgr_ssn อาจจะเป็น null แทน


inconsistent ! หากต้องการเปลี่ยน คนควบคุม department ใดๆ แล้วเราจำเป็นต้อง Update ให้ ทุกๆ tuple ที่อยู่ใน Department นั้นๆ ทุกคน ซึ่งอาจจะทำให้เกิดการผิดพลาดใด้ ซึ่งหากแยกตารางแล้ว จะไม่มีปัญหานี้เนื่องจาก สามารถ update ในจุดเดียวได้เลย ที่ ตารางของ department

Guideline 2 -  ออกแบบให้ไม่มีการอัพเดท ที่ผิดปกติ เกิดขึ้น แต่ถ้ามันเกิด ก็ควรจะ note เอาไว้ และให้มันใจว่า โปรแกรมที่อัพเดทนั้น ทำงานได้อย่างถูกต้องแล้ว

Guideline 3 - หลีกเลี่ยงการ กำหนด  attributes  ในฝั่ง relation  ที่อาจก่อให้เกิด Null มากๆ  หากหลีกเลี่ยงไม่ได้ พยายามให้มันเป็น case เฉพาะ เท่านั้นไม่ใช่ ตัวหลักที่จะเกิดได้ เช่น เราจะไม่กำหนด ว่า ใครเป็นคนดูแล department ไหนในฝั่ง คนถูกจ้างเพราะไม่ใช่ทุกคนจะ เป็นคนดูแล department ดังนั้นจะมีคนที่เป็น null เยอะมากจึงควรจะใส่ไว้ใน ฝั่ง department ว่าใครเป็นผู้ดูแลมากกว่า

Guideline 4 - ออกแบบ  relation schemas ที่สามารถ Join กันได้โดยใช้ เงื่อนไขต่างๆที่เท่ากัน กับ attributes ที่มีความสัมพันธ์กันอย่างเหมาะสม โดยต้องยืนยันได้ว่า จะไม่มี การสร้าง tuple ที่เหนือความคาดหมายออกมาได้  โดยหลีกเลี่ยง ความสัมพันธ์ ที่มีการรวมกันที่ไม่ใด้ใช้ foreign key, primary key ขึ้นมา เพราะหากนำมา join แล้วมักจะเกิด tuple ที่เหนือความคาดหมายออกมา

 อย่างเช่นว่า ในภาพ relation ของ EMP_LOCS นั้น เป็น Multivalue ของ สถานที่ ของ Employee ซึ่ง การจะอ้างอิงได้นั้นคือ การใช้ SET ของ Ename , Plocation ในการอ้างอิงข้อมูล หรือ PK ได้ แต่ถ้าหาก เราใช้เพียงตัวใดตัวหนึ่ง ก็จะไม่ใช่ PK และ ดังในภาพ หาก เรานำ แค่ Plocation มาใช้ในการ Join กัน กับ Table EMP_PROJ1 ก็จะเกิดผลลัพธ์ที่ เรียกว่า Spurious tuples การคลอสโพดัค Plocation = Bellaire จะได้ ออกมา 4 Tuple คือ ผลคูณคลอสโพดัค ที่ตรงเงื่อนไขได้แก่

row 1, row4 ของ talbe EMP_LOCS กับ row 1และ row 4 ของ EMP_PROJ1

จะได้ผลลัพธ์ เป็น ประมาณ
{
row1_emp_locs, row1_emp_proj1 ,
row4_emp_locs, row1_emp_proj1 ,
row1_emp_locs, row4_emp_proj1 ,
row4_emp_locs, row4_emp_proj1 ,
}

ซึ่งเป็นผลลัพธ์ที่นำไปใช้ไม่โยชน์ ยาก เพราะ เราจะอ้างอิง ด้วย Ssn ก็จะได้ผลลัพธ์ออกมาถึง 2 ตัว ที่มีค่าซ้ำซ้อนกันเกือบทั้งหมดยกเว้นในส่วนของ Ename

และนี้เป็นผลลัพธ์ทั้งหมดที่ไม่ได้แสดงแค่บ่างส่วน จะสังเกตเห็นได้ว่า มีค่าซ้ำซ้อนกันจำนวนมาก
ซ่ึงในตารางตัวอย่างนี้ จะแก้ปัญหา โดยไม่เปลี่ยนแปลง table เลยคาดว่าไม่น่าจะได้ เพราะ มีการออกแบบมา โดยที่ไม่สามารถใช้ pk ในการ join กันได้ เพราะตาราง EMP_PROJ1  ไม่มี set ที่เป็น pk ของ EMP_LOCS 

วันอังคารที่ 20 มีนาคม พ.ศ. 2561

Database System - work 7 test performance for sqlite and mariadb on Google clound vm low ram

กำหนดการ คิวรี่ ข้อมูล ดังนี้


หาคนที่ได้เกรดรหัสวิชา 010123112 เกรด A

SELECT s.Student_ID,s.First_name,s.Last_name,r.Subjectname,r.Grade
FROM Student as s

INNER JOIN Student_Records as r ON
s.Student_ID = r.Student_ID
   
WHERE r.Subjectid='010123112' AND r.Grade='A'

ORDER BY s.Student_ID ASC;
ดูเกรดรหัสวิชา 080103016 ของคนที่ได้ A รหัสวิชา 010123112

SELECT s.Student_ID,s.First_name,s.Last_name,a .Subjectname,
a.Grade,r.Subjectname,r.Grade
FROM Student as s
INNER JOIN (SELECT * FROM Student_Records WHERE Subjectid='010123112' AND Grade='A' ) as a ON
s.Student_ID = a .Student_ID
INNER JOIN Student_Records  as r ON
a.Student_ID = r.Student_ID AND r.Subjectid='080103016';
และ Hard Ware เป็น VM บน Google Cloud Platform
Ram 0.6 GB



ปัญหาที่พบ
ย้าย ข้อมูลจาก SQLITE3 > > MySQL ?  จากไฟล์ .db จะนำเข้า MySQL ได้ยังไง ผ่านแค่การใช้งาน
CommandLine [ เนื่องจากต้องการให้ข้อมูล มีจำนวนที่เท่ากันทั้ง 2 table และเหมือนกัน ]
แก้โดย
  1. Export to csv file
  2. ใช้ คำสั่ง LOAD DATA INFILE …. เพื่อโหลดข้อมูลจาก csv เข้า Table ใน database ของ MySQL
http://www.sqlitetutorial.net/sqlite-export-csv/
การแปลง ข้อมูลในตารางเป็นcsv
https://stackoverflow.com/questions/3635166/how-to-import-csv-file-to-mysql-table/24170168
การใช้คำสั่ง LOAD DATA INFILE แบบตัวอย่าง

โดย











วันอังคารที่ 20 กุมภาพันธ์ พ.ศ. 2561

Database System - work 6 Try to insert more transcript data to sqlite more than ram


ขั้นตอนการทดลอง

1 .  กำหนดเลขเริ่มต้น
2 .   loop จำนวนมาก count i
3 .  f_name = sarik_<start + count>  , l_name = kumpan<start + count>
4 .  student id = random<55, 60> + 010126 + start + i
5 .  วิชา แต่ละคนเท่ากัน แต่เกรด เซ็ค ไม่เหมือนกัน ใช้การ random
6 .  เพิ่มไปเรื่อยๆ จนได้ขนาดที่พอใจ
โดย มีตัวอย่างโค้ด ที่ใช้ในการเพิ่มข้อมูล ดังนี้


ปัญหาที่พบและทางแก้

แรมมีขนาดใหญ่ การจะ Insert ให้ .db file มีขนาดมากกว่า ram ต้องใช้เวลานานเกินไป

แก้โดยการใช้ VM มาช่วย เพื่อ ใช้ เครื่องที่มี สเปค หน่วยความจำต่ำๆมาใช้งาน

ใช้ Google Cloud Platform



โดยเลือกมาใน service ของ Computer > computer Engin

และการตั้ง เครื่องนั้นกำหนดได้หลากหลายเช่น


ขนาดหน่วยความจำ จำนวน Core รวมทั้ง OS ซึ่งจะมีผลต่อค่าใช้จ่าย ซึ่งผมมีเงินเหลือ จากกิจกรรมที่เขาแจกให้มา 300 เหรียญ นั้นจึงได้นำมาใช้งาน


เปิดเข้า คอมแมนไลน์ ใน SSH ได้จากในภาพ

จากนั้นหลังจากลง Tools ต่างๆ เช่น python sqlite3 แล้ว ก็ ทำการ clone code มาจาก github 


และทำการเพิ่มขนาดไฟล์จนได้ขนาด ที่ต้องการ เช่น 1.3 GB ( ประมาณ 2x ram )


จากนั้นจึงได้เริ่มทำการทดลอง จับเวลาการ คิวรี่ข้อมูล ต่างๆ ดังนี้



table user 532,330 row ใช้เวลาการ แสดงข้อมูลทั้งหมด 156.828 sec





ต่อมาใน table student_records มีข้อมูล 19,184,513 row แต่ปัญหาคือการ คิวรี่ แสดงข้อมูลทั้งหมด ไม่ทราบว่า เป็นที่ terminal หรือว่า ทาง sqlite เองที่ไม่สามารถแสดง จนครบได้ ซึ่งในภาพจะแสดง ทั้ง 3 ครังที่พยายามแล้วค้าง

จึงได้ เปลี่ยนเป็น การคิวรี่แสดงข้อมูล 2 ล้านแถวแรกแทน



ซึ่งจะใช้เวลา 866.787 วินาที


ซึ่งโดยสรุปแล้ว

ตอนนี้ เท่าที่ลอง ยัง insert ได้อยู่ ในขณะที่ขนาดเกิน 2 เท่าของแรมไปแล้ว
แต่การ คิวรี่นั้น ยังไม่ทราบสามารถ ทีั่ขัดข้อง

ref 

การวัดเวลาคิวรี่