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

MySQL on Ubuntu

จากบทความก่อนหน้า ได้เขียนอธิบายวิธีการติดตั้ง SQLite3 บน Ubuntu ไปแล้วนั้น ในบทความนี้ก็จะกล่าวถึงการติดตั้ง MySQL Server บน Ubuntu และวิธีการใช้งาน

ขั้นแรก

อัพเดท Ubuntu's Advanced Packaging Tool (APT) โดยใช้คำสั่ง
sudo apt update

ขั้นที่สอง

ติดตั้ง MySQL โดยใช้คำสั่ง
sudo apt install mysql-server

ขั้นที่สาม 

ตั้งค่า Initialize ของ MySQL โดยใช้คำสั่ง
sudo mysql_secure_installation
โดยหลังจากใช้คำสั่งนี้ ก็จะมีคำถามหลายคำถามขึ้นมา เช่น การตั้ง Password ของ root user

ทดสอบ MySQL Server 

เราสามารถเปิด SQL prompt ได้โดยใช้คำสั่ง
sudo mysql


การสร้าง Database Book, Author, Publisher บน MySQL

 ขั้นตอนแรก

ทำการสร้าง Database โดยใช้คำสั่ง
mysql> CREATE DATABASE BAP;
เมื่อสร้างสำเร็จ ก็ทำการเลือกใช้ Database ที่เพิ่งสร้าง
 mysql> USE BAP;

ขั้นตอนที่สอง สร้าง Table ของ Publisher

โดยใช้คำสั่งจากบทความที่แล้วได้เลย ก็คือ
 mysql> CREATE TABLE publisher (publisher_id INTEGER PRIMARY KEY AUTO_INCREMENT, publisher_name TEXT NOT NULL, location TEXT NOT NULL, publisher_tel TEXT NOT NULL);
ถ้าหากเราใช้ MySQL นั้น ในส่วน field ของ Auto Increment นั้นจะต้องใช้แบบนี้เท่านั้น
AUTO_INCREMENT
ต่างจากที่ใช้ใน SQLite ก็คือ AUTOINCREMENT

ขั้นตอนที่สาม สร้าง Table ของ Author

mysql> CREATE TABLE author (author_id INTEGER PRIMARY KEY AUTO_INCREMENT, author_name TEXT NOT NULL, author_address TEXT, author_tel TEXT, publisher_id INTEGER NOT NULL, FOREIGN KEY(publisher_id) REFERENCES publisher(publisher_id));

ขั้นตอนที่สี่ สร้าง Table ของ Book

mysql> CREATE TABLE book (book_id INTEGER PRIMARY KEY AUTO_INCREMENT, book_name TEXT NOT NULL, release_date TEXT NOT NULL, copy INTEGER NOT NULL, publisher_id INTEGER, FOREIGN KEY(publisher_id) REFERENCES publisher(publisher_id));

ขั้นตอนที่ห้า สร้าง Table ของ Book_Author (M:N Relationship) 

mysql> CREATE TABLE book_author (book_id INTEGER, author_id INTEGER, FOREIGN KEY(book_id) REFERENCES book(book_id),FOREIGN KEY(author_id) REFERENCES author(author_id));

ขั้นตอนสุดท้าย เพิ่มข้อมูลในแต่ละ Table 

Table - Publisher
mysql> INSERT INTO publisher (publisher_name, location, publisher_tel) VALUES ("Pearson Education Limited", "United Kingdom", "020 7010 2336"); 
mysql> INSERT INTO publisher (publisher_name, location, publisher_tel) VALUES ("Mcgraw-hill International Enterprises", "United States", "212-904-2078"); 
mysql> INSERT INTO publisher (publisher_name, location, publisher_tel) VALUES ("Mcgraw-hill International Enterprises", "United States", "212-904-2078"); 
Table -  Book
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Computer Organization and Architecture", "2013", "9", 2); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Concepts of Programming Languages", "2013", "10", 2); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Programming the World Wide Web", "2013", "7", 2); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("The Intel Microprocessors : Architecture, Programmi", "2008", "8", 2); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Management", "2015", "13", 2); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Aircraft Basic Science", "2013", "8", 3); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Essentials of Corporate Finance", "2002", "3", 3); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Egypt in Spectacular Cross-Section", "2005", "1", 3); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Fundamentals of Corporate Finance Alternate Edition 9ED (P)", "2010", "9", 3); 
mysql> INSERT INTO book (book_name, release_date, copy, publisher_id) VALUES ("Corporate Finance : Corporate Principles", "2007", "1", 3);
Table -  Author
mysql> INSERT INTO author (author_name, author_address, publisher_id) VALUES ("William Stallings", "USA", 2); 
mysql> INSERT INTO author (author_name, author_address, publisher_id) VALUES ("Robert W. Sebesta", "Colorado", 2); 
mysql> INSERT INTO author (author_name, author_address, publisher_id) VALUES ("Barry B. Brey", "USA", 2); 
mysql> INSERT INTO author (author_name, author_address, publisher_id) VALUES ("Stephen P. Robbins", "USA", 2); 
mysql> INSERT INTO author (author_name, author_address, publisher_id) VALUES ("Michael J Kroes", "USA", 3); 
mysql> INSERT INTO author (author_name, author_address, publisher_id) VALUES ("Stephen A. Ross", "USA", 3);
Table -  Book Author
mysql> INSERT INTO book_author (book_id, author_id) VALUES (1, 1) -- Computer Organization and Architecture, William Stallings; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (2,2) -- Concepts of Programming Languages, Robert W. Sebesta; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (3,2) -- Programming the World Wide Web, Robert W. Sebesta; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (4,3) -- The Intel Microprocessors : Architecture, Programmi, Barry B. Brey; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (5,4) -- Management, Stephen P. Robbins; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (6,5) -- Aircraft Basic Science, Michael J Kroes; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (7,6) -- Essentials of Corporate Finance, Stephen A. Ross; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (8,6) -- Egypt in Spectacular Cross-Section, Stephen A. Ross; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (9,6) -- Fundamentals of Corporate Finance Alternate Edition 9ED (P), Stephen A. Ross; 
mysql> INSERT INTO book_author (book_id, author_id) VALUES (10,6) -- Corporate Finance : Corporate Principles, Stephen A. Ross;

การทดสอบ Query ข้อมูล

 - ข้อมูลทั้งหมดของ Book

mysql> SELECT * FROM book;
ผลลัพธ์ที่ได้

 - ข้อมูลทั้งหมดของ Author

mysql> SELECT * FROM author;
ผลลัพธ์ที่ได้

 - ข้อมูลทั้งหมดของ Publisher

mysql> SELECT * FROM publisher;
ผลลัพธ์ที่ได้

 - ข้อมูลทั้งหมดของ Book Author

mysql> SELECT * FROM book_author;
ผลลัพธ์ที่ได้

= คำถาม =

Can use the same command from SQLite?

ตอบ    สามารถใช้ได้เกือบทั้งหมด แต่ว่าคำสั่งจาก MySQL จะมีให้ใช้เยอะกว่าและมี Data Types ให้เลือกใช้ได้เยอะกว่า

What changes are needed?

ตอบ    เช่นคำสั่ง AUTOINCREMENT ของ SQLite จะต้องเปลี่ยนเป็น AUTO_INCREMENT





Normalization

ในบทความนี้จะพูดถึงการตัวอย่างการทำ Normalization ให้กับ Relation ในรูปแบบต่างๆ โดยมีรูปแบบที่จะนำเสนออยู่ 3 รูปแบบคือ
  1. First Normal Form (1NF)
  2. Second Normal Form (2NF)
  3. Third Normal Form (3NF)

First Normal Form (1NF)

ตัวอย่าง    

    จากตัวอย่าง Relation ของ ClientRental จะเห็นได้ว่าเป็นแบบ Unnormalized table และมี Primary Key คือ clientNo และยังมี Repeating group อยู่ภายใน Unnormalized table นี้ด้วยซึ่งก็คือ
Repeating Group = (propertyNo, pAddress, rentStart, rentFinish, rent, ownerNo, oName)
    ทำให้เห็นได้ว่า จะมีข้อมูลที่เป็น multiple values หรือข้อมูลที่มีหลายค่า อยู่ภายในความสัมพันธ์
จากตัวอย่างจะเห็นว่า มี 2 ค่า สำหรับ propertyNo (PG4 และ PG16) ในลูกค้า (Client) ที่ชื่อว่า John Kay หากต้องการที่จะทำให้ Unnormalized table ให้เป็น 1NF เราจะต้องทำให้มีแต่ข้อมูลที่เป็น single value ภายในแต่ละหลัก และแต่ละแถว โดยสามารถทำได้โดย การนำ Repeating group ออกไป

    ขั้นแรก    เราจะต้องนำ Repeating group ออก ในที่นี้จะนำ property rented details ที่มีลักษณะซ้อนอยู่ในแถวออกไป และนำไปเป็นข้อมูลในแต่ละแถวที่มี Key เหมือนกัน ดังรูปด้านล่าง
    

และรูปด้านล่างก็คือ Functional Dependencies (fd1 ถึง fd6) สำหรับความสัมพันธ์ ClientRental

    ซึ่ง ณ ตอนนี้ความสัมพันธ์ ClientRental นั้นเป็นแบบ 1NF แล้วแต่ว่าจะมีข้อมูลเดิมๆ ซ้ำกันอยู่หลายรอบ หรือที่เรียกว่า Data Redundancy ซึ่งจะทำให้เกิด Update anomalies ได้หากนำไปใช้

    ขั้นที่สอง    เราจะนำ Repeating group (property rented details ) ออก โดยนำข้อมูลที่ซ้ำไปใส่ไว้ใน relation ที่แยกออกไป โดยจะมี Key attribute คือ clientNo ดังรูป

ทำให้เราสามารถสรุป 1NF relations มาได้ดังนี้
Client                              (clientNo, cName)
PropertyRentalOwner     (clientNo, propertyNo, pAddress, rentStart, rentFinish, rent,
ownerNo, oName)

Second Normal Form (2NF)

    ความหมายของ 2NF ก็คือ relation ที่เป็น First normal form และทุก non-primary-key เป็น
fully functionally dependent บน primary key

    โดยการทำ Normalization สำหรับ 1NF relation ไปเป็น 2NF relation จะทำได้โดย นำ partial dependencies ออกไปจาก relation 

   ClientRental relation จะมี functional dependencies ดังนี้

fd1 clientNo, propertyNo ® rentStart, rentFinish (Primary key) 
fd2 clientNo ® cName (Partial dependency) 
fd3 propertyNo ® pAddress, rent, ownerNo, oName (Partial dependency) 
fd4 ownerNo ® oName (Transitive dependency) 
fd5 clientNo, rentStart ® propertyNo, pAddress, rentFinish, rent, ownerNo, oName (Candidate key) 
fd6 propertyNo, rentStart ® clientNo, cName, rentFinish (Candidate key)
และผลจากการเปลี่ยน 1NF เป็น 2NF เป็นไปดังรูปด้านล่าง


ขั้นตอนของการทำ 2NF ก็คือ เราจะทดสอบ ClientRental relation โดยหาว่ามี partial dependencies บน primary key หรือไม่ จากการทดสอบจะเห็นได้ว่า client attribute (cName) เป็น partial dependencies บน primary key และยังมี (pAddress, rent, ownerNo, oName) อีกที่เป็น partial dependencies และ
property rents attrbutes (rentStart และ rentFinish) เป็น fully dependent บน primary key ทั้งหมด

จากการสังเกตุ Partial dependencies ที่มีภายใน relation หมายความว่า relation นี้ไม่ใช่ 2NF โดยการที่จะเปลี่ยนให้เป็น 2NF สามารถทำได้โดย สร้าง relation ใหม่ขึ้นมา ที่ไม่มี non-primary key เป็น partial dependent และประกอบไปด้วย ส่วนของ primary key ที่เป็น fully functionally dependent

ทำให้เราสามารถสรุป 2NF relations มาได้ดังนี้
Client                    (clientNo, cName) 
Rental                   (clientNo, propertyNo, rentStart, rentFinish) 
PropertyOwner     (propertyNo, pAddress, rent, ownerNo, oName)

Third Normal Form (3NF)

    ความหมายของ 3NF ก็คือ relation ที่เป็นทั้ง First normal form และ Second normal form และไม่มี non-primary key attributes  ที่เป็น transitively dependent บน primary key

โดยการทำ Normalization สำหรับ 2NF relation ไปเป็น 3NF relation จะทำได้โดย นำ transitive dependencies ออกไปจาก relation 

จากการทำ 2NF ด้านบน แสดงให้เห็นถึง functional dependencies ของ Client, Rental และ PropertyOwner ได้ดังนี้
Client 
fd2 clientNo ® cName (Primary key) 
Rental 
fd1 clientNo, propertyNo ® rentStart, rentFinish (Primary key) 
fd5' clientNo, rentStart ® propertyNo, rentFinish (Candidate key) 
fd6' propertyNo, rentStart ® clientNo, rentFinish (Candidate key) 
PropertyOwner 
fd3 propertyNo ® pAddress, rent, ownerNo, oName (Primary key) 
fd4 ownerNo ® oName (Transitive dependency)
จะเห็นได้ว่า non-primary key attributes ทุกตัวในความสัมพันธ์ Client และ Rental เป็น functionally dependent บน primary key ของตัวเอง ทำให้เป็น 3NF แล้วสำหรับความสัมพันธ์นี้

และจะเห็นได้  non-primary key attributes ทุกตัวในความสัมพันธ์ PropertyOwner เป็น functionally dependent บน primary key ของตัวเอง ยกเว้น oName ที่เป็น transitively depentdent บน ownerNo
และการที่จำให้ 2NF เป็น 3NF จะต้องทำให้ transitive dependency หายไป และเราจะสร้าง relation ใหม่ขึ้นมา 2 อัน ดังรูปแบบดังนี้
PropertyForRent     (propertyNo, pAddress, rent, ownerNo) 
Owner                     (ownerNo, oName)


ทำให้เราสามารถสรุป 3NF relations มาได้ดังนี้
Client                     (clientNo, cName) 
Rental                     (clientNo, propertyNo, rentStart, rentFinish) 
PropertyForRent     (propertyNo, pAddress, rent, ownerNo) 
Owner                     (ownerNo, oName)

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

Functional Dependencies

ความหมาย

    Functional dependency เป็นคุณสมบัติของความหมายหรือความหมายของแอตทริบิวต์ในความสัมพันธ์ (Relation) ความหมายจะเป็นตัวบ่งชี้ว่าแอตทริบิวต์เกี่ยวข้องกันอย่างไร และระบุ Function Dependency ระหว่างแอททริบิวต์
    การที่ Functional dependency มีอยู่ การอ้างอิง (Dependency) จะเป็นข้อจำกัด (Constraint)ระหว่างแอตทริบิวต์

ตัวอย่าง


    จากตัวอย่างในรูป ส่วนของ staffNo และ position ของ staff  ของ SL21 เราจะเห็นได้ว่า position ของ staff เป็น Manager. อธิบายง่ายๆก็คือ staffNo จะเป็นตัวที่สามารถกำหนดหรือบอก position ได้
    โดยสามารถอธิบายได้ดังรูปด้านล่าง

    ในรูป (b) จะเห็นได้ว่าเมื่อนำ attribute มาสลับกัน จะไม่สามารถทำได้ เพราะว่า position จะไม่สามารถบ่งบอกได้ถึง staffNo

    ความสัมพันธ์ระหว่าง staffNo และ position คือแบบ one-to-one (1:1) โดย staff number แต่ละเลขจะมีแค่ 1 position. กลับกัน ความสัมพันธ์ระหว่าง position และ staffNo คือ one-to-many (1:N)
โดยที่จะสามารถมี staff หลายคนใน position เดียวกันได้

    สรุปได้ว่า staffNo จะเป็นตัว determinant ของ functional dependency

Update Anomalies

ความหมาย

    เป็นความสัมพันธ์ที่มีข้อมูลที่มีลักษณะ Redundant หรือว่าซ้ำกัน ซึ่งอาจจะทำให้เกิดปัญหาได้ 
โดยสามารถแบ่งประเภทได้เป็น 3 ประเภทคือ

  1. Insertion Anomalies
  2. Deletion Anomalies
  3. Modification Anomalies

ตัวอย่าง

Insertion Anomalies

    การที่เราจะทำการ insert รายละเอียดของ staff คนใหม่ ไปยังความสัมพันธ์ StaffBranch เราจะต้องรวมรายละเอียดของ branch ที่ staff จะไปอยู่ด้วย. ยกตัวอย่างเช่น เราต้องการ insert รายละเอียดของ staff คนใหม่ที่ เลขที่ branch B007 นั้นหมายถึงเราจะต้องใส่ข้อมูลที่ถูกต้องของ branch นั้นๆ และข้อมูลนั้นจะต้องสอดคล้องกับค่าอื่นๆภายใน branch B007 ด้วย จะเห็นได้ว่าการ insert ครั้งนี้จะยังไม่มีผลกระทบซักเท่าไหร่ เนื่องจากข้อมูลของ B007 นั้นมีอยู่ในความสัมพันธ์ของ Branch
    ในอีกกรณีหนึ่งของการ insert คือเมื่อทำการ insert ข้อมูลของ branch ใหม่ที่ไม่มี staff อยู่ในนั้นเลย ไปยัง StaffBranch จึงจำเป็นต้องใส่ null เข้าไปเป็น attribute ของ staff เช่น staffNo ยังไงก็ตาม staffNo นั้นเป็น Primary Key สำหรับความสัมพันธ์ StaffBranch ดังนั้นการที่เราจะเพิ่ม null เข้าไปยัง staffNo จะเป็นการกระทำที่ไม่ถูกต้อง

Deletion Anomalies

    ถ้าเราต้องการที่จะลบข้อมูลออกจาก StaffBranch โดยข้อมูลที่ต้องการลบออกคือ สมาชิกคนสุดท้ายภายใน branch ข้อมูลของ branch นั้นๆก็จะหายไปด้วย เช่นถ้าเราจะลบข้อมูลของ staff SA9 (Mary Howe) จากใน StaffBranch ข้อมูลของ branch B007 ก็จะหายไปจากฐานข้อมูล โดยการออกแบบความสัมพันธ์จากรูปด้านบนจะแก้ปัญหานี้ได้ เนื่องจากมีการเก็บข้อมูลของ Branch แยกไว้ทำให้เมื่อลบข้อมูลออกจาก StaffBranch แล้วข้อมูลของ branch ก็ยังคงอยู่ในความสัมพันธ์ Branch

Modification Anomalies

    หากเราต้องการที่จะแก้ไขข้อมูลจาก 1 ใน attribute ของ branch หนึ่งภายในความสัมพันธ์ StaffBranch ยกตัวอย่างเช่น ต้องการที่จะแก้ไข address ของ branch B003 เราจะต้อง update ข้อมูลทของ staff ทุกคนที่อยู่ใน branch นั้น โดยหากการแก้ไขครั้งนี้ไม่ได้แก้ไขข้อมูลทุกตัวที่เกี่ยวข้อง ก็จะทำให้เกิดความไม่สอดคล้องกันของฐานข้อมูล เช่น branch B003 อาจจะมีหลาย address ใน staff ที่ต่างกัน