วันอาทิตย์ที่ 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 แบบตัวอย่าง

โดย