Basic Kubernetes Part 1 - Kubernetes คืออะไร และ เตรียมเครื่องเพื่อใช้งาน

Basic Kubernetes Part 1 - Kubernetes คืออะไร และ เตรียมเครื่องเพื่อใช้งาน

เกริ่นก่อนเข้าเรื่อง

ก่อนจะเริ่มเนื้อหาผมขอออกตัวก่อนเลยว่าผมไม่ใช่ผู้เชี่ยวชาญด้านการใช้งาน Kubernetes ผมเป็นแค่ Developer ที่ต้องใช้งาน Kubernetes ซึ่งกว่าจะใช้งานเป็นนั้นใช้เวลาานานมาก Video ที่สอนก็เป็นภาษาต่างประเทศฟังก็ไม่ค่อยเข้าใจ พอจะเรียนของไทยคอร์สเรียนก็มีราคา ซึ่งเป็นไปได้ยากที่บริษัทเล็กๆนั้นจะต้องแบกภาระส่ง Developer ไปเรียน ผมจึงเห็นว่ามันคงดีถ้ามีคนสอน Kubernetes แบบพื้นฐานให้ ดังนั้นผมก็เลยทำเองเลยละกัน สอนมันแบบไร้ใบ Certificate นี่แหละ สอนตามที่ทดลองที่เคยทำรู้เท่าไหร่ก็สอนเท่านั้น ดังนั้นผมจึงไม่การันตีว่าเนื้อหาทั้งหมดจะถูกต้องตามหลักการและเป็น Best practice

Kubernetes คืออะไร

Kubernetes หรือเรียกสั้นๆว่า k8s ( ตัว k เป็นตัวแรกและอีก 8 ตัวตามมาก่อนลงท้ายด้วย s ) เป็นตัวโปรแกรมที่มีไว้จัดการตัว Container ศัพท์ทางการเรียกว่า Container Orchestration โดยมันมีหน้าที่ทำการสร้าง container ตามที่เราต้องการ เช่น มีค่า config อะไร ใช้ storage ที่ไหน เชื่อมต่อกับ network อะไร จะให้ contianer ไปอยู่ที่เครื่องไหน container นั้นต้องใช้ RAM , CPU เท่าไหร่ ถ้าเกิดเกินจะต้อง scale out แบบไหน นี่เป็นสิ่งที่ Container Orchestration สามารถทำได้ ซึ่งตัว Container Orchestration นั้นไม่ได้มีแค่ Kubernetes จริงๆยังมี Docker Swarm , Mesos แต่ผู้ที่ได้รับความนิยมในการใช้มากที่สุดคือ Kubernetes (การที่มีคนนิยมใช้มากที่สุดไม่ได้แปลว่ามันดีที่สุด ตัว Docker Swarm , Mesos ก็มีข้อดีของมันซึ่งเหนือกว่า Kubernetes ) จนตอนนี้กลายเป็นเรื่องพื้นฐานที่ Developer ควรจะต้องรู้เหมือน docker

Install Kubernetes

เราสามารถ Install Kubernetes ใช้งานเองได้โดยสามารถดูได้ตาม OS ที่เราใช้

แต่หากใครไม่สะดวกจะลงเองหรือคิดว่าลงแล้วจะติดผมก็มีตัว VM ที่ลง k8s (จริงๆคือ k3s) และโปรแกรมที่จำเป็นต้องใช้งานไว้เรียบร้อยแล้ว คุณสามารถลงตัว Virtualbox แล้ว config network ก็สามารถนำมาใช้งานได้เลย

ใช้งาน Kubernetes ผ่าน VM

  1. ทำการ Install VirtualBox โดยเข้าไปที่ Link นี้ : https://www.virtualbox.org/wiki/Downloads แล้วเลือกตาม OS ที่ใช้

  2. ทำการ Download ตัว VM ตาม Link

  3. ทำการแตก zip แล้วกด double click ที่ไฟล์ training-rocky-k8s.vbox ตัว Virtual box จะเปิดขึ้นมา

  4. ทำการ Setting Network โดยทำการเลือกตามภาพและกดสร้าง

จากนั้นทำการเลือก Network adapter ที่ทำการสร้างขึ้นมา ของผมคือ VirtualBox Host-Only Ethernet Adapter #3(ของคุณอาจไม่เหมือนกับของผม) ให้เป็นดังภาพ

จากนั้นให้ทำการเลือกที่ VM : training-rocky-k8s แล้วเลือก Setting แล้วเลือก Network ดังภาพ

เลือก Adapter 1 เลือกชนิดของ Attach เป็น Host Only Adapter แล้วเลือก Adapter ที่คุณสร้างโดยของผมคือ VirtualBox Host-Only Ethernet Adapter #3 (ของคุณอาจไม่เหมือนของผม)

เลือก Adapter 2 เลือกชนิดของ Attach เป็น NAT

  1. ทำการ Start ตัว VM ขึ้นมา เปิด Browser ขึ้นมาจากนั้นเปิดไปที่ URL : http://192.168.156.101:8080/ ซึ่งถ้าไม่มีอะไรผิดพลาดจะได้ดังภาพ

ซึ่งที่คุณเปิดขึ้นมามันคือ Visual Code ที่ใช้งานบน Server ดังนั้นคุณสามารถสร้างไฟล์ แก้ไขไฟล์ สามารถสั่งใช้งานคำสั่งต่างๆผ่าน Terminal ใน Visual code ได้เลย

ทดสอบการใช้งาน Kubernetes

ส่วนนี้เรามาลองทดสอบว่าที่เราทำการ Install Kubernetes นั้นสำเร็จหรือไม่ โดยมีขั้นตอนดังต่อไปนี้

  1. สร้างไฟล์ test-deploy.yml โดยจะวางที่ไหนก็ได้ตามใจ โดยตัวไฟล์จะมีข้อมูลตามด้านล่าง
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 31040
targetPort: 80
nodePort: 31040
name: nodered-port
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
  1. ทำการสั่งให้ Kubernetes ทำการสร้าง container ในรูปแบบที่เราต้องการ
1
kubectl apply -f test-deploy.yml

  1. ทำการสั่ง Command ด้านล่างเพื่อเช็คว่า Kubernetes ทำการสร้าง container ให้เราตามที่ต้องการหรือไม่
1
2
kubectl get pods
kubectl get service

  1. เปิด Web browser จากนั้นไปที่ URL : http://<ip ของเครื่องที่ลง Kubernetes>:31040 โดยของผม ip ของเครื่องที่ลง Kubernetes คือ 192.168.156.101 ดังนั้น URL ของผมจึงเป็น http://192.168.156.101:31040

อธิบายว่าเราทำอะไรไป

ไฟล์ test-deploy.yml นั้นเป็นไฟล์ที่ใส่ข้อมูลที่จะสั่งให้ Kubernetes นั้นทำการสร้าง container แบบไหน เปิด Port อะไร และให้เข้ามาจาก Port อะไร โดยไฟล์ test-deploy.yml เป็นการสั่งให้สร้าง container nginx ขึ้นมาโดยกำหนดว่าให้มี 3 container คอยช่วยงานกัน (เห็นได้จากสั่ง kubectl get pods แล้วเห็นว่ามี 3 ตัวที่ run อยู่) จากนั้นทำการบอกว่าให้สามารถเข้าถึง container นี้ได้จาก Port 31040 จากเครื่องที่ลง ( เห็นได้จากสั่ง kubectl get service แล้วเห็นว่ามีการ Bind Port 31040 กับ service nginx ) ซึ่งเมื่อทดลองเปิด Browser แล้วเข้าไปที่ http://<ip ของเครื่องที่ลง Kubernetes>:31040 ก็จะเห็นว่าเราสามารถเข้าไปใช้งาน nginx ที่เราสร้างได้

ลบสิ่งที่สร้าง

ทำการสั่งคำสั่งด้านล่างเพื่อลบ container ที่ทำการสร้าง

1
kubectl delete -f test-deploy.yml

สรุป

ตอนนี้เราได้รู้กันแล้วว่า Kubernetes คืออะไรใช้ทำอะไร จากนั้นเราก็ได้ทำการ Install Kubernetes เพื่อจะนำมาทำการใช้งาน โดยมีวิธีให้ลงทั้งแบบลงบน OS เลย หรือจะใช้ผ่าน VM ที่ผมสร้างขึ้นมาให้ และสุดท้ายเราได้ลองสั่งใช้งานตัว Kubernetes ให้ทำการสร้าง Container nginx เพื่อให้เรามาทดลองใช้งาน

สำหรับตอนต่อไปเราจะมาทำความรู้จักเกี่ยวกับ Pod ว่ามันคืออะไร เวลาจะสร้างมันจะทำอย่างไร

Basic Database System Part 7 - ออกแบบ Database ด้วย ER Model ตอนที่ 2

Basic Database System Part 7 - ออกแบบ Database ด้วย ER Model ตอนที่ 2

ตอนที่แล้วเราได้รู้วิธีการเขียน ER Model กันมาแล้ว ตอนนี้เราจะมาเปลี่ยน ER Model ให้กลายเป็น Relational Database Model เพื่อเอาไปเป็นตัว Table ตั้งต้นก่อนจะนำไปทำ Normalization Process

เปลี่ยน ER Model ไปเป็น Relational Database Model

เราจะเอา ER Model จากตัวอย่างโจทย์การประชุมวิชาการทางศาสนามาเป็นตัวอย่างการแปลง ER Model ไปเป็น Relational Database Model

1. แปลงเป็น Entity ให้กลายเป็น Relation Table ตาม Attribute ที่มี โดยให้ Key Attribute มาเป็น Primary key

จากตัวอย่างเราจะแปลง Entity : SPEAKER , RELIGION , TEXT ไปเป็น Relation Table ซึ่งจะแปลงเป็น Table ได้ดังภาพ

2. แปลง Relationship แบบ M to M หรือ Relationship ที่เกิดจาก Entity ที่มากกว่า 2 ไปเป็น Relation Table โดยเอา Primary key ของแต่ละ Entity ไปเป็น Primary key ของ Table ใหม่ (และเป็น FK ด้วย) และเอา Attribute ของ Relationship ไปเป็น Attribute ในตาราง

จากตัวอย่างเราจะเห็น Relationship ที่เป็น M to M อยู่คือ SPEAK กับ READ ซึ่งจะแปลงเป็น Table ได้ดังภาพ

3. ดูที่ Relationship แบบ 1 To M จากนั้นนำ Primary key ของฝั่ง M ไปเป็น Foreign key ของ Table ฝั่ง 1

จากตัวอย่างเราจะเห็น Relationship : HAS ที่เกิดจาก Entity : RELIGION กับ Entity : TEXT เป็น 1 to M ซึ่งจะทำให้เราแก้ไข Table : TEXT เป็น

4. ดูที่ Relationship แบบ 1 to 1 จากนั้นตัดสินใจเลือกฝั่งใดฝั่งหนึ่งเป็น Table หลักจากนั้นให้ Table รองเอา Primary key ของ Table หลักมาเป็น Foreign key

เนื่องจากความสัมพันธ์นี้ไม่มีตัวอย่างการประชุมวิชาการเลยขอเอาความสัมพันธ์ พนักงาน กับ แผนก มาเป็นตัวอย่าง

ซึ่งเราจะเห็นว่ามี Entity พนักงาน กับ แผนก โดยเราตัดสินใจว่าจะเอา Entity พนักงานเป็น Table หลัก ซึ่งเราจะได้ Table ออกมาดังภาพ

ผลลัพธ์การเปลี่ยน ER Model เป็น Relational Table

ผลลัพธ์จากการเปลี่ยน ER Model การประชุมวิชาการทางศาสนา ไปเป็น Relational Model จะเป็นดังภาพ

Associative Entity

อันนี้เป็น Type พิเศษของ Relationship ซึ่งเกิดจาก Relationship แบบ M to M ที่อยากจะมีแบบหลายครั้ง พูดแบบนี้คุณอาจคิดไม่ออก ลองนึกภาพการยืมหนังสือในห้องสมุด โดยมี Entity คือ สมาชิก กับ หนังสือ เราจะเขียน ER Model ได้ดังภาพ

จากนั้นเราเปลี่ยน ER Model เป็น Relational Table ได้ดังภาพ

ดูแล้วเหมือนไม่มีปัญหาอะไร แต่ปัญหามันจะเกิดขึ้นถ้าเราอยากเก็บประวัติการยืมหนังสือ ตัวอย่างช่น ถ้าหากสมาชิก M001 ต้องการยืมหนังสือชื่อ “Database Design” ข้อมูลที่จะ Save ลง Table : ยืม จะเป็นดังภาพ

คราวนี้ถ้าเราอยากเก็บว่า M001 ยืมหนังสือชื่อ “Database Design” ไปแล้วกี่ครั้งมันจะทำไม่ได้เพราะ Primary key จะซ้ำ ตรงนี้บางท่านบอกว่างั้นก็เพิ่ม Attribute วันที่ยืมเข้าไปสิ ซึ่งก็ทำได้ครับ พอทำแล้วสัญลักษณ์จะเปลี่ยนไปเป็นแบบภาพด้านล่าง เพื่อให้เข้าใจว่า Relationship แบบนี้เกิดซ้ำได้

ซึ่ง Table ที่ได้จะเป็น

แต่สมมติว่า Associative Entity นี้จะต้องไปมี Relationship กับ Entity อื่น ซึ่งอาจจะทำให้เกิดการเอา Primary key ของ Associative Entity ไปเป็น Foreign key ซึ่งจากตัวอย่างนี้ต้องใช้ถึง 3 Attribute ซึ่งบางกลุ่มเห็นว่ามันยุ่งยากจึงมีการสร้าง Surrogate key (key แทน ) มาใช้แทน Primary key 3 attribute ซึ่งสามารถทำได้ดังภาพ

ซึ่งสามารถเปลี่ยนเป็น Table ได้ดังภาพ

โดย Primary key จะกลายเป็น ID_การยืม ส่วน Primary key เก่า 3 Attribute จะกลายเป็น Unique Key แทน

สรุป

ตอนนี้เราได้เห็นวิธีการเปลี่ยน ER Model ให้กลายเป็น Relational Database Model เพื่อนำไปตั้งต้นในการทำ Normalization Process ต่อ ซึ่งจะเห็นได้ว่าไม่ยากเลย และตอนนี้ได้แนะนำ Entity อีก Type นึงซึ่งก็คือ Associative Entity ว่ามันคืออะไร เอาไปใช้ตอนไหน

สำหรับตอนนี้น่าจะเป็นตอนสุดท้ายในชุด Basic Database System ก็หวังว่าทุกตอนน่าจะสร้างประโยชน์ให้กับผู้ที่เข้ามาอ่านไม่มากก็น้อย และสุดท้ายผมอยากจะฝากไว้ว่า “พื้นฐานเป็นเรื่องสำคัญ” ถ้าคุณเข้าใจพื้นฐานคุณจะสามารถต่อยอดความรู้อื่นๆได้ไม่ยาก แล้วพบกันใหม่ในหัวข้ออื่นๆสวัสดีครับ

Basic Database System Part 6 - ออกแบบ Database ด้วย ER Model ตอนที่ 1

Basic Database System Part 6 - ออกแบบ Database ด้วย ER Model ตอนที่ 1

สำหรับ 2 ตอนที่แล้วเราได้เรียนรู้การทำ Normalization ให้ถึงระดับ 5NF ไปแล้ว แต่ผมเชื่อว่าคงมีหลายคนสงสัยว่า เราจะได้ตารางเริ่มต้นแล้วเอามาทำ Normalization ยังไง อยู่ดีๆมันขึ้นมาเองเลยเหรอ จริงๆมันมีวิธีให้ได้มาซึ่งตารางนั้น

  1. เอามาจาก Report ใช่ครับ คุณฟังไม่ผิดครับ ปกติงานส่วนใหญ่จะรู้ว่าต้องเก็บข้อมูลอะไรส่วนหนึ่งจะรู้จาก Report ครับ เพราะสุดท้ายแล้วเราจะเอา Report ออกมาดูว่ามีอะไรในระบบ มีอะไรทำสำเร็จเท่าไหร่ ไม่สำเร็จเท่าไหร่ ซึ่ง Report ส่วนใหญ่เป็นตาราง

  2. ใช้วิธีการออกแบบที่มีคนคิดขึ้นมาแล้ว โดยแต่ละวิธีเมื่อออกแบบเสร็จเราจะได้เป็น Conceptual model ตามแต่ละวิธี โดย Conceptual model คือ model ที่ทำให้เราเข้าใจว่าสิ่งที่เราสนใจนั้นเกี่ยวข้องกันอย่างไร มีโครงสร้างอย่างไร ซึ่งตัว Conceptual model นี้ไม่ขึ้นตรงกับ DBMS เจ้าไหน และ Database model อะไร เมื่อคุณได้ตัว Conceptual model ออกมาคุณสามารถแปลงมันไปเป็น Database model ใดก็ได้ โดย Conceptual model ที่เป็นที่นิยมมากๆมี 2 ชนิดคือ ER Model กับ ORM โดยที่ผมจะเขียนนั้นคือ ER Model เพราะคนส่วนใหญ่ใช้ (คนส่วนใหญ่ใช้ไม่จำเป็นต้องดีที่สุดนะครับ ลองไปดูการออกแบบด้วย ORM ดูเพิ่มเติมครับ บางทีอาจจะสนุกกว่าการใช้ ER )

Entity Relationship Model ( ER Model )

Entity Relationship Model คือ Model ที่พูดถึง Entity ซึ่งหมายถึงสิ่งที่เราสนใจในระบบ อาจจะหมายถึงหนังสือ คน การโอน การยืม ตามแต่สิ่งที่ระบบนั้นสนใจ กับ Relationship ซึ่งหมายถึงความสัมพันธ์ ( เตือนไว้ตรงนี้เลยว่าไม่เกี่ยวกับ Relation ในเนื้อหา Relational database ) รวมแล้ว Entity Relationship model คือ Model ที่แสดงความสัมพันธ์ระหว่าง Entity ในระบบ

สัญลักษณ์ของ Entity Relationship Model

ถ้าสมมุติเราทำระบบเก็บข้อมูลพนักงานในบริษัท Entity ที่เราน่าจะต้องสนใจคือ “พนักงาน” ซึ่งพนักงานก็น่าจะมีข้อมูลเกี่ยวกับ รหัสพนักงาน , ชื่อ-นามสกุล , วันที่เริ่มทำงาน , เพศ ซึ่งด้วยข้อมูลทั้งหมดนี้เราสามารถเขียนมันให้อยู่ในสัญลักษณ์ดังภาพด้านล่าง

โดยเราจะไล่ทีละสัญลักษณ์

Entity

นี่คือสัญลักษณ์แทน Entity โดย Entity เราจะตั้งชื่อว่าอะไรก็ใส่เข้าไป โดยในตัวอย่างแรก Entity พนักงาน เราก็ใส่พนักงานเข้าไปแทน Entity

Key attribute

นี่คือสัญลักษณ์แทน Key attribute โดย Key attribute คือค่าที่ใช้อ้างอิงถึง Entity ได้เพียง Entity เดียว (มองง่ายๆว่าคือ Primary) ในตัวอย่างแรกของเราคือรหัสพนักงาน ซึ่งรหัสพนักงานสามารถใช้เป็นตัวอ้างอิงถึง Entity ได้เพียง Entity เดียว โดย Key attribute อาจมีหลายตัวได้

Attribute

นี่คือสัญลักษณ์แทน Attribute ซึ่งคือค่าต่างๆที่ Entity นั้นจากตัวอย่างของเราคือ ชื่อ-นามสกุล (ไม่เป็น Key attirbute เพราะอาจจะมีคนชื่อนามสกุลซ้ำกันก็ได้ เช่น บุญชู บ้านโข้ง อาจจะมีหลายคน) เพศ วันที่เริ่มทำงาน

ความสัมพันธ์ระหว่าง Entity

ระบบที่เรากำลังออกแบบคือระบบเก็บข้อมูลพนักงานในบริษัท Entity ของเราไม่ได้มีเพียงแค่ Entity พนักงานอย่างเดียว มันน่าจะมี Entity อื่นด้วย ตัวอย่างเช่น Entity แผนกดังภาพ

แล้วความสัมพันธ์ระหว่าง Entity พนักงานกับ Entity แผนกเกี่ยวข้องกันยังไง อันนี้แล้วแต่ระบบที่คุณสนใจว่ามันเกี่ยวข้องกันยังไงตาม อย่างระบบของผมที่สมมติขึ้น Entity พนักงานกับ Entity แผนก เกี่ยวข้องกันคือ พนักงานอยู่ภายใต้แผนก ซึ่งจากความสัมพันธ์นี้จะเขียน Model ได้ดังภาพ

โดยเราสามารถอ่านความสัมพันธ์ระหว่าง Entity พนักงาน กับ Entity แผนกได้แบบนี้

  • 1 Entity พนักงาน อยู่ภายใต้ Entity แผนก ได้เพียง 1 Entity แผนก (ภาษามนุษย์คือ พนักงาน 1 คน อยู่ภายใต้ แผนก ได้แผนกเดียว)

  • 1 Enttiy แผนก มี Entity พนักงาน อยู่ภายใต้ได้ “หลาย” Entity พนักงาน ( ภาษามนุษย์คือ แผนก 1 แผนก มีพนักงาน อยู่ภายใต้ ได้หลายคน)

Relationship

Relationship ใช้สัญลักษณ์ สี่เหลี่ยมขนมเปียกปูนในการบอกความสัมพันธ์ว่าคือความสัมพันธ์มีตัวอักษร 1 , M , N เป็นจำนวนความสัมพันธ์

คราวนี้คุณอาจจะสงสัยว่าตัวอักษร 1 , M อะไรพวกนี้มันเขียนยังไง จะรู้ได้ไงว่ามันเป็น 1 หรือ M เอาอะไรตัดสินใจ เดี๋ยวเราค่อยๆมาทำความเข้าใจกันครับ

ลากเส้นความสัมพันธ์

ถ้าเราอยากรู้ว่า Entity มีความเกี่ยวข้องกันยังไงให้ลองยกตัวอย่างขึ้นมา เช่น พนักงาน E001 , E002 , E003 , E004 เนี่ยมันอยู่ภายใต้ แผนก DEV , QA ยังไง ถ้าคิดไม่ออกลองดูภาพด้านล่างครับ

จากภาพคุณจะเห็นว่าความสัมพันธ์ว่าพนักงานแต่ละคนอยู่ภายใต้แผนกอะไร หากคุณสังเกตดีๆ คุณจะเห็นว่า 1 พนักงานนั้นอยู่ได้ 1 แผนก ส่วนถ้ามองฝั่งแผนกจะเห็นว่า 1 แผนกนั้นมีพนักงานอยู่ได้หลายคน ( M ) ดังนั้นเวลาไปเขียนสัญลักษณ์ตัวเลขจะเป็นฝั่ง Entity พนักงานจะเป็นตัว M เพื่อบอกว่า 1 Entity แผนกมีหลาย Entity พนักงาน ส่วนฝั่งแผนกจะใส่เลข 1 เพื่อบอกว่า 1 Entity พนักงานอยู่ได้ 1 Entity แผนก

แล้วมีความสัมพันธ์แบบอะไรบ้าง

ตัวอย่างความสัมพันธ์อยู่ภายใต้เป็นความสัมพันธ์แบบ 1 to M แต่คุณก็น่าจะเกิดคำถามว่ามันมีความสัมพันธ์แบบอื่นไหม เช่น แบบ 1 to 1 หรือ M to M อะไรแบบนี้ ซึ่งผมก็ขอบอกเลยครับว่ามีครับ เรามาลองดูตัวอย่างกัน

1 to 1

จริงๆความสัมพันธ์ระหว่าง พนักงาน กับ แผนก ไม่ได้มีความสัมพันธ์แค่ “อยู่ภายใต้” จริงๆยังมีความสัมพันธ์อื่นอีก เช่น ความสัมพันธ์ เป็นหัวหน้าแผนก ซึ่งความสัมพันธ์แบบเป็นหัวหน้าแผนกนี้เป็นความสัมพันธ์แบบ 1 to 1 คือ พนักงาน 1 คนเป็นหัวหน้าแผนกได้เพียง 1 แผนก ส่วน แผนก 1 แผนก เป็นมีหัวหน้าได้ 1 คน โดยเราสามารถทดสอบด้วยการลากเส้นความสัมพันธ์ดังรูปด้านล่าง (ขอละการเขียน Attriubte นะครับ)

M to M

คราวนี้มาลองคิดดูว่าบริษัทเนี่ยน่าจะมีโปรเจคที่บริษัทรับมาทำซึ่งแน่นอนว่าพนักงานน่าจะต้องถูกจัดให้ทำโปรเจคนั้น โดยพนักงานหนึ่งคนอาจจะถูกให้ทำหลายโปรเจค ดังนั้นความสัมพันธ์มันน่าจะเป็นแบบ M to M ซึ่งเราสามารถทดสอบเขียนความสัมพันธ์ดังรูปด้านล่าง (ขอละการเขียน Attriubte นะครับ)

Relationship มี Attribute ได้ไหม

คุณอาจจะมีคำถามว่า Relationship มันมี Attribute ได้ไหม คำตอบคือมันมีได้ครับ ยกตัวอย่างเช่นความสัมพันธ์ ที่ พนักงานต้องรับผิดชอบโปรเจคนั้นอาจมีค่าที่เกี่ยวข้องกับความสัมพันธ์นั้น เช่น จำนวนชั่วโมงที่ต้องรับผิดชอบต่อสัปดาห์ ซึ่งเป็นเรื่องที่เกิดขึ้นได้กับทุกความสัมพันธ์ ดังนั้นเราสามารถเขียน Attribute ของความสัมพันธ์ได้ดังภาพ

ความสัมพันธ์เกิดจาก Entity มากกว่า 2 Entity ได้หรือไม่

ตัวอย่างมาทั้งหมดนั้นเป็นความสัมพันธ์ที่เกิดจาก Entity 2 ตัวมีความสัมพันธ์กัน แล้วถ้า Entity มากกว่า 2 ตัวสามารถมีความสัมพันธ์กันได้ไหม คำตอบคือได้ครับ ตัวอย่างความสัมพันธ์ การขายของ โดยมี Entity ที่เกี่ยวข้องคือ บริษัทที่ขาย ของที่ขาย โปรเจค โดยเขียนความสัมพันธ์ดังภาพ (ขอละการเขียน Attribute ของ Entity ครับ)

Entity สามารถมีความสัมพันธ์กับตัวเองได้หรือไม่

คำตอบคือได้ครับ ยกตัวอย่าง พนักงานสามารถถูกกำหนดหน้าที่ให้ดูแลพนักงานคนอื่น เหมือนเป็นพี่เลี้ยง ซึ่งพนักงานหนึ่งคนสามารถดูแลพนักงานได้หลายคนและพนักงานสามารถถูกดูแลจากพนักงานหลายคนได้ ซึ่งเราสามารถเขียนความสัมพันธ์ได้ดังภาพ (ขอละการเขียน Attribute ของ Entity ครับ)

มาลองเขียน ER Model จากโจทย์กัน

มีการจัดประชุมวิชาการทางศาสนาขึ้นโดยในงานจะมีผู้ขึ้นมาพูดเกี่ยวกับศาสนาต่างๆ โดยการประชุมจะพูดเกี่ยวกับศาสนานั้นว่าศาสนานั้นชื่อศาสนาอะไร มีศาสดาเป็นใคร พระคัมภีร์หรือหนังสือเกี่ยวกับศาสนาคืออะไร โดยในงานประชุมวิชาการนี้จะมี Speaker มาพูดเกี่ยวกับศาสนาต่างๆ ซึ่ง Speaker แต่ล่ะท่านนั้นเป็นผู้เชี่ยวชาญเคยอ่านหนังสือของศาสนาต่างๆมาแล้ว โดยทางงานวิชาการได้ให้ข้อมูลเกี่ยวกับศาสนาและ Speaker ที่จะมาพูดมาดังภาพ

หน้าที่ของเราคือทำ ER Model จากข้อมูลทั้งหมดที่มี

วิเคราะห์โจทย์

จากข้อมูลที่ได้เราพอเห็นคร่าวๆว่าน่าจะมี 2 Entity แน่นอนคือ RELIGION กับ SPEAKER แน่นอน และทั้งสองน่าจะมีความสัมพันธ์ด้วยความสัมพันธ์ SPEAK คือ SPEAKER SPEAK RELIGION ซึ่งจะได้ ER Model เบื้องต้นออกมาดังภาพ

ซึ่งข้อมูลที่เหลือที่ยังไม่อยู่ใน ER Model คือข้อมูลเกี่ยวกับ Text ซึ่งถ้าเราสังเกตดีๆจะเห็นว่า TEXT น้ันมีความสัมพันธ์กับ RELIGION และ SPEAKER ดังนั้นเราน่าจะให้ตัว TEXT เป็น Entity ด้วย ซึ่งจะได้ ER Model ออกมาดังภาพ

สรุป

สำหรับตอนนี้เราได้เรียนรู้เกี่ยวกับการเขียน Entity Relationship Model ว่ามีเขียนยังไง มีสัญลักษณ์อะไรบ้าง ไปจนถึงทดลองเขียน Entity Relationship Model จากโจทย์งานประชุมวิชาการศาสนา ซึ่งทั้งหมดที่เราเรียนรู้ไปเป็นเพียงบางส่วนของ Entity Relationship Model ซึ่งผมคิดว่าใช้บ่อยในการทำงาน จริงๆยังมีอีกหลายสัญลักษณ์ที่ผมไม่ได้พูดถึงตัวอย่างเช่น Weak Entity เป็นต้น ซึ่งถ้าใครสนใจสามารถไปหาอ่านเพิ่มได้ สำหรับตอนหน้าเราจะมาเปลี่ยน Entity Relationship Model นี้ให้กลายเป็น Relational Database Model เพื่อเอาไปใช้งานกัน

Ref

ตัวอย่างโจทย์เอามาจากหนังสือ Relational database systems : language, conceptual modeling and design for engineers

500 ล้านปีของความรัก วิทยาศาสตร์ของอารมณ์ ความรัก และความเกลียดชัง

500 ล้านปีของความรัก วิทยาศาสตร์ของอารมณ์ ความรัก และความเกลียดชัง

500 ล้านปีของความรัก วิทยาศาสตร์ของอารมณ์ ความรัก และความเกลียดชัง

ผมได้รู้จักหนังสือเล่มนี้จาก Page : Tactschool ที่แนะนำหนังสือน่าอ่านเมื่อหลายปีที่แล้ว แต่ตอนนั้นไม่ได้อ่านเพราะไปอ่านหนังสือเกี่ยวกับปรัชญาและการลงทุน จนเมื่อไม่นานมานี้ผมไปเห็นหนังสือชุดนี้ใน TK Park ก็เลยยืมมาอ่าน ซึ่งพอได้อ่านแล้วก็เข้าใจเลยทำไมหลายคนถึงแนะนำว่าเป็นหนังสือดี

หนังสือเล่มนี้พาเราไปเรียนรู้เกี่ยวกับ “มนุษย์” ซึ่งก็คือตัวเราผ่านคำถามที่เราอาจจะเคยสงสัยหรือบางเรื่องที่ธรรมดามากๆจนเราไม่เคยนึกสงสัย ตัวอย่างเช่น ทำไมเราชอบกินของหวานของมันทั้งๆที่รู้ว่ามันอันตรายต่อสุขภาพ ทำไมเราต้องฆ่ากันเพียงเพราะพูดหยามกันเล็กๆน้อยๆ ทำไมคู่รักมักจะทำอะไรแบบเด็กๆ อารมณ์มาจากไหน ยาแก้ปวดทำไมสามารถช่วยให้เจ็บจากการอกหกน้อยลง ทำไมคนเราถึงฆ่าล้างเผ่าพันธุ์กันได้ ทุกคำถามที่ว่ามาหนังสือเล่มนี้มีคำตอบให้เราทั้งหมด แถมเป็นคำตอบที่ไม่ได้มโนขึ้นมาแต่ผ่านการศึกษาจากการทดลอง การแสกนสมอง ด้วยวิธีการทางวิทยาศาสตร์ ดังนั้นมันจึงน่าเชื่อถือและสอดคล้องกัน และที่เด่นที่สุดของหนังสือเล่มนี้คือการเขียนเป็นเรื่องเล่าให้เราอ่านได้อย่างได้เรื่อยๆสบายๆไม่เครียด เหมือนเรามีเพื่อนผู้รู้มาเล่าเรื่องให้เล่าฟังด้วยศัพท์ง่ายๆสนุกและเห็นภาพ ดังนั้นคุณจะอ่านมันได้แบบเพลินๆเลยทีเดียว

ในส่วนต่อไปผมจะเขียนเล่าสิ่งที่ผมได้จากหนังสือซึ่งถือเป็นส่วนน้อยมากๆจากในหนังสือ

ทำไมทหารถึงเดินสวนสนาม

เคยสงสัยไหมว่าทำไมเราซึ่งจะไปเป็นทหารทำไมเราต้องมาฝึกเดินสวนสนาม ต้องมาวิ่งจัดแถวตอนหน้ากระดาน 10 คน 20 คน วิ่งวนไปวนมา ฝึกแบบนี้ซ้ำไปซ้ำมา ในสมัยก่อนอาจจะจำเป็นในรูปแบบการจัดทัพสู้กันในระยะประชิด แต่ในปัจจุบันเราใช้ปืนยิงไกลห่างกันเป็น 100 - 200 เมตร ก็ยิงถึง แล้วถ้าเคลื่อนที่แบบสวนสนามรับรองเลยโดนยิงตายง่ายๆแน่ ด้วยการทำที่ไม่สมเหตุสมผลนี้ทำให้นักวิทยาศาสตร์ท่านหนึ่ง (ผมจำชื่อไม่ได้แล้ว) ที่ได้ไปเป็นทหารเกิดความสงสัย ว่าทำไปทำไม แต่จริงๆมันมีอีกคำถามหนึ่งซึ่งเขาก็รู้สึกได้และสงสัยคือตอนเป็นทหารเขาเริ่มรู้สึกแปลกๆหลังจากฝึกสวนสนามไปนานๆ เขารู้สึกว่าเขาเริ่มรู้สึกถึงความเป็นกลุ่ม รู้สึกฮึกเหิมไปกับกลุ่ม เริ่มรู้สึกอยากทำอะไรให้กับกลุ่ม ความรู้สึกถึงความเป็นตัวเองเริ่มลดลง ตอนแรกเขาคิดว่าเขาเป็นเพียงคนเดียวแต่เมื่อถามหลายๆคนที่ฝึกด้วยกันก็ได้คำตอบว่ารู้สึกแบบเดียวกัน

อาการแบบนี้ไม่ได้เกิดแค่การเดินสวนสนาม อาการเหล่านี้สามารถเกิดได้กับการร้องหรือการเต้นที่ทำเป็นหมู่คณะ ตัวอย่างง่ายๆถ้าคุณได้ยินและร้องเพลงชาติตอนทีมชาติของเราได้เหรียญทองในงานแข่งขันระดับใหญ่ๆเช่น เอเชียนเกมส์ หรือ ซีเกมส์ คุณจะรู้สึกถึงความฮึกเฮิม ความรักชาติ รู้สึกเราเป็นหนึ่งเดียวกันอย่างแปลกประหลาด (ทั้งๆที่เราฟังเพลงชาติที่อื่นเราไม่ได้อิน บางคนถึงกับบอกว่าไร้สาระ)

เมื่อความเป็นตัวตนถูกลดลงรู้สึกถึงความเป็นกลุ่มมากขึ้นอยากทำเพื่อกลุ่มมากขึ้น ดังนั้นมันจึงสามารถให้คุณทำสิ่งที่คุณไม่คิดว่าจะทำได้เช่นสละชีวิตให้กลุ่ม ทำอะไรที่ปัจเจกเขาไม่ทำกัน ทีนี้คงรู้แล้วนะครับว่าทำไมทหารถึงมีการฝึกการเดินสวนสนาม

การแลกเปลี่ยน เรื่องธรรมดาของมนุษย์แต่ไม่ธรรมดาในทางธรรมชาติ

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

แต่การแลกเปลี่ยนเหล่านี้หายากในสิ่งมีชีวิตอื่นบนโลกมาก ลิงชิมแปนซีญาติของเรานั้นก็ไม่สามารถทำได้ในระดับเดียวกับเรา พวกมันสามารถแลกเปลี่ยนของที่มันเห็นคุณค่ามากกับน้อยได้ เช่น แลกองุ่นกับแครอท (หวานมาก กับ ไม่หวานเลย) แต่มันไม่สามารถแลกเปลี่ยนของที่มีค่ามากๆกับมากรองลงมาได้ เช่น แลกองุ่นกับแอปเปิ้ล (หวานมากสุด กับ หวานรองลงมา) แตกต่างจากมนุษย์ที่สามารถแลกเปลี่ยนได้เกือบทุกอย่างภายใต้ความพอใจของตนเอง เราสามารถแลกของมีค่าจำนวนมากเพื่อได้กระเป๋าโง่ๆที่ใช้ประโยชน์อะไรไม่ได้เยอะ

แล้วความสามารถในการแลกเปลี่ยนมันสำคัญอย่างไร เมื่อเราเริ่มแลกเปลี่ยนมันมีผลพวงกระทบเป็นลูกโซ่ ลองคิดตามนะครับ มีสองหมู่บ้าน หมู่บ้านนึงอยู่ติดทะเล กับ อีกหมู่บ้านอยู่ในป่า ทั้งสองหมู่บ้านบังเอิญได้พบกันและได้แลกเปลี่ยนของมีค่าของตน เช่น หมู่บ้านทะเลแลกปลากับหมู่บ้านในป่า ซึ่งเป็นของที่แต่ละฝ่ายอยากได้ เมื่อเริ่มแลกเปลี่ยนคนในแต่ละหมู่บ้านก็เริ่มอยากได้ของจากอีกฝั่งมากขึ้น เกิดเป็นการค้าขาย เมื่อมีการค้าขายก็ย่อมเกิดการแข่งขันจะทำอย่างไรให้ได้ของที่อีกฝั่งอยากได้ในปริมาณที่มากขึ้น แต่ละหมู่บ้านก็ต้องไปพัฒนาความสามารถในด้านนั้นของตน เช่น หมู่บ้านในป่าต้องพัฒนาความสามารถในการล่า จะล่ายังไงให้ได้เยอะ จะต้องพัฒนาเครื่องมือของตนให้ดีขึ้น การแลกเปลี่ยนอาจจะทำให้ค้นพบเทคโนโลยีใหม่ๆ เช่น หมู่บ้านติดทะเลอาจได้ความรู้ใหม่ว่ากระดูกของสัตว์จากป่าสามารถเอามาทำอุปกรณ์ได้ดีกว่าใช้หินใช้ไม้หรือก้างปลา กระดูกของสัตว์ในป่าสามารถทำเบ็ดได้ดีกว่า หรือ หมู่บ้านป่าได้รู้ว่าเกลือสามารถถนอมอาหารได้พวกเขาก็สามารถใช้เกลือหมักเนื้อของพวกเขากลายเป็นเนื้อเค็ม

จริงๆผลกระทบที่ตามมาจากการแลกเปลี่ยนมีมากกว่านี้แต่ผมอยากคุณไปอ่านจากหนังสือจะดีกว่าเพราะมันเยอะจริงๆแถมสนุกมากด้วย

อ่านแล้วได้อะไร

สำหรับผมหนังสือชุดนี้คือหนังสือที่ดีมาก ผมว่าเป็นหนังสือที่ควรหามาอ่านเพราะมันเป็นหนังสือที่ช่วยให้เราเข้าใจตัวเราเองที่เป็นมนุษย์ เข้าใจว่าทำไมฉันถึงรู้สึกแบบนั้นแบบนี้ ทำไมผู้ชายชอบมองส่วนเว้าส่วนโค้งของผู้หญิง ทำไมผู้ชายถึงชอบผู้หญิงที่ดูสาว ทำไมผู้หญิงถึงเลือกผู้ชายแล้วเลือกผู้ชายอีก ทำไมเราถึงฆ่าล้างเผ่าพันธุ์กันทั้งๆที่เราส่วนใหญ่นั้นเป็นคนมีน้ำใจช่วยเหลือกันอยู่บ่อยๆ จริยธรรมนั้นมีมาตั้งแต่มนุษย์เกิดหรือไม่ ซึ่งเมื่อเรารู้แล้วว่าทำไมเป็นอย่างนั้นเราก็สามารถหลีกเลี่ยงหรือหักห้ามใจ (ใช้คำว่าหาเหตุผลอื่นมาสนับสนุนให้ทำอีกอย่างแทนจะถูกกว่า) ไม่ทำในสิ่งนั้นได้

การอ่านหนังสือเล่มนี้เหมือนผมกลับไปอ่านหนังสือ “พวกฉัน พวกมัน พวกเรา” “วิทยาศาสตร์แห่งความสุข” “MISBEHAVING” แต่เป็นในมุมมองภาพรวมซึ่งมีการเชื่อมโยงส่วนต่างๆให้เราเห็นด้วย โดยส่วนตัวผมยกให้เป็นหนังสือที่ควรไปหามาอ่านเพราะมันจะทำให้คุณเข้าใจ ยอมรับ ความเป็นมนุษย์ของเรา และหาทางจัดการกับความเป็นมนุษย์ของเราครับ

Hedwig and The Angry Inch

Hedwig and The Angry Inch

ออกตัวก่อนเลยว่าผมไม่ใช่ผู้มีความรู้ความเชี่ยวชาญในด้านการแสดง การกำกับ ไม่ใช่ศิษย์เก่าของที่ไหน ผมเป็นแค่พนักงานบริษัทเอกชนย่านใจกลางเมืองที่ดันรู้ว่ามีการจัดแสดงละครเวทีซึ่งสามารถไปดูฟรีได้ (คุณอ่านไม่ผิดครับ มันฟรี และ ผมชอบดูของฟรี) ผมก็เลยไปดูละครเวทีเรื่องนี้แบบไม่รู้เรื่องย่อใดๆ ไม่รู้ทั้งผู้กำกับ นักแสดง ไปรู้กันเลยว่าเรื่องที่ดูมันเป็นยังไง ซึ่งหลายครั้งที่เจอเรื่องดีๆ หลายครั้งเหมือนกันที่เหมือนกูไปเสียเวลาไปดูอะไรก็ไม่รู้ ดังนั้นการวิจารณ์ หรือ Review แล้วแต่จะพูดเป็นสิ่งที่มาจากคนไม่รู้ศาสตร์และศิลป์ ซึ่งอาจจะเข้าไม่ถึงสิ่งที่เรียกว่าสุดยอดการแสดงดังนั้นถ้ามันไปขัดใจใครก็ขออภัย

ผมนอกเรื่องไปเยอะละเรามาพูดถึงละครเวทีเรื่องนี้กันดีกว่า ละครเรื่องนี้เราถึงคุณ Hedwig ซึ่งเป็นศิลปินระดับโลกมีวงของตัวเองและตอนนี้กำลัง World tour มาที่ประเทศไทยของเรา ซึ่งผู้ชมจะกลายเป็นคนที่มาชมการแสดงของคุณ Hedwig พร้อมกับรู้เรื่องราวในชีวิตของคุณ Hedwig ว่าเป็นมาอย่างไร

เพลงกับเนื้อเรื่อง

อย่างที่ผมบอกไปการดูละครเวทีเรื่องนี้คือการไปดูการแสดงคอนเสิร์ตของคุณ Hedwig ซึ่งแน่นอนว่ามันจะมีเล่นเพลงซึ่งละครเวทีเรื่องนี้ใช้การเล่าประวัติของคุณ Hedwig ว่าเขาคือใคร ผ่านอะไรมาบ้างในชีวิต ซึ่งแต่พอเล่าถึงแต่ละเหตุการณ์จบก็จะมีเพลงที่ตรงกับเหตุการณ์ตอนนั้นมาให้เราได้ฟัง ซึ่งแต่ละเพลงก็มีเนื้อหาที่ดีถ่ายทอดให้เราเข้าใจความรู้สึกของคุณ Hedwig มากขึ้นซึ่งถือว่าทำได้ดีมากๆ

บท

สำหรับผมบทเรื่องนี้ดูไม่มีอะไรมาก ไม่ได้ทำให้น่าติดตามอยากรู้ทุกวินาที ทั้งหมดคือการเล่าเรื่องชีวิตของคุณ Hedwig นั่นแหละว่าเขาคือใคร ผ่านอะไรมา อาจจะมีน่าสนใจนิดหน่อยก็ตรงปมที่คุณ Hedwig เกี่ยวอะไรกับคุณ Tommy และการใช้เรื่องทฤษฎีความรักของเพลโตที่บอกว่ามนุษย์ในอดีตมี 2 คนในหนึ่งร่างซึ่งอาจจะเป็นชายชาย หญิงหญิง ชายหญิง แต่ถูกพระเจ้าจับแยกออกจากกันเพราะเกรงกลัวความสามารถของมนุษย์ ซึ่งนั่นทำให้มนุษย์โหยหาอีกครึ่งเพื่อมาเติมเต็มซึ่งนั่นสามารถอธิบายได้ว่าทำไมคนบางคนถึงชอบเพศเดียวกัน (ดูเป็นทางออกที่ดีในการอธิบาย) ซึ่งจากการใช้ทฤษฎีนี้อธิบายทำให้เราเข้าใจคุณ Hedwig ว่าทำไมเขาถึงฝังใจกับคุณ Tommy ขนาดนั้น

การแสดง

สิ่งที่ทำให้ผมคิดว่าเรื่องนี้มีคุณค่าคุ้มกับเวลาที่เสียไปคงจะเป็นการแสดงของนักแสดง นักแสดงที่เล่นเป็นคุณ Hedwig นี่เขาเล่นได้สุดยอดจริงๆแบบที่เราดูแล้วเชื่อว่าเขาเป็นคุณ Hedwig จริงๆไม่ได้กำลังแสดง ส่งอารมณ์สุขเศร้าตลกมาให้เราได้อย่างเต็มที่ (ผมเคยเห็นนักแสดงคนนี้เล่นเรื่องอื่นมาแล้ว (ถ้าจำไม่ผิด แต่คงไม่ผิดหรอก) เรื่องแวมไพร์อะไรสักอย่าง แต่เรื่องนั้นไม่น่าประทับใจเท่าไหร่ อาจจะเพราะบทไม่ได้ส่งให้เขาเล่นได้เต็มที่เหมือนเรื่องนี้) แถมเขามีการเล่นนอกบทที่เล่นได้ดีรู้ว่าควรเล่นตอนไหน เล่นกับใคร บริบทไหนที่ควรเล่น (ปกติถ้าเจอคนเล่นนอกบทที่ไม่เก่งมาก เล่นแล้วคนจะไม่เข้าใจ เงียบ หรือไปต่อไม่ได้ )

สรุป

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

วิทยาศาสตร์แห่งความสุข - สำรวจความสุขและความหมายของชีวิตด้วยวิทยาศาสตร์

วิทยาศาสตร์แห่งความสุข - สำรวจความสุขและความหมายของชีวิตด้วยวิทยาศาสตร์

วิทยาศาสตร์แห่งความสุข - สำรวจความสุขและความหมายของชีวิตด้วยวิทยาศาสตร์

หลังจากอ่านหนังสือพวกพัฒนาตัวเองมาได้สักพักหนึ่งผมเริ่มรู้สึกว่าหนังสือพวกนี้มันพยายามทำให้เราทำอะไรทีเยอะแยะเหนือคน หรือหาวิธีสุดยอดต่างๆนาๆ บางเล่มก็แบบจับใจคนใน 15 นาที เปลี่ยนเป็นยอดคนด้วยการทำแบบนั้นแบบนี้ ซึ่งมันก็ดีครับแต่มันไม่ถูกจริตของผมและผมรู้ว่าวิธีของเขาใช้กับตัวผมไม่ได้ (เพราะผมลองแล้ว)

คำถามที่น่าสนใจคือผมพยายามทำตามหนังสือพวกนั้นไปเพื่ออะไร ถ้าตอบแบบหมาๆเลยก็คืออยากให้ตัวเองเก่งมีหน้าที่การงานที่ดีเพื่อให้ได้เงินเดือนที่เยอะขึ้นแล้วจากนั้นก็เอาเงินเดือนมาใช้จ่ายกับบางสิ่งที่ตัวเองพอใจ ซึ่งความพอใจนั้นอาจจะเรียกว่า “ความสุข” ก็ได้ ดังนั้นแทนที่ผมจะมุ่งหาวิธีเพิ่มเงินเดือนเพื่อสร้าง “ความสุข” (ที่เกิดจากความพอใจ) สู้ผมไปศึกษาว่า “ความสุข” คืออะไรน่าจะดีกว่า

ถ้าคุณไปหาหนังสือเกี่ยวกับความสุขผมรับรองเลยว่าน่าจะมีเป็นร้อยเล่ม อาจจะเกี่ยวกับศาสนา ความเชื่อ วิธีปฏิบัติตัว การมองโลกให้มีความสุข ซึ่งผมก็อ่านมาหลายเล่มทั้งแบบที่พูดถึงความสุขโดยตรง หรือนิยายปรัชญาที่พูดถึงความสุขในแง่มุมต่างๆของตัวละคร แต่ส่วนใหญ่มันก็ดูจะตอบแบบครอบจักรวาลหรือออกแนวเพ้อเจ้อไปเลย (คุณอาจไม่พอใจผมแต่แน่นอนครับ “เรื่องของคุณ” ) จนได้มาเจอหนังสือ วิทยาศาสตร์แห่งความสุข - สำรวจความสุขและความหมายของชีวิตด้วยวิทยาศาสตร์ ที่อธิบายความสุขจากมุมมองทางวิทยาศาสตร์ทั้งในด้านการแพทย์ ทางจิตวิทยาที่ใช้การทดลองกับกลุ่มทดลอง อีกทั้งหนังสือยังรวบรวมแนวคิดเกี่ยวกับความสุขของอารยธรรมยิ่งใหญ่บนโลกทั้งฝั่งตะวันออกและตะวันตก ซึ่งบอกเลยถ้าคุณอ่านหนังสือเล่มนี้แล้วคุณจะเข้าใจความสุขในหลายๆแง่มุม

คนรวย ผู้มั่งคั่ง ทำไมยังมีความทุกข์

คุณคงได้ยินเรื่องเล่าของคนมั่งมีรวยล้นฟ้าแต่ชีวิตยังทุกข์ไหมครับ ผมเชื่อว่าคุณคงเคยได้ยิน ถ้าคุณเป็นคนนับถือศาสนาพุทธหรือเรียนโรงเรียนพุทธที่ใส่วิชาพระพุทธศาสนาในหลักสูตรคุณคงรู้จัก “เจ้าชายสิทธัตถะ” ที่มีทรัพย์สินเงินทอง ข้าทาสบริวาร แต่เขาก็ยังรู้สึกทุกข์จนสุดท้ายต้องออกบวชหาทางพ้นทุกข์ ซึ่งหลายคนก็จะพูดว่า “ถ้ากูรวยแบบนั้น กูไม่ออกบวชแม่งหรอก กูจะอยู่แบบนั้นใช้ชีวิตสบายไปจนตายเลย” หรือ ถ้ามองให้ใกล้ตัวขึ้นมาหน่อย หากคุณเป็นคนชั้นกลางที่มีเงินเดือนมากกว่าค่าแรงขั้นต่ำ คุณมีเงินเหลือจากค่าใช้จ่ายในชีวิตประจำวัน มีเงินเก็บ มีประกันสุขภาพ ถ้ามองแบบพื้นๆไม่ลงรายละเอียดคุณควรจะมีความสุข (กินอิ่ม นอนหลับ ไม่ต้องดิ้นรน) แต่ถ้าลองถามตัวเองดีๆคุณจะรู้สึกว่างเปล่า ชีวิตมันขาดอะไร น่าเบื่อ ไม่มี “ความสุข” เลย จนมันทำให้คุณขวนขวายหาสิ่งใหม่เข้ามาในชีวิต ไม่ว่าจะเป็นต้องมีบ้าน มีรถ มีเครื่องใช้ของใช้ใหม่ๆ ถ้ามีอยู่แล้วก็ต้องหาที่ดีกว่า ตำแหน่งงานที่มีอยู่แล้วยังไม่มากพอ ต้องมีมากกว่านี้

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

ความสุขหาได้เสมอเพราะเราปรับตัว

ผมขึ้นหัวข้อแบบนี้คงจะมีคนเริ่มหมันไส้บอกว่า “มึงลองมาเป็นคนจนสิไอ้เวร” ไม่ก็ “มึงกำลังทำให้ความจนเป็นเรื่องโรแมนติกสินะไอ้เวร” จริงๆผมว่าหลายๆคนที่ศึกษาเกี่ยวกับความสุขน่าจะโดนคำถามแบบนี้ ซึ่งบางคนรวมถึงผมก็คงจะด่ากลับว่า “เหี้ยไรมึง กูไปบอกตอนไหนวะ” แล้วก็เริ่มวิวาทะไร้สาระและประโยชน์กันตอ่ไป แต่นักวิทยาศาสตร์หลายคนไม่เสียเวลากับเรื่องไร้สาระพวกนั้นครับ เพราะเขาคงแยกออกระหว่าง “คุณภาพชีวิต” กับ “ความสุข” และเขากำลังศึกษาความสุขไม่ได้กำลังจะทำให้คนทั้งโลกคิดว่าเป็นคนจนแล้วมีความสุข เป้าหมายของเขากำลังค้นหาว่าความสุขเกิดได้กับคนที่ดูจะไม่มีความสุขเลยได้ไหม

การศึกษาของนักวิทยาศาสตร์เหล่านั้นคือไปตรวจสอบคนปกติที่เกิดอุบ้ติเหตุแล้วทำให้เขาต้องกลายเป็นอัมพาตทั้งตัวว่าเขาจะยังสามารถมีความสุขได้หรือไม่ ซึ่งถ้าผมและคุณได้ยินแค่นี้ก็คงจะรู้สึกว่ามันจะไปมีความสุขหลังจากอัมพาตได้ยังไงมันจะต้องทุกข์ทรมานไปจนวันตายแน่นอน แต่จากการศึกษาพบว่ามันมีจริงๆครับช่วงทุกข์ทรมานจนอยากตาย แต่เมื่อเวลาผ่านไปคนเหล่านั้นจะเริ่มกลับมามีความสุขได้ โดยมีความสุขผ่านสิ่งที่พวกเขาพอที่จะทำได้ เช่น การดูทีวี ได้ฟังเสียงจากคนที่อ่านหนังสือให้ฟัง เป็นต้น ซึ่งมันน่าจะเหนือจากที่คุณและผมคิดใช่ไหมครับ

การศึกษาที่แล้วเจาะจงไปหาคนที่อยู่ดีๆก็ทุกข์แบบแสนสาหัสว่าจะสามารถมีความสุขได้ไหม ทีนี้มาถึงการศึกษาคนที่น่าจะทุกข์อยู่ตลอดเวลาว่าเขาสามารถมีความสุขได้หรือไม่ โดยเขาทำการศึกษาคนที่ทำอาชีพขายบริการ (ในบางประเทศคนขายบริการมีคุณภาพชีวิตไม่ค่อยดีเท่าไหร่) ซึ่งก่อนอ่านผมคิดว่าเขาคงทุกข์ทรมานต้องมาทำงานอะไรพวกนี้ เงินที่ได้ก็น้อยนิด มีปัญหาเรื่องการตีค่าเกี่ยวกับคุณค่าของชีวิต เขาคงจะต้องทุกข์ทรมานไม่มีวันความสุขได้แน่ แต่จากการศึกษาพบว่าคนเหล่านั้นสามารถมีความสุขได้ซึ่งก็ไม่ต่างจากการศึกษาที่แล้วคือเขามีความสุขจากสิ่งที่พวกเขาพอจะมีได้คือ การคุยกับเพื่อน คนรู้จัก

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

จากหลายๆการศึกษามันคงบอกคุณได้อย่างหนึ่งว่าคนเราสามารถหาความสุขให้ตัวเองได้เสมอดูได้จากทั้งคนที่กลายเป็นอัมพาตหรือคนที่มีอาชีพที่ไม่น่าจะหาความสุขได้ ดังนั้นถ้ามีใครสักคนพูดว่าความสุขสามารถหาได้เสมอเขาไม่ได้พูดเกินจริงนะครับ เช่นกัน ต่อให้คุณรวยล้นฟ้าล้นแผ่นดินคุณก็อาจจะไม่ได้มีความสุขมากขึ้นกว่าเดิมสักเท่าไหร่ครับ ทั้งหมดทั้งมวลนั้นเกิดจากการที่คนเรามีการปรับตัวให้เข้าสภาพปัจจุบัน

ทำเลยมีความสุขแน่นอน

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

  1. ลดระยะเวลาการเดินทาง จากการสำรวจพบว่าคนจำนวนมากไม่มีความสุขกับการเดินทางไกลซึ่งส่วนใหญ่จะเป็นการเดินทางไปทำงาน ซึ่งก็น่าจะเป็นเรื่องที่ทุกคนเจอกัน ไม่ว่าจะเป็นสภาพรถติด เพื่อนร่วมถนนชั้นเลว ดังนั้นหากคุณลดระยะเวลาการเดินทางลดได้คุณก็จะทุกข์กับเรื่องเหล่านี้น้อยลงมาก

  2. ที่พักไม่อยู่ในที่เสียงดัง จากการสำรวจพบว่าคนจำนวนหนึ่งทุกข์กับการอาศัยอยู่ในที่เสียงดังเพราะทำให้มีปัญหาเกี่ยวกับการนอนและสูญเสียสมาธิ ซึ่งเรื่องนี้เราก็เข้าใจได้เลยเพราะถ้าคุณมีบ้านอยู่ใกล้ผับหรือสถานที่ก่อสร้างคุณคงรำคาญเสียงรบกวนซึ่งมันแทบจะดังตลอดเวลาที่มีกิจกรรม

  3. จัดการรูปร่างของคุณให้ตรงตามความต้องการของคุณ เรื่องนี้ในหนังสืออธิบายว่าเรื่องนี้เป็นเรื่องความมั่นใจของคนนั้น เขายกตัวอย่างเพศหญิงที่มีปัญหาหน้าอกใหญ่ หรือ เล็กจนเกินไปทำให้ตัวเองขาดความมั่นใจ ไม่ค่อยรู้สึกมีความสุข แต่หลังจากพวกเธอเข้ารับการผ่าตัดให้หน้าอกมีขนาดตามที่ตัวเองต้องการแล้วพบว่าผู้หญิงเหล่านั้นมีความสุขมากขึ้นซึ่งนั่นมาจากการที่เธอมีความมั่นใจ

อ่านแล้วได้อะไร

จริงๆหนังสือเล่มนี้ยังมีอีกหลายเรื่องที่น่าสนใจไม่ว่าจะเป็นเรื่อง ช้างและควาญช้าง (ถ้าเข้าใจตรงนี้คุณจะเห็นภาพใหม่เกี่ยวกับความสุข) ทนายของตัวเอง กระจกสีกุหลาบ การตัดสินคนอื่น ที่มาของความสุข การถูกล็อตเตอร์รี่ความสุข สมการของความสุข (อันนี้มีสูตรจริงจัง) ซึ่งน่าสนใจมากกว่าที่ผมเขียนเล่าไปด้านบน (ก็ถ้าผมเล่าส่วนที่น่าสนใจสุดคุณก็ไม่ไปหามาอ่านน่ะสิ) ซึ่งผมรับรองเลยว่าอ่านแล้วคุ้มค่ากับเวลามากๆ มันจะทำให้คุณเข้าใจความสุขมากขึ้นซึ่งเมื่อคุณเข้าใจแล้วคุณก็สามารถนำมันมาปรับใช้กับชีวิตของคุณได้ ซึ่งมันดีกว่าการคุณไปอ่านหนังสือ How to ต่างๆนาๆแล้วเอามาทำตามเพื่อให้ได้ดั่งใจโดยไม่รู้ว่าเป้าหมายที่อยากทำนั้นคืออะไร

นายพลกับคืนหายนะ - An unpleasant predicament

นายพลกับคืนหายนะ - An unpleasant predicament

นายพลกับคืนหายนะ - An unpleasant predicament

หนังสือเล่มนี้เป็นหนังสือที่รวมเรื่องสั้นของ Fyodor Dostoevsky ซึ่งเขาคือนักเขียนชื่อดังของรัสเซีย ผมเคยอ่านงานเขียนของเขาที่ชื่อ “พี่น้องคารามาซอฟ” แล้วรู้สึกประทับใจในวิธีการเขียนและการสร้างตัวละครของเขา เนื้อเรื่องก็แหวกแนวไม่เหมือนตลาด แม้แต่ผมที่เป็นคนในยุคปัจจุบันได้อ่านก็รู้สึกว่ามันแหวกแนวดี ดังนั้นผมจึงไม่พลาดจะเอาหนังสือเล่มนี้มาอ่าน

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

นิยายในจดหมายเก้าฉบับ

หากคนรู้จักนิยาย Chat ที่อ่านเป็นบรรทัดบรรทัดโต้ตอบไปมาและให้เราไปทำความเข้าใจว่าเกิดอะไรขึ้นผ่านการ Chat ของตัวละครสองคนนั้น นิยายในจดหมายเก้าฉบับนี้ก็น่าจะคล้ายคลึงกันเพียงแต่เปลี่ยนจากการ Chat มาเป็นจดหมายที่ส่งไปมาระหว่างกัน ซึ่งแน่นอนว่ามันไม่ใช่การโต้ตอบแบบทันทีทันใด เราไม่สามารถรู้ได้เลยว่าฝั่งเขียนจดหมายเจออะไร ฝั่งรับกำลังทำอะไรอยู่ระหว่างฝั่งเขียนกำลังส่ง ดังนั้นการเราจะได้สนุกไปกับการอ่านจดหมายของแต่ล่ะฝั่ง แล้วสงสัยว่ามันเกิดอะไรขึ้นแล้วระหว่างสองฝั่ง และแต่ละฝั่งจะโต้ตอบอย่างไร โดยในเรื่องนี้จะเป็นการส่งจดหมายคุยกันระหว่างเพื่อนสองคนที่ทำธุรกิจร่วมกันที่ต้องการนัดเจอกันแต่คุยเกี่ยวกับปัญหาบางอย่าง โดยฝั่งหนึ่งส่งจดหมายไปนัดพบกับอีกฝั่ง แต่ดูเหมือนจะมีอะไรบางอย่างทำให้เขาทั้งสองต้องส่งจดหมายคุยกันแทนที่จะได้นัดเจอกัน ซึ่งจดหมายที่ส่งไปส่งกลับระหว่างสองคนจะค่อยๆเปิดเผยเรื่องราวๆต่างๆระหว่างเพื่อนสองคนนี้ และนำพาไปสู่จุดจบที่น่าประหลาดใจ

นายพลกับคืนหายนะ

คุณเคยมีภาพในหัวประมาณว่า ฉันจะไปพูดนำเสนองานแล้วการพูดของคุณจะทำให้ทุกคนเข้าใจ ฉันจะสอนให้เด็กคนนี้เป็นเด็กฉลาดทำให้ชาติเจริญ ฉันสามารถทำได้แน่นอนเพราะฉันมีความรู้ความสามารถ หรือ คุณภาพที่คุณจะทำบางสิ่งบางอย่างให้ดีขึ้นด้วยความรู้ความสามารถของคุณ เรื่อง “นายพลกับคืนหายนะ” คือนิยายที่ว่าด้วยการที่นายพลคนหนึ่งมีภาพในหัวว่าตนนั้นจะทำอะไรให้ดีขึ้นได้บ้าง ซึ่งเขาคิดว่าเขาทำได้แน่เพราะเขาเป็นถึงนายพลของรัสเซียเลยทีเดียว มีอะไรที่เขาจะทำไม่ได้ล่ะ ดังนั้นเขาจึงพยายามที่จะทำให้ภาพนั้นเกิดขึ้นจริง แต่ภาพนั้นจะเกิดขึ้นจริงหรือไม่ ลองไปหาอ่านดูครับรับรองว่าคุณจะอาจจะเข้าใจโลกนี้มากขึ้นผ่านเรื่องสั้นเรื่องนี้ก็ได้

อ่านแล้วได้อะไร

สำหรับผมเล่มนี้อ่านแล้วได้ความสนุกไปกับเนื้อเรื่องที่มีความบ้าบอและตลกร้าย ในเรื่องมีการเสียดสีสภาพสังคมของรัสเซียในยุคนั้นซึ่งผู้เขียนทำได้ดีคือแผงมาให้คิดไม่ได้ยัดเยียดว่าต้องเชื่อแต่ทำให้เห็นภาพและเข้าใจจากในตัวเนื้อเรื่อง ดังนั้นหากใครต้องการอ่านเรื่องสั้นเนื้อเรื่องไม่หนักมากแต่อ่านแล้วได้เรื่องไปให้คิด ผมก็แนะนำหนังสือเล่มนี้

Basic Database System Part 5 - Normalization Process 4NF , 5NF

Basic Database System Part 5 - Normalization Process 4NF , 5NF

ในตอนที่แล้วเราได้ทำ Normalization Process ไปถึงขั้น BCNF ซึ่งจากตัวอย่างที่เราได้ลองทำกันนั้นมันไม่มีปัญหา INSERT , DELETE , UPDATE ซึ่งนั่นทำให้เกิดความเข้าใจผิดๆว่าทำ Normalization Process ถึงขั้น BCNF ก็พอ ในตอนนี้เราจะมาดูว่า Table ที่เป็น BCNF ก็ยังเกิดปัญหา INSERT , DELETE , UPDATE ได้ จากนั้นเราจะมาทำ Normalization Process กันต่อจนถึงขั้น 5NF

Table : Course Teacher Text (CTX)

Course Teacher Text

นี่เป็นรายละเอียดเกี่ยวของ Course เรียนที่บอกว่าจะสอนวิชาอะไร ใครเป็นอาจารย์ และต้องใช้หนังสืออะไรบ้าง ซึ่งจากตัวอย่างเราจะเห็นว่า Course : Database มีอาจารย์สอน 2 คนคือ John , Smith ใช้หนังสือสำหรับสอนวิชานี้ 2 เล่มคือ Set theory , DBMS Technology ส่วน Course : Math มีอาจารย์สอน 1 คนคือ John ใช้หนังสือสำหรับสอนวิชานี้ 3 เล่มคือ Set theory , Algebra , Calculus

ถ้าเราอยากเก็บข้อมูลนี้ให้อยู่ใน Relational Database Model เราสามารถทำได้โดยใช้ Normalization Process ที่เราเรียนไปในตอนที่แล้ว ซึ่ง Table ที่ได้ออกมาจะมีหน้าตาแบบนี้

Table : Course Teacher Text (CTX) ที่เป็น BCNF

รายละเอียดของ Table

  1. Primary key : { COURSE , TEACHER , TEXT }
  2. Candidate key : { COURSE , TEACHER , TEXT }
  3. Nonkey attribute : ไม่มี
  4. FD ไม่มี

ตรวจสอบว่าเป็น BCNF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และแต่ละ Column มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น

Table เป็น BCNF แต่ปัญหา INSERT , DELETE , UPDATE

คุณจะเห็นว่า Table : Course Teacher Text (CTX) นั้นเป็น BCNF แล้ว ซึ่งถ้าคุณเชื่อตามความเชื่อผิดๆที่บอกไปตอนต้นว่า Table ที่เป็น BCNF (บางคนบอก 3NF) แล้วจะไม่มีปัญหาเรื่องการ INSERT , DELETE , UPDATE เรามาลองพิสูจน์กันครับว่าจริงไหม

ปัญหา Insert ข้อมูลเข้าไปไม่ได้

ถ้าผมต้องการอยากเพิ่ม COURSE : PROGRAMMING เข้าไปโดยวิชานี้ใช้ TEXT : BASIC C, C++ , JAVA Programming เข้าไป เราจะได้ข้อมูลที่จะ INSERT เป็น

ข้อมูลที่ต้องการ INSERT ลง TABLE : CTX

ซึ่งจะเห็นว่าเราไม่สามารถ INSERT ข้อมูลได้เพราะติดกฎเรื่อง Primary key must not be null

ปัญหา Delete

ถ้าสมมุติผมต้องการลบข้อมูล TEACHER : John ออกไป คุณจะเห็นว่าถ้าลบข้อมูล John ออกไป ข้อมูลของ TEXT ที่เกี่ยวกับ COURSE : Math ทั้งหมดจะหายไปด้วย ซึ่งนั่นไม่ใช่สิ่งที่เราต้องการ

ข้อมูลที่ต้องการ DELETE

ยังมีปัญหาอยู่

คุณจะเห็นแล้วว่าแม้ Table จะเป็น BCNF แต่มันก็ยังเกิดปัญหา INSERT , UPDATE , DELETE อยู่ ดังนั้นถ้าใครบอกว่า Normalization Process ทำแค่ BCNF (3NF) ก็พอ ผมแนะนำให้เอา Table : Course Teacher Text (CTX) ให้เขาดูครับ เขาจะได้เข้าใจว่ามันไม่ใช่อย่างที่เขาคิด

ความสัมพันธ์ระหว่าง Column (Attriubte) ของ Table : CTX

ใน Table : CTX นั้นไม่มีความสัมพันธ์แบบ FD เลย แต่ถ้าคุณดูความสัมพันธ์ตามงานจริงคุณจะรู้ว่าตัว COURSE นั้นจะเป็นตัวบอกว่ามี TEACHER คนไหนบ้างที่สอนวิชานี้ และ COURSE นั้นเป็นตัวบอกว่ามี TEXT เล่มไหนถูกใช้ในการสอนบ้าง และ TEXT กับ TEACHER นั้นไม่ได้มีความเกี่ยวข้องกันเลย (TEACHER ไม่ได้เป็นตัวบอกว่าใช้ TEXT เล่มไหน และ TEXT ก็ไม่บอกว่า TEACHER คนไหนต้องใช้ ) เราจะเรียกความสัมพันธ์ใน Table นี้ว่า Multivalued dependence ( MVD )

Multivalued dependence ( MVD )

Given a relational table structure T , With attributes X , Y and Z , the multivalued dependence (MVD) T.X ->-> T.Y holds in T if and only if the set of Z-values matching a given (X-value, Y-value) pair in T depends only on the X-Value and is independent of the Y-value. As usual , X, Y and Z may be composite.
Note that MVDs as defined can exist only if the relational table structure T has at least three attributes.

ผมแนะนำให้อ่านนิยามภาษาอังกฤษนะครับ สำหรับภาษาไทยที่ผมจะแปลผมไม่รู้จะแปลยังไงให้ถูกดี ลองอ่านดูละกันครับ

กำหนดให้ Table T มี Column (Attribute) X , Y และ Z โดย Multivalued dependence (MVD) T.X ->-> T.Y จะอยู่ใน Table T ก็ต่อเมื่อ มี Set ของค่าใน Column Z ตรงกับคู่ของค่า ( X-value , Y-value ) โดยค่า Z นั้นจะขึ้นอยู่กับ X เท่านั้น และค่า Z เป็นอิสระต่อ Y โดยปกติแล้ว X Y และ Y นั้นจะอยู่ด้วยกัน ดังนั้น MVD จะเกิดขึ้นได้ก็ต่อเมื่อ Table นั้นมีอย่างน้อย 3 Attribute

อ่านแล้วอาจจะงงเรามาดูตัวอย่างของ Table : CTX

Table : CTX มี 3 Column (Attribute) คือ COURSE , TEACHER , TEXT

  1. MVD COURSE ->-> TEACHER

    X คือ COURSE , Y คือ TEACHER , Z คือ TEXT

    ตรงนี้เราพอเห็นแล้วว่า COURSE ->-> TEACHER น่าจะเป็น MVD เพราะค่า COURSE นั้นกำหนดกลุ่มของค่า TEACHER แต่เราต้องตรวจสอบด้วยนิยามคือดูค่า TEXT ว่าตรงตามเงื่อนไขไหม

    ตรวจสอบทีละเงื่อนไขว่าเป็น MVD หรือไม่

    • Z ขึ้นอยู่กับ X เท่านั้น ดูได้จากค่า Text = { Set theory , DBMS Technology } เมื่อ Course = Database และ Text = { Set theory , Algebra , Calculus } เมื่อ Course = Math

    • Z เป็นอิสระจาก Y ดูได้จาก TEXT สามารถเปลี่ยนค่าได้โดยไม่เกี่ยวข้องกับ TEACHER เลย

    • Z (Text) = { Set theory , DBMS Technology } นั้นสามารถ Map ได้กับคู่ของ COURSE , TEACHER ซึ่งก็คือ {Database , John} , { Database , Smith } ได้

      MVD COURSE ->-> TEACHER

  1. MVD COURSE ->-> TEXT

    X คือ COURSE , Y คือ TEXT , Z คือ TEACHER

    ตรวจสอบทีละเงื่อนไขว่าเป็น MVD หรือไม่

    • Z ขึ้นอยู่ X เท่านั้น ดูได้จากค่า TEACHER = { John , Smith } เมื่อ Course = Database และ TEACHER = { John } เมื่อ Course = Math

    • Z เป็นอิสระจาก Y ดูได้จาก TEACHER สามารถเปลี่ยนค่าได้โดยไม่เกี่ยวกับ TEXT เลย

    • TEACHER = { John , smith } นั้นสามารถ Map ได้กับคู่ของค่า COURSE , TEXT ซึ่งก็คือ { Database , Set theory } , { Database , DBMS Technology }

      MVD COURSE ->-> TEXT

ข้อสังเกตเกี่ยวกับ MVD

  • เวลาเกิด MVD นั้นจะเกิดเป็นคู่อย่างในตัวอย่างเมื่อเกิด MVD COURSE ->-> TEACHER ก็จะเกิด MVD COURSE ->-> TEXT เกิดขึ้นเสมอ ดังนั้นเขาจะเขียน MVD เป็น MVD COURSE ->-> TEACHER | TEXT

  • ความสัมพันธ์แบบ MVD นั้นเป็นความสัมพันธ์แบบ 1 to Many ตัวอย่างเช่น MVD COURSE ->-> TEXT นั้นค่า COURSE หนึ่งค่าสามารถกำหนดว่าค่า TEXT สามารถมีค่าเป็นอะไรได้หลายค่า เช่น ถ้า COURSE = Database ค่า TEXT ที่สามารถเป็นได้คือ { Set theory , DBMS Technology } คราวนี้ถ้าเราเกิดสมมุติว่าความสัมพันธ์แบบ MVD X ->-> Y แล้ว Set ของ Y มีค่า 1 ค่า มันก็จะกลายเป็น 1 to 1 ซึ่งนั่นก็หมายความว่ามันคือความสัมพันธ์แบบ FD ดังนั้นความสัมพันธ์แบบ FD ซึ่งเป็นกรณีพิเศษของ MVD

4NF

A relational table structure T is in th fourth normal form (4NF) if it is in BCNF and all MVDs in T are FDs Only.

ผมแนะนำให้อ่านนิยามภาษาอังกฤษเพราะเป็นนิยามที่ถูกต้องครับ แต่ถ้าไม่เข้าใจลองอ่านที่ผมแปล

Table จะเป็น 4NF เมื่อ Table นั้นเป็น BCNF และ MVD ทั้งหมดใน Table ต้องเป็น FD

ตรวจสอบ Table : CTX

MVD ของ Table : CTX

  • MVD COURSE ->-> TEACHER
  • MVD COURSE ->-> TEXT

Table นี้ไม่เป็น 4NF เพราะ MVD ไม่ได้เป็น FD ดูได้จากเพราะค่า COURSE –>–> TEACHER เป็น 1 to many ดังนั้น MVD นี้ไม่ได้เป็น FD

วิธีแก้ไข

ให้ทำการแยกความสัมพันธ์ MVD ออกไปเป็น Table ใหม่ Table : CTX มี 2 MVD ก็จะได้เป็น 2 Table คือ Table : Course Teacher (CT) กับ Table : Course Text (CX)

Table : Course Teacher (CT)

Table : Course Teacher (CT)

รายละเอียดของ Table

  1. Primary key : { COURSE , TEACHER }
  2. Candidate key : { COURSE , TEACHER }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี
  5. MVD : ไม่มี

ตรวจสอบว่าอยู่ใน 4NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม

Table : Course Text (CX)

Table : Course Text (CX)

รายละเอียดของ Table

  1. Primary key : { COURSE , TEXT }
  2. Candidate key : { COURSE , TEXT }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี
  5. MVD : ไม่มี

ตรวจสอบว่าอยู่ใน 4NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม

ตรวจสอบปัญหา Insert Update Delete

ปัญหา Insert ข้อมูลเข้าไปไม่ได้

ถ้าผมต้องการอยากเพิ่ม COURSE : PROGRAMMING เข้าไปโดยวิชานี้ใช้ TEXT : BASIC C, C++ , JAVA Programming เข้าไป เราจะได้ข้อมูลที่จะ INSERT เข้า Table : Course Text (CX) ได้เลย

INSERT ข้อมูลลง TABLE : CX

ซึ่งจะไม่ติดปัญหา Primary Must not be null

ปัญหา Delete

ถ้าสมมุติผมต้องการลบข้อมูล TEACHER : John ออกไป เราก็สามารถลบข้อมูลออกจาก Table : Course Teacher (CT) ได้เลยซึ่งข้อมูลเกี่ยวกับ Text จะไม่หายไปเหมือนกรณีที่แล้ว

DELETE ข้อมูล TABLE : CT

Table : Vendor Item Project (VIJ)

Table : Vendor Item Project (VIJ)

Table : Vendor Item Project (VIJ) Table นี้นั้นทำการเก็บข้อมูลว่า Vendor ไหน ส่ง Item อะไร ให้ Project ไหน ดูแล้วมันก็เหมือน Table ทั่วไปใช่ไหมครับ โดยตัว Table นี้เก็บข้อมูลเกี่ยวกับ Vendor ไหนมี Item อะไร Item อะไรถูกใช้กับ Project ไหน และ Project ไหนใช้งาน VENDOR เจ้าไหน ฟังแล้วมันก็เก็บข้อมูลทั่วๆไปใช่ไหมครับแต่ Table นี้มีความพิเศษครับ เรามาลองดูกันครับ

รายละเอียดของ Table

  1. Primary key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  2. Candidate key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าอยู่ใน 4NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม

Table เป็น 4NF แต่ยังมีปัญหา INSERT , DELETE , UPDATE

คุณอ่านไม่ผิดครับ Table นี้เป็น 4NF และยังมีปัญหา ปัญหา INSERT , DELETE , UPDATE อยู่ครับ (ใครบอก 3NF ไม่มีปัญหา นี่ 4NF แล้วยังมีปัญหาเลย) ลองมาดูปัญหากัน

ปัญหา Insert ข้อมูลไม่ได้

ถ้าผมอยาก Insert ข้อมูลว่า VENDOR : V2 ว่ามี ITEM : I2 ขาย เราจะทำการ INSERT ข้อมูลเข้าไปดังภาพ ซึ่งจะไม่สามารถทำได้เพราะติด Primary must not be null

ข้อมูลที่ต้องการ INSERT ลง TABLE : VIJ

ปัญหา Delete ข้อมูล

ถ้าผมอยากลบข้อมูลที่ VENDOR : V1 ขาย ITEM : I2 ซึ่งถ้าผมลบข้อมูลนี้ไปแล้ว ข้อมูลที่ว่า ITEM : I2 นั้นถูกใช้ใน PROJECT : 1 นั้นจะถูกลบไปด้วยครับ

5NF

A relational table structure T is in projection-join normal form (PJ/NF) or the fifth normal form (5NF) if and only if every join dependency in T is implied by the candidate keys of T.

แนะนำให้อ่านนิยามภาษาอังกฤษครับ หากอ่านไม่เข้าใจจริงๆค่อยมาอ่านที่ผลแปลไทย

Table จะเป็น 5NF ก็ต่อเมื่อทุก Join dependency ใน Table จะต้องมี candidate key ของ Table นั้น

ผมว่าอ่านแล้วน่าจะไม่เข้าใจเพราะติดศัพท์ Join dependency ดังนั้นเรามาทำความเข้าใจ Join dependency คืออะไร

Join dependency

เราทราบแล้วว่าตัว Table : CTX นั้นสามารถถูกแยกออกมาเป็น Table : CT , Table : CX ซึ่งการแยก Table ได้หรือไม่นั้นมาจากการแยก Table แล้วสามารถ Join กลับมาเป็นข้อมูลเดิมได้ ดังตัวอย่าง CTX ด้านล่างที่สามารถแยกและ Join กลับได้ข้อมูลดังเดิม

ตัวอย่างการแยก Table ที่สามารถ Join กลับได้

แต่ถ้าเราเปลี่ยนการแยก Table เป็น Table : CT กับ Table : TX นั้นจะไม่สามารถ JOIN กลับได้เหมือนเดิม

ตัวอย่างการแยก Table แล้วไม่สามารถ Join กลับได้

ดังนั้น Table : CTX นั้นมี Join dependency กับการแยก Table ด้วย ( COURSE , TEXT ) , (COURSE , TEACHER ) แต่ไม่มี Join dependency กับ ( COURSE , TEACHER ) ( TEACHER , TEXT )

โดยเวลาเราเขียนความสัมพันธ์แบบ Join dependency จะเขียนอยู่ในรูป

R(A,B,C) มีความสัมพันธ์แบบ JD * (AB , AC)

โดยถ้าจากตัวอย่างของเราจะเขียนอยู่ในรูป

CTX(COURSE , TEACHER , TEXT) มีความสัมพันธ์แบบ JD * ( (COURSE , TEACHER) , (COURSE , TEXT) )

JD ของ TABLE : VIJ

TABLE : VIJ มี Join dependency คือ

VIJ(VENDOR_ID , ITEM_ID , PROJECT_ID) มีความสัมพันธ์แบบ JD * ( (VENDOR_ID , ITEM_ID ) , ( ITEM_ID , PROJECT_ID ) , ( PROJECT_ID , VENDOR_ID ) )

ตัวอย่างการแยก TABLE : VIJ แล้วสามารถ JOIN กลับ

ตรวจสอบว่า TABLE : VIJ เป็น 5NF ไหม

  1. Primary key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  2. Candidate key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  3. JD : ( (VENDOR_ID , ITEM_ID ) , ( ITEM_ID , PROJECT_ID ) , ( PROJECT_ID , VENDOR_ID ) )

Table : VIJ ไม่เป็น 5NF เพราะ JD ไม่ได้มี Candidate key ในนั้น

วิธีแก้ไข

ทำการแยก Table ออกไปตาม JD ของ Table นั้น ซึ่งจากตัวอย่างเราจะแยก Table ออกเป็น 3 Table คือ

TABLE : VENDOR ITEM (VI)

TABLE :  VENDOR ITEM (VI)

รายละเอียด Table

  1. Primary key : { VENDOR_ID , ITEM_ID }
  2. Candidate key : { VENDOR_ID , ITEM_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)
  6. JD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ Table นี้ไม่มี JD ดังนั้นจึงไม่ต้องเช็คว่าทุก JD มี Candidate key อยู่ไหม

TABLE : ITEM_PROJECT (IJ)

TABLE :  ITEM_PROJECT (IJ)

รายละเอียด Table

  1. Primary key : { ITEM_ID , PROJECT_ID }
  2. Candidate key : { ITEM_ID , PROJECT_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)
  6. JD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ Table นี้ไม่มี JD ดังนั้นจึงไม่ต้องเช็คว่าทุก JD มี Candidate key อยู่ไหม

TABLE : PROJECT_VENDOR (JV)

TABLE : PROJECT_VENDOR (JV)

รายละเอียด Table

  1. Primary key : { PROJECT_ID , VENDOR_ID }
  2. Candidate key : { PROJECT_ID , VENDOR_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)
  6. JD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ Table นี้ไม่มี JD ดังนั้นจึงไม่ต้องเช็คว่าทุก JD มี Candidate key อยู่ไหม

ตรวจสอบว่ามีปัญหา INSERT UPDATE DELETE ไหม

ปัญหา INSERT ข้อมูลไม่ได้

ถ้าผมอยาก Insert ข้อมูลว่า VENDOR : V2 ว่ามี ITEM : I2 ขาย เราสามารถทำการ INSERT ข้อมูลลง Table : VENDOR_ITEM ได้เลย โดยไม่ติดปัญหา Primary key must not be null

ปัญหา DELETE ข้อมูล

ถ้าผมอยากลบข้อมูลที่ VENDOR : V1 ขาย ITEM : I2 ก็สามารถลบข้อมูลได้เลยไม่ติดอะไร

การทำ 5NF ต้องทำให้ Table เหลือแค่ 2 Column (Attribute)

เรื่องนี้เป็นความเข้าใจผิดว่าเวลาจะทำให้ Table ให้เป็น 5NF ได้นั้นต้องแยก Table ให้เหลือ 2 Column ซึ่งนั่นทำให้เกิดปัญหาเรื่อง Join ข้อมูลทำให้เกิดปัญหาเรื่อง performance แต่นี่เป็นความเข้าใจที่ผิดครับ หากคุณอ่านนิยามของ 5NF ดีๆไม่มีตรงไหนบอกว่าต้องมี Column (Attribute) เหลือแค่ 2 Column เรามาดูตัวอย่าง Table ที่เป็น 5NF และมีมากกว่า 2 Column ดูกันครับ (คุณเคยเห็น Table นี้แล้ว)

TABLE : USER

รายละเอียด Table

  1. Primary key : USERNAME

  2. Candidate key :

    • USERNAME
    • EMAIL
  3. Nonkey attribute :

    • USER_TYPE
  4. FD :

    • USERNAME -> EMAIL
    • EMAIL -> USERNAME
    • USERNAME -> USER_TYPE
    • EMAIL -> USER_TYPE
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)

  6. JD

    • ( (USERNAME , EMAIL ) , ( USERNAME , USER_TYPE ) )

    • ( (USERNAME , EMAIL ) , ( EMAIL , USER_TYPE ) )

    • ( (EMAIL , USERNAME) , ( USERNAME , USER_TYPE) )

    • ( (EMAIL , USERNAME ) , ( EMAIL , USER_TYPE ) )

      จะเห็นว่า 1 Table สามารถมีได้หลาย JD นะครับ ลองแยก Table แล้วกลับไป JOIN ดูครับมัน JOIN กลับได้ข้อมูลเดิมทั้งหมด

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี FD ระหว่าง Nonkey attribute
  • BCNF: เป็นเพราะ Determinant ของ FD ใน Table นี้เป็น Candidate key ทั้งหมด
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ ทุก JD มี Candidate key อยู่ด้วยทั้งหมด (ลองดูครับจะเห็นว่ามี USERNAME , EMAIL เป็นส่วนประกอบในทุกๆ JD )

จากตัวอย่างนี้คุณจะเห็นว่า Table ที่มี 3 Column ก็เป็น 5NF ได้นะครับ (จริงๆจะกี่ Column ก็ได้ครับ ตราบเท่าที่มันตรงนิยาม)

อย่า Split ถ้าไม่จำเป็น

อย่า Split ถ้าไม่จำเป็น เป็นคำพูดที่อาจารย์สอนวิชา Database ผมพูดเสมอ เพราะคนส่วนใหญ่มักจะเข้าใจผิดว่าการทำ Normalization นั้นคือการพยายามแยก Table ให้เล็กที่สุด แบบที่บางคนเข้าใจกันว่า 5NF ต้องมี 2 Column (Attribute) ซึ่งการทำ Normalization นั้นมีเป้าหมายเพื่อจัดการให้ Table ไม่มีปัญหา INSERT , DELETE , UPDATE ซึ่งเมื่อเกิดปัญหาก็ต้องแก้โครงสร้างของ Table นั้นคือการแยกตาราง ดังนั้นอย่าเข้าใจผิดนะครับ เราทำเพื่อแก้ปัญหา ไม่ใช่ทำเพื่อแยก Table

สรุป

ตอนนี้เราได้รู้ว่า 4NF , 5NF คืออะไร วิธีการแก้ไขให้ Table เป็น 4NF , 5NF และเราได้ทำลายความเชื่อและความเข้าใจผิดๆที่ว่าการทำ Normalization ทำถึง BCNF (3NF) ก็พอผ่านการแสดงให้เห็นปัญหา INSERT DELETE UPDATE ที่ยังคงมีอยู่

สุดท้ายผมหวังว่าเนื้อหาเกี่ยวกับ Normalization ทั้ง 3 ตอนที่ผมเขียนไปคงมีประโยชน์ไม่มากก็น้อย และที่สำคัญผมแนะนำให้ท่านไปหาหนังสือเกี่ยวกับวิชา Database จริงๆมาอ่านเพราะหนังสือเหล่านั้นจะอธิบายได้ดีกว่าที่ผมอธิบายเยอะมากๆครับหรือถ้ามีโอกาสควรไปเรียนกับอาจารย์ที่สอนวิชา Database ดูครับ คุณจะได้เห็นตัวอย่างที่ทำให้เข้าใจมากกว่านี้ครับ และหากข้อมูลตรงจุดไหนไม่ถูกต้อง ไม่ครบถ้วน สามารถแจ้งผมได้เลยนะครับ เดี๋ยวจะไปแก้ให้ถูกต้องให้ครับ

ในตอนถัดไปเราจะมาดูวิธีการ Design Database ด้วยการใช้ ER Diagram กันครับ

REF

  • กระบวนการ Normalization Process และนิยามที่เป็นภาษาอังกฤษทั้งหมด และตัวอย่าง Table : CTX , Table : VIJ เอามาจาก หนังสือ Relational database systems : language, conceptual modeling and design for engineers

Basic Database System Part 4 - Normalization Process , 1NF , 2NF , 3NF, BCNF

Basic Database System Part 4 - Normalization Process , 1NF , 2NF , 3NF, BCNF

ในตอนที่แล้วเราได้รู้ว่า Normalization คืออะไรไปแล้ว ตอนนี้เรามาดูว่า Normalization มีขั้นตอนอะไรบ้าง จากนั้นเราไปรู้จัก 1NF , 2NF , 3NF, BCNF ว่ามันคืออะไร

Normalization Process

กระบวนการทำ Normalization มีขั้นตอนง่ายๆดังต่อไปนี้

  1. ตรวจสอบว่า Table ที่ทำการตรวจสอบนั้นอยู่ใน 1NF ไหม ถ้าไม่อยู่ในรูปแบบ 1NF ต้องทำให้อยู่ในรูปแบบ 1NF
  2. ทำการตรวจสอบว่า Table นั้นอยู่ใน NF ชั้นที่ต้องการแล้วรึยัง ถ้าไม่อยู่ให้ทำการแยก Table ตามหลักการของแต่ NF โดยทั่วไปแล้วเราจะทำจนกว่าจะถึงชั้น 5NF (ใครบอกถึง 3NF ถือว่าผิดนะครับ ต้องทำถึง 5NF)
  3. กลับทำข้อ 2 ไปเรื่อยๆจนกว่าทุก Table ที่เรามีจะอยู่ใน NF ที่เราต้องการ ( โดยทั่วไปคือต้องถึง 5NF )

อ่านถึงตรงนี้แล้วอาจจะงงเพราะติดศัพท์พวก NF คืออะไร 1NF คืออะไร 5 NF คืออะไร เดี๋ยวเรามาค่อยๆดูกันครับว่า NF คืออะไร ไล่ไปเรื่อยๆจนถึง BCNF แล้วไปต่อ 4NF , 5NF ในตอนต่อไป

Normal form (NF)

Normal form คือ Table (Relation) ที่อยู่ในรูปแบบที่ดี (Good form) โดยแต่ละ Normal form นั้นจะแก้ปัญหาเกี่ยวกับ INSERT UPDATE DELETE ในกรณีต่างๆ ซึ่งแต่ละ Normal form นั้นระบุเงื่อนไขไว้ว่าต้องมีคุณสมบัติอะไรจึงจะผ่าน Normal form นั้น ในกรณีไม่ผ่านก็จะมีวิธีแก้ไขบอกว่าต้องทำอย่างไร

1NF

A relation table structure T is in the first normal form (1NF) , if and only if all of its attributes contain atomic values only , and each attribute belongs to only one domain

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

Table ที่จะเป็น 1NF ได้นั้น Column (Attribute) ทั้งหมดของ Table นั้นจะต้องมีค่าเป็น atomic value และ Column เหล่านั้นต้องมีค่ามาจาก Domain เดียวกัน

อ่านแบบนี้คงจะไม่เข้าใจเรามาลองดูตัวอย่าง Table ที่ไม่ผ่าน 1NF กันดีกว่า

All of its attributes contain atomic values only : Column (Attribute) ทั้งหมดของ Table นั้นจะต้องมีค่าเป็น atomic value

เรามาดูตัวอย่าง Table ที่ Column (Attribute) มีค่าไม่เป็น atomic value

Column : MOBILE_NO ไม่เป็น Atomic value

จากตัวอย่าง Table ในภาพจะเห็นว่า Column “MOBILE_NO” นั้นไม่เป็น Automic value เพราะมีค่าเป็น List ของเบอร์มือถือที่ User คนนั้นมี ถามว่าปัญหาที่จะเกิดขึ้นจาก Table ที่เก็บค่าแบบนี้คือ เวลาคุณอยากเพิ่มเบอร์โทรขึ้นมาคุณจะสั่งยังไง มันจะไม่ใช่การสั่งแบบ INSERT เบอร์โทรศัพท์ใหม่เข้าไป แต่ต้องไปดูก่อนว่ามี Row ของ User นี้อยู่ใน Database ไหม ถ้าไม่มีจะ INSERT แต่ถ้ามีต้องเป็น UPDATE ค่าที่ Row เก่า ซึ่งคุณจะต้องทำการ Substring ตัดต่อ String เบอร์โทรศัพท์ เช่นกันถ้าต้องการลบข้อมูลโทรศัพท์คุณจะไม่ได้สั่ง DELETE ROW แต่จะกลายเป็นต้องเข้าไปหา ROW ของ USER นั้นจากนั้นดึงค่าจากนั้นต้อง Replace string แล้วเอาค่าใหม่ใส่เข้าไปแทน

อีกทั้งถ้าคุณจำได้ Relation คือ Subset of the Cartesian product of domains ผลลัพธ์ของ Cartesian product of domains ที่ออกมาใน attribute ต่างๆจะไม่มีทางเป็น Set หรือ List ดังนั้น Table ที่เราเห็นนี้ไม่ใช่ Relation ด้วยซ้ำไป

วิธีแก้ไข

วิธีแก้ไข Table นี้ให้อยู่ในรูปแบบ 1NF ก็คือทำให้มันเป็น Automic value คือให้ 1 row มี 1 ค่าไป ซึ่งจะได้ผลลัพธ์ออกมาดังภาพด้านล่าง

Table ที่ถูกแก้ให้เป็น 1NF

Each attribute belongs to only one domain : แต่ละ Column (Attribute) ต้องอยู่ภายใน 1 Domain เท่านั้น

เรามาดูตัวอย่าง Table ที่ไม่ถูกกฎนี้กัน

Column : VALUES มีค่ามาจากหลากหลาย Domain

จากตัวอย่าง Table จะเห็นว่า Column : VALUES นั้นมีค่ามาจากหลาย Domain คือจะเห็นว่าเป็นค่าที่มา Domain : เบอร์มือถือ , Domain : email ปัญหาที่จะเกิดกับ Table นี้คือ ถ้าคุณอยากหาแสดงข้อมูล USERNAME , EMAIL , MOBILE_NO, NICKNAME ของ USER ทั้งหมดที่มี EMAIL = ‘surapong007@hotmail.com’ คุณจะเขียน SQL ยังไงออกมา (เขียนได้นะครับแต่เขียนยากในระดับหนึ่งเลย)

อีกทั้ง Table นี้ไม่จัดเป็น Relation เพราะ ผลลัพธ์ของ Cartesian product of domains ที่ออกมาใน attribute ต่างๆต้องมาจาก Domain เดียวกันไม่ใช่มาจากหลากหลาย Domain

วิธีแก้ไข

วิธีแก้ไขให้ Table นี้อยู่ในรูปแบบ 1NF คือแยก Column ที่มาจากหลาย Domain ให้เป็น Column ใหม่ไปเลยดังภาพด้านล่าง

Table ที่ถูกแก้ให้เป็น 1NF

จะเห็นว่า Table ถูกเพิ่ม Column : EMAIL , MOBILE_NO, NICKNAME เข้าไป

ลองตรวจสอบกับ TABLE : CURRENTCY_TRADING_SYSTEM ว่าเป็น 1NF ไหม

TABLE : CURRENTCY_TRADING_SYSTEM

เราลองตรวจ TABLE : CURRENTCY_TRADING_SYSTEM ดูว่าเป็น 1NF ไหมโดยดูตามกฏของ 1NF ที่ว่า

  • All of its attributes contain atomic values only
    ข้อนี้ผ่านเพราะทุกค่าของแต่ละ Column เป็น Atomic value
  • Each attribute belongs to only one domain
    ข้อนี้ผ่านเพราะทุกค่าของแต่ละ Column มาจาก Domain เดียวกัน

ดังนั้น TABLE : CURRENTCY_TRADING_SYSTEM จึงเป็น 1NF

2NF

A relation table structure T is in the second normal form (2NF) if and only if the relationship between primary key and every nonkey attribute is in full functional dependence

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

Table ที่จะเป็น 2NF ได้นั้น ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ทุกตัวต้องเป็น Full functional dependence

ผมเชื่อว่าอ่านแล้วอาจจะไม่เข้าใจเพราะติดศัพท์ทางเทคนิค เรามาดูศัพท์เทคนิคทีละตัวครับ

Nonkey attribute

คือ Column หรือกลุ่มของ Column ที่ไม่ได้เป็น Candidate key (จริงๆ Column มันคือ Attribute นั่นแหละ ถ้าตามทฤษฎีเราต้องเรียก Column ว่า Attribute เรียก Row ว่า Tuple แต่ขอละเป็น Column ละกันนะ)

Functional dependence (FD)

คือความสัมพันธ์แบบ Function อ่านแล้วงงใช่ไหมครับ คิดง่ายๆครับว่าถ้า A มีความสัมพันธ์แบบ Function กับ B ( A -> B ) แปลว่า ถ้าเรากำหนดค่า A เป็นค่าหนึ่ง จะได้ค่า B เป็นค่าหนึ่งเสมอ ซึ่งผมว่าก็ไม่เข้าใจอีกแหละ เราลองมาดูตัวอย่างอย่างกัน

 ความสัมพันธ์ระหว่าง USERNAME กับ EMAIL

คุณลองดู COLUMN USERNAME กับ EMAIL ครับ คุณจะเห็นว่าถ้าเรากำหนดค่า USERNAME เป็น sarun เราจะได้ email เป็น fax_inwza007@hotmail.com เสมอ ซึ่งไม่ได้แค่ USERNAME เป็น sarun USERNAME อื่นๆก็เป็นแบบนี้ ความสัมพันธ์แบบนี้คือ Funcational dependence ครับ ถามว่าแล้วเราจะรู้ได้ไงว่ามันเป็น ต้องมานั่งไล่ดูค่าทุกค่าเลยเหรอ จริงๆคือไม่ใช่ครับ เราดูค่าเบื้องต้นเพื่อคาดเดาว่าอาจจะใช่ การจะบอกว่าใช่หรือไม่ใช่นั้นต้องไปดูความสัมพันธ์ตามงานจริงครับ คือในงานนี้ USERNAME กับ EMAIL เป็น Functional dependence ( USERNAME -> EMAIL ) เพราะ USERNAME มี EMAIL ได้แค่ EMAIL เดียว ดังนั้นถ้ากำหนดค่า USERNAME อะไรก็จะอ้างถึง EMAIL ได้ EMAIL เดียวเสมอ มันจะแตกต่างกับความสัมพันธ์ระหว่าง USERNAME กับ CURRENCY_CODE ครับที่ 1 USERNAME สามารถมีได้หลาย CURRENCY_CODE

ความสัมพันธ์ระหว่าง USERNAME กับ CURRENCY_CODE

Full Functional dependence

ในส่วนที่แล้วเรารู้ว่า Functional dependence (FD) แต่ Full Functional dependence คืออะไรล่ะ อธิบายยากคุณลองดูตัวอย่างดีกว่า คุณสังเกตุดูจะเห็นว่า { USERNAME , CURRENCY_CODE } มีความสัมพันธ์ FD กับ EMAIL

คุณลองดูได้เลยครับว่าจริงไหม มันจริงแน่นอนครับเพราะ USERNAME มันเป็น FD กับ EMAIL ดังนั้นจะเอา USERNAME ไปรวมกับ Column ไหนมันก็เป็น FD หมดแหละ แต่สิ่งที่เราต้องการจริงๆคือความสัมพันธ์แบบ USERNAME -> EMAIL ไม่ใช่ { USERNAME , CURRENCY_CODE } -> EMAIL ดังนั้นจะเป็น Full Functional dependence ก็ต่อเมื่อ EMAIL นั้นขึ้นอยู่กับค่า USERNAME และ CURRENCY_CODE ทั้งคู่ ซึ่งจะเห็นว่าไม่ใช่เพราะ EMAIL ขึ้นอยู่กับค่า USERNAME ค่าเดียว

  • { USERNAME , CURRENCY_CODE } -> EMAIL
  • USERNAME -> EMAIL

หรือว่าง่ายๆถ้าหาค่าฝั่งซ้ายที่เป็น Subset ได้ก็แปลว่าไม่เป็น Full FD ละ จากตัวอย่าง { USERNAME , CURRENCY_CODE } -> EMAIL ไม่เป็น Full FD เพราะเราเจอ FD : USERNAME -> EMAIL ซึ่งจะเห็น USERNAME เป็น Subset ของ { USERNAME , CURRENCY_CODE }

ลองตรวจสอบกับ TABLE : CURRENTCY_TRADING_SYSTEM ว่าเป็น 2NF ไหม

เรามา List แต่ละส่วนประกอบที่เราต้องใช้ตรวจสอบ

  1. Primary key : { USERNAME , CURRENCY_CODE }

  2. Nonkey attribute มีดังต่อไปนี้

    • EMAIL
    • USER_TYPE
    • PRIORITY
    • CURRENCY_NAME
    • COUNTRY
    • AMOUNT
  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • USERNAME -> EMAIL
    • USERNAME -> USER_TYPE
    • USERNAME -> PRIORITY
    • CURRENCY_CODE -> CURRENCY_NAME
    • CURRENCY_CODE -> COUNTRY
    • USER_TYPE -> PRIORITY
    • { USERNAME , CURRENCY_CODE } -> AMOUNT

จากนิยาม

A relation table structure T is in the second normal form (2NF) if and only if the relationship between primary key and every nonkey attribute is in full functional dependence

Table ที่จะเป็น 2NF ได้นั้น ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ทุกตัวต้องเป็น Full functional dependence

จะเห็นว่า TABLE : CURRENTCY_TRADING_SYSTEM ไม่เป็น 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ไม่ได้เป็น Full functional dependence ดูได้จาก { USERNAME , CURRENCY_CODE } ไม่ได้เป็น Full FD กับ EMAIL , USER_TYPE , PRIORITY , CURRENCY_NAME , COUNTRY

วิธีแก้ไข

วิธีแก้ทำให้ Table นี้เป็น 2NF ก็คือแยก Table ออกไปโดยเราจะแยก Table ตาม FD ที่เป็น Subset ของ Primary เลยครับ จากนั้นก็ตรวจสอบอีกครั้งว่าเป็น 2NF ไหม โดยจากตัวอย่างเราจะแยกได้ 3 Table คือ

Table : USER

TABLE : USER

ตรวจสอบว่า Table นี้เป็น 2NF ไหม

  1. Primary key : USERNAME

  2. Nonkey attribute มีดังต่อไปนี้

    • USER_TYPE

    • PRIORITY

      คุณอาจจะสงสัยว่าทำไม EMAIL หายไปไหน ที่มันหายไปเพราะ EMAIL เป็น Candidate key นะครับ

  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • USERNAME -> USER_TYPE
    • USERNAME -> PRIORITY
    • USER_TYPE -> PRIORITY

Table นี้เป็น 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute เป็น Full FD ทั้งหมด

Table : CURRENCY

Table : CURRENCY

ตรวจสอบว่า Table นี้เป็น 2NF ไหม

  1. Primary key : CURRENCY_CODE

  2. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY

      คุณอาจจะสงสัยว่าทำไม CURRENCY_NAME หายไปไหน ที่มันหายไปเพราะ CURRENCY_NAME เป็น Candidate key นะครับ ทำไม Country ไม่เป็น ที่ไม่เป็นก็เพราะบางประเทศมีหลายสกุลเงินนะครับ

  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • CURRENCY_CODE -> COUNTRY

Table : USER_CURRENCY

Table : USER_CURRENCY

ตรวจสอบว่า Table นี้เป็น 2NF ไหม

  1. Primary key : { USERNAME , CURRENCY_CODE }

  2. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY

      คุณอาจจะสงสัยว่าทำไม CURRENCY_NAME หายไปไหน ที่มันหายไปเพราะ CURRENCY_NAME เป็น Candidate key นะครับ ทำไม Country ไม่เป็นล่ะ ที่ไม่เป็นก็เพราะบางประเทศมีหลายสกุลเงินครับ

  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • { USERNAME , CURRENCY_CODE } -> AMOUNT

Table นี้ 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute เป็น Full FD ทั้งหมด

3NF

A relation table structure T is in the third normal form (3NF) if and only if T is in 2NF and there are no funcational dependencies between nonkey attributes of T

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

Table จะเป็น 3NF ก็ต่อเมื่อ Table นั้นเป็น 2NF และ Table นั้นไม่มี funcational dependence ระหว่าง nonkey attributes ของ Table นั้น

สำหรับขั้นนี้นั้นเราไม่ติดศัพท์อะไรแล้ว เรามาตรวจสอบ Table ที่เราได้จากขั้นตอนที่แล้วกันเลยว่าจะสามารถเป็น 3NF ได้หรือไม่

Table : USER_CURRENCY

Table : USER_CURRENCY

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF

Table : CURRENCY

Table : CURRENCY

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF

Table : USER

Table : USER

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • USER_TYPE
    • PRIORITY
  2. FD ระหว่าง Nonkey attribute

    • USER_TYPE -> PRIORITY

Table นี้ไม่เป็น 3NF เพราะเราตรวจพบ FD คือ USER_TYPE -> PRIORITY ซึ่งเป็น Nonkey attribute

วิธีแก้ไข

ให้ทำการแยกตารางออกไปตาม FD ของ Nonkey attribute ครับ ส่วน Table เดิมเก็บ Column ที่เป็นตัวกำหนดไว้ ส่วน Column ที่มีค่าตามให้ลบออกจาก Table โดยจากตัวอย่างเราจะแก้ไข Table : USER ลบ Column : PRIORITY และ สร้าง Table USER_TYPE ขึ้นมาใหม่

Table : USER

Table : USER

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • USER_TYPE
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF ตามนิยาม

Table : USER_TYPE

Table : USER_TYPE

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • PRIORITY
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF ตามนิยาม

Table ที่เป็น 3NF ที่มีปัญหา INSERT , DELETE , UPDATE

Table ที่เป็น 3NF และมีปัญหา INSERT , DELETE , UPDATE

เรามาดูรายละเอียดของ TABLE นี้เพื่อนำไปใช้ในการตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Primary key : { USERNAME , CURRENCY_CODE }
  2. Candidate key : { USERNAME , CURRENCY_CODE } , { EMAIL, CURRENCY_CODE }
  3. Nonkey attribute มีดังต่อไปนี้
    • AMOUNT
      EMAIL ไม่เป็น Nonkey attribute เพราะมันเป็น 1 ใน Candidate key
  4. FD ใน Table
    • { USERNAME , CURRENCY_CODE } -> AMOUNT
    • { EMAIL , CURRENCY_CODE } -> AMOUNT
    • USERNAME -> EMAIL
    • EMAIL -> USERNAME

ตรวจสอบ NF แต่ละขั้น

  • 1NF
    เป็น 1NF เพราะทุก Column ( Attribute ) เป็น Atomic และ แต่ละ Column มีค่ามาจาก Domain เดียว
  • 2NF
    เป็น 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ทุกตัวเป็น Full functional dependence ดูได้จาก { USERNAME , CURRENCY_CODE } เป็น Full FD กับ AMOUNT ซึ่งเป็น nonkey attribute ตัวเดียว
  • 3NF
    เป็น 3NF เพราะ Table นี้เป็น 2NF และ Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes ดูได้จาก Nonkey attribute มีตัวเดียว

ปัญหา Insert ข้อมูลไม่ถูกต้องเข้าไปได้

ตัวอย่างปัญหา Insert ข้อมูลไม่ถูกต้องเข้าไปได้

Table นี้จะมีปัญหาการ Insert ข้อมูลที่ไม่ถูกต้องเข้าไปได้ดูได้จากเราสามารถ Insert ข้อมูล EMAIL ของ USERNAME : apirat เป็น champ007@gmail.com ได้ ซึ่งนั่นทำให้เกิดปัญหา Data inconsistency

ปัญหา Insert ข้อมูลเข้าไปไม่ได้

จากตัวอย่างเราไม่สามารถ Insert ข้อมูลของ User ใหม่เข้าไปได้เลย เช่น ถ้าผมต้องการ Insert ข้อมูล User : wasinee เข้าไปผมจะไม่สามารถเข้าไปได้เพราะติดกฎ Primary key must not be null

ตัวอย่างปัญหา Insert ข้อมูลเข้าไปไม่ได้

ปัญหา Delete ข้อมูล

จากตัวอย่างถ้าเราลบข้อมูลการ Row ที่ผมล้อมกรอบสีแดงไว้ ข้อมูลของ User : apirat จะหายไปเลย ทั้งๆที่เราอยากลบข้อมูลการที่เขามีเงินสกุล THB ไปเท่านั้น

ตัวอย่างปัญหา Delete ข้อมูล

ซึ่งจากป้ญหานี้จึงต้องทำ Normalization ขั้นตอนต่อไป

BCNF

A relation table structure T is in the Boyce/Codd normal form (BCNF) if and only determinant in T is a candidate key of T.

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

Table จะเป็น BCNF ได้นั้น Determinant ทั้งหมดใน Table จะต้องเป็น Candidate key ของ Table

ผมว่าคุณน่าจะไม่เข้าใจเพราะติดศัพท์เทคนิค Determinant ว่าคืออะไร

Determinant

ถ้าเราบอกว่า A กับ B มีความสัมพันธ์แบบ Functional dependence โดยค่าของ A เป็นตัวกำหนดว่าค่าของ B เราจะสามารถซึ่งจะเขียนอธิบายแบบนี้ A -> B ซึ่ง A จะเป็น Determinant ดังนั้นถ้ามีความสัมพันธ์ FD ที่ USERNAME -> EMAIL ก็แปลว่า USERNAME เป็น Determinant

ตรวจสอบ Table ที่เป็น 3NF ที่มีปัญหาว่าเป็น BCNF ไหม

รายละเอียดของ Table

  1. Candidate key : { USERNAME , CURRENCY_CODE } , { EMAIL, CURRENCY_CODE }
  2. FD ใน Table
    • { USERNAME , CURRENCY_CODE } -> AMOUNT
    • { EMAIL , CURRENCY_CODE } -> AMOUNT
    • USERNAME -> EMAIL
    • EMAIL -> USERNAME

เนื่องจาก Table นี้มี Determinant ที่ไม่เป็น Candidate key คือ USERNAME และ EMAIL ดังนั้น Table นี้ไม่ได้เป็น BCNF

วิธีแก้ไข

วิธีแก้ไขให้ Table นี้ให้เป็น BCNF นั้นสามารถทำได้โดยแยกเอา COLUMN ที่เป็น Determinant ที่ไม่ได้เป็น Candidate key ออกไปโดยผมจะเลือกเอา Column EMAIL ออกไปซึ่งจะทำให้เราจะได้ตารางใหม่สองตารางเป็น

TABLE : BCNF_USER_CURRENCY

TABLE : BCNF_USER_CURRENCY

ตรวจสอบว่า Table นี้เป็น BCNF ไหม

  1. Candidate key : { USERNAME , CURRENCY_CODE }
  2. FD ใน Table
    • { USERNAME , CURRENCY_CODE } -> AMOUNT

เนื่องจาก Determinant ของทุก FD เป็น Candidate key ดังนั้น Table นี้จึงเป็น BCNF

TABLE : BCNF_USER

TABLE : BCNF_USER

ตรวจสอบว่า Table นี้เป็น BCNF ไหม

  1. Candidate key : USERNAME , EMAIL
  2. FD ใน Table
    • USERNAME -> EMAIL
    • EMAIL -> USERNAME

เนื่องจาก Determinant ของทุก FD เป็น Candidate key ดังนั้น Table นี้จึงเป็น BCNF

เกี่ยวกับ BCNF

โดยปกติแล้ว Table ที่เป็น 3NF ส่วนใหญ่นั้นจะไม่มีปัญหา INSERT , DELETE , UPDATE ที่มาจากความสัมพันธ์ FD แล้ว แต่จะมีบางกรณีแบบในตัวอย่างที่เป็น 3NF แล้วแต่ยังมีปัญหา ดังนั้นจึงมีการคิดค้น BCNF เพื่อตรวจสอบและจัดการกับกรณีนี้

สรุป

สำหรับตอนนี้เราได้เรียนรู้เกี่ยวกับ Normalization Process ว่ามีกระบวนการอย่างไร Normal Form ตั้งแต่ขึ้น 1NF ถึง BCNF ได้รู้ว่า Functional Dependency คืออะไร เราได้ลองทำ Normalization Process กับ Table : CURRENTCY_TRADING_SYSTEM ไปจนถึงขั้น BCNF แล้ว (ตัวอย่างผมทำให้ดูถึง 3NF คุณลองไปทำต่อดูว่า Table เหล่านั้นเป็น BCNF ได้ยังไง) ซึ่งเราจะได้ Table ทั้งหมดตามภาพด้านล่าง

Table ทั้งหมดที่เป็น BCNF

ซึ่งถ้าคุณอ่านถึงตอนที่แล้วคุณจะรู้ว่า Table เหล่านี้ไม่มีปัญหา INSERT , DELETE , UPDATE แล้ว ซึ่งนั่นทำให้เกิดความเข้าใจผิดๆว่า Normalization Process นั้นทำถึงแค่ BCNF ก็พอ (มีแย่กว่านั้นที่บอกว่า 3NF ก็พอ) จริงๆถ้าทำถึงขั้น BCNF แล้ว Table ทั้งหมดที่ได้จะไม่เกิดปัญหา INSERT , DELETE , UPDATE ที่มาจากความสัมพันธ์ระหว่าง Column ( Attribute ) ที่เป็น FD แต่ความสัมพันธ์นั้นไม่ได้มีแค่ FD ครับ ยังมีความสัมพันธ์อื่นๆอีก ดังนั้นตอนต่อไปเราจะมาทำ Normalization Process ในขั้น 4NF ,5NF กันต่อครับ

Ref

  • กระบวนการ Normalization Process และนิยามที่เป็นภาษาอังกฤษทั้งหมดเอามาจาก หนังสือ Relational database systems : language, conceptual modeling and design for engineers

Basic Database System Part 3 - Normalization

Basic Database System Part 3 - Normalization

สำหรับตอนนี้เราจะมาพูดถึง Normalization ว่ามันคืออะไร จากนั้นเราจะมาดูตัวอย่างของปัญหาจนทำให้เราต้องมาทำ Normalization กันครับ แล้วก็ตามที่ผมบอกไปนะครับที่ผมเขียนตรงนี้อาจไม่ถูกต้องตามทฤษฎี 100% คุณสามารถอ่านมันเป็นแนวทางเริ่มต้นครับ จากนั้นพอเข้าใจแล้วลองไปหาหนังสือเกี่ยวกับ Database จริงๆมาอ่าน หรือถ้าได้มีโอกาสเรียนกับอาจารย์ก็ขอให้ตั้งใจเรียนและถามสิ่งที่สงสัยกับอาจารย์ที่สอนนะครับ

Normalization

จริงๆผมอยากเอาปัญหาตั้งก่อนแล้วค่อยบอกว่า Normalization แต่คิดไปคิดมาอธิบายก่อนเลยดีกว่าว่ามันคืออะไรเพราะมันสั้นมากๆ โดย Normalization คือกระบวนการในการออกแบบ Database เพื่อไม่ให้เกิดปัญหาเกี่ยวกับ INSERT , UPDATE , DELETE และทำให้ข้อมูลที่เราเก็บนั้นไม่มีความซ้ำซ้อนของข้อมูล

ปัญหา INSERT , UPDATE , DELETE

ส่วนนี้เรามาดูว่า Table (Relation) ที่เราคิดออกแบบขึ้นมาแล้วยังไม่ผ่านกระบวนการ Normalization จะมีปัญหาอะไรบ้าง

Table : CURRENCY_TRADING_SYSTEM

Table :  CURRENCY_TRADING_SYSTEM

สมมุติว่าผมต้องการทำ Application แลกเปลี่ยนเงินตราระหว่างประเทศขึ้นมา เรา Design Table : CURRENCY_TRADING_SYSTEM ขึ้นมาเพื่อเก็บข้อมูลว่า User ไหนเก็บเงินสกุลไหนไว้บ้าง ซึ่งผมก็ออกแบบ Table ไว้เก็บข้อมูลดังภาพ โดยแต่ละ Column จะเก็บข้อมูล

  • USERNAME : เก็บ USERNAME ของผู้ใช้
  • EMAIL : เก็บ EMAIL ของผู้ใช้
  • USER_TYPE : เก็บว่าผู้ใช้นี้เป็น TYPE ไหน
  • PRIORITY : ค่าความสำคัญของ USER โดยความสำคัญจะขึ้นอยู่กับว่าเป็น USER TYPE ไหน โดยค่ายิ่งมากยิ่งสำคัญ
  • CURRENCY_CODE : CODE ของสกุลเงินนั้น
  • CURRENCY_NAME : ชื่อของสกุลเงินนั้น
  • COUNTRY : ชื่อประเทศเจ้าของสกุลเงินนั้น
  • AMOUNT : ผู้ใช้มีเงินสกุลนั้นเท่าไหร่

Table นี้มี Primary key คือ USERNAME , CURRENTCY_CODE ซึ่งคุณสามารถตรวจสอบได้โดยเอา USERNAME + CURRENCY_CODE ไปทำการค้นหาคุณจะเจอแค่ 1 ROW เสมอ และมันก็ตรงตาม Business Logic คือ USER หนึ่งคนก็ควรมีข้อมูลการถือเงินสกุลใดสกุลหนึ่งแค่ 1 ข้อมูลเท่านั้น มันคงจะแปลกๆถ้าบอกว่า USER : surapong มีเงิน THB 2 จำนวน

ปัญหาการ Insert

ตอนเราเห็น Table นี้เราอาจจะไม่เห็นปัญหาของมัน แต่เมื่อเราเริ่มใช้งานเนี่ยเราจะเริ่มเจอปัญหา ปัญหาแรกที่เราจะเจอมี 2 ปัญหาคือ

  1. INSERT ข้อมูลไม่ได้
  2. INSERT ข้อมูลที่ไม่ถูกต้องเข้าไปได้

เรามาดูทีละปัญหา

INSERT ข้อมูลไม่ได้

ลองนึกภาพตามนะครับว่า ถ้าคุณอยากจะ Add User ใหม่เข้ามาในระบบ แต่ User นั้นยังไม่ได้โอนเงินเข้ามาในระบบคุณเลยสักสกุลเงิน ดังนั้นข้อมูลที่คุณจะ Insert เข้าไปก็จะมีหน้าตาประมาณนี้

ข้อมูล User ที่ต้องการ Insert

ซึ่งมันเหมือนจะ Insert ได้ใช่ไหมครับ แต่จริงๆมัน Insert ไม่ได้ครับ เพราะกฎของ Relational Database Model ที่ตั้งไว้ว่า Primary key must not be null พอตัว CURRENCY_CODE มีค่าเป็น NULL ข้อมูลนี้จึงไม่สามารถ INSERT ได้

ในทางกลับกันถ้าคุณอยากเพิ่มสกุลเงินชนิดใหม่เข้าไปเก็บใน Database ซึ่งเงินพอเป็นเงินสกุลใหม่ก็แปลว่าไม่มีคนเคยซื้อเงินสกุลนี้เลย ข้อมูลที่ Insert เข้าไปก็จะเป็น

ข้อมูล Currency ที่ต้องการ Insert

ซึ่งจะเห็นว่า USERNAME = NULL ก็แปลว่าไม่สามารถ INSERT ข้อมูลได้ครับ

INSERT ข้อมูลที่ไม่ถูกต้องเข้าไปได้

ถ้าสมมุติคุณอยากจะเพิ่มข้อมูลการซื้อสกุลเงินใหม่ของ USER : surapong เข้าไป แต่ตอนบันทึกนั้น เขาใส่ข้อมูล email ผิดลงไปดังตัวอย่าง

ข้อมูล User ที่ต้องการ Insert ที่มีข้อมูล Email ไม่ถูกต้อง

ซึ่งจากตัวอย่างนั้นข้อมูลสามารถเพิ่มลงไปใน Database ได้ แต่ปัญหาที่เกิดขึ้นคือความถูกต้องของข้อมูล คุณจะเห็นได้ว่าตอนนี้ USER : surapong เนี่ยมี EMAIL ที่ 2 EMAIL คือ surapong_inwza007@hotmail.com , surapong_007inwza@hotmail.com ซึ่งคำถามคือตกลง EMAIL ไหนเป็น EMAIL ที่ถูก สมมติถ้าต้องส่ง EMAIL ไปให้ user คนนั้นเราจะต้องใช้ EMAIL ไหนล่ะ ปัญหาข้อมูลไม่ถูกต้องไม่สัมพันธ์กันนี้มีชื่อเรียกว่า Data inconsistency

ปัญหาการ Delete

ปัญหาการ Delete ที่เราจะเจอนั้นคือปัญหาการลบข้อมูลที่ไม่ได้อยากลบให้หายไปด้วย อ่านแล้วอาจจะไม่เข้าใจ เรามาลองดูตัวอย่างครับ

ข้อมูลที่ต้องการ Delete

จากภาพเราต้องการลบ Row ที่ล้อมกรอบสีแดงไว้ ซึ่งก็เป็นเรื่องปกติที่จะลบข้อมูลออกเพราะ User ทำการถอนเงินออกไปแล้ว แต่ปัญหาอยู่ที่เมื่อเราลบข้อมูล Row นี้ทิ้งไป ข้อมูลเกี่ยวกับสกุลเงิน JPY (Yen) จะหายไปจาก Database ด้วย ซึ่งนั่นเป็นสิ่งที่เราไม่ต้องการ

ปัญหาการ Update

ตัวอย่างข้อมูลที่ซ้ำซ้อน

ปัญหานี้เกิดจากที่มีข้อมูลซ้ำซ้อนอยู่ใน Table จากตัวอย่างคุณจะเห็นว่าข้อมูล email ของ USER นั้นแสดงซ้ำ คราวนี้เวลาจะต้องแก้ไขข้อมูล email เช่น ต้องการเปลี่ยน email ของ USER : sarun เป็น sarun@gmail.com ก็ต้องทำการ UPDATE ทุก Row ที่ USERNAME = sarun ซึ่งถ้าเป็นคำสั่ง SQL ก็จะเป็นแบบนี้

1
2
3
UPDATE CURRENCY_TRADING_SYSTEM
SET EMAIL = 'sarun@gmail.com'
WHERE USERNAME = 'sarun'

ถามว่ามันเป็นปัญหายังไง ปัญหาคือเมื่อมันมีหลาย ROW ถ้าระหว่างที่กำลัง UPDATE แต่ละ ROW อยู่นั้นตัว DBMS นั้นเกิดปัญหา ก็แปลว่า ข้อมูล email ของ USER : sarun นั่นเองจะมี email เก่ากับ email ที่ถูกแก้ไขไปแล้วอยู่ ซึ่งนั่นก่อให้เกิดปัญหา Data inconsistency ครับ แต่น้่นเป็นเรื่องเมื่ออดีตครับ ในปัจจุบันนั้น DBMS นั้นมี TRANSACTION PROCESS ซึ่งนั่นก็แปลว่า ถ้าเกิดปัญหาระหว่างการ UPDATE ตัวระบบก็จะ ROLLBACK ข้อมูลกลับไปเหมือนว่าไม่เคยสั่ง UPDATE ดังนั้นปัญหาเรื่อง Data inconsistency จากการ UPDATE จะไม่เกิดขึ้นครับ

แล้วเราจะแก้ปัญหาพวกนี้ยังไง

วิธีแก้ปัญหา INSERT , UPDATE , DELETE ก็คือการทำ Normalization ครับ โดยกระบวนการทำนั้นผมจะยังไม่อธิบายในตอนนี้ เพราะถ้าอธิบายในตอนนี้มันจะยาวมากเพราะต้องยกตัวอย่างให้เห็น ดังนั้นเราแสดงผลลัพธ์จากการทำ Normalization ก่อนเพื่อให้เห็นว่ามันสามารถแก้ปัญหา INSERT , UPDATE , DELETE ได้จริง

ผลลัพธ์จากการทำ Normalization

Table ที่เกิดจากการทำ Normalization

ผลลัพธ์จากการทำ Normalization นั้นจะเปลี่ยนจาก Table : CURRENCY_TRADING_SYSTEM มาเป็น 4 Table คือ

  • USER : Table นี้เก็บข้อมูลของ User
  • USER_TYPE : Table นี้เก็บข้อมูลของ USER TYPE
  • CURRENCY : Table นี้เก็บข้อมูลของ CURRENCY
  • USER_CURRENCY : Table นี้เก็บข้อมูลว่า USER นั้นมี CURRENCY ใดอยู่บ้าง

ทดสอบกับปัญหาการ Insert

ทดสอบกับปัญหา Insert ไม่ได้

หากเราต้องการ Insert User ใหม่เข้าไปในระบบเราสามารถ Insert ข้อมูลไปที่ Table : User ได้เลยเพราะไม่ติดปัญเรื่อง Primary key must not be null แล้ว

ข้อมูล User ใหม่ที่ต้องการ Insert

ทดสอบปัญหา INSERT ข้อมูลที่ไม่ถูกต้องเข้าไปได้

ปัญหานี้จะถูกแก้เพราะเมื่อเราต้องการ Insert ข้อมูว่า User : surapong มีสกุลเงินใหม่เพิ่มเข้าไปนั้นจะทำการเพิ่มที่ Table : USER_CURRENCY ซึ่ง Table นี้จะทำการกรอกแค่ USERNAME , CURRENCY , AMOUNT เท่านั้น ดังนั้นจะไม่มีทางกรอกข้อมูลที่ไม่ถูกต้องไม่สอดคล้องลงไปได้

ข้อมูล USER_CURRENCY ใหม่ที่ต้องการ Insert

ทดสอบกับปัญหาการ Delete

ปัญหาการ Delete แล้วลบข้อมูลที่ไม่อยากลบจะไม่เกิดขึ้นเพราะเวลาลบข้อมูลเราลบที่ Table : USER_CURRENCY ซึ่งเมื่อลบไปแล้วข้อมูลของ CURRENCY ก็ยังคงอยู่ไม่ได้หายไป

ข้อมูลที่ต้องการลบ

อยากแสดงข้อมูลเหมือน Table : CURRENCY_TRADING_SYSTEM จะทำยังไง

ถ้าเราอยากแสดงข้อมูลเหมือนกับ Table : CURRENCY_TRADING_SYSTEM นั้นสามารถทำได้โดยการ SELECT แล้วในคำสั่ง SELECT เราสั่งให้ทำการ JOIN TABLE ที่เกี่ยวข้องเข้าด้วยกัน โดยจากตัวอย่างเราจะได้คำสั่ง SQL แบบนี้

1
2
3
4
5
SELECT *
FROM USER_CURRENCY t1
INNER JOIN USER t2 ON t1.USERNAME = t2.USERNAME
INNER JOIN CURRENCY t3. ON t1.CURRENCY_CODE = t3.CURRENCY_CODE
INNER JOIN USER_TYPE t4 ON t2.USER_TYPE = t4.USER_TYPE

ปัญหาใหม่

เมื่อทำ Normalization เพื่อออกแบบ Database ให้ไม่ให้เกิดปัญหาการ INSERT , DELETE , UPDATE ซึ่งผลลัพธ์ที่ได้คือเปลี่ยนจาก 1 Table กลายเป็น 4 Table ปัญหาที่ตามมาก็คือเมื่อต้องการแสดงข้อมูลให้เหมือนกับ Table : CURRENCY_TRADING_SYSTEM นั้นจะต้องทำการ JOIN ซึ่งเมื่อทำการ JOIN ก็จะเกิดปัญหาเรื่องต้องใช้ Resource มาทำการ JOIN ซึ่งเป็นปัญหาด้าน Performance

พอเป็นแบบนี้คุณก็จะบอกว่า อ้าวแล้วทำไปทำไมวะ คำตอบก็คือ ปัญหาเรื่อง Resource ที่ใช้ในการ JOIN ซึ่งเป็นปัญหาเรื่อง Performance นั้นสามารถแก้ไขได้ด้วยการเพิ่ม Hardware หรือใช้วิธีการ Tuning DBMS ให้สามารถ JOIN ได้เร็วขึ้นอาจจะทำ INDEX แบ่ง Partition data ต่างๆนาๆ แต่ปัญหา INSERT , UPDATE , DELETE และปัญหา Data inconsistency นั้นไม่สามารถแก้ได้ด้วย Hardware หรือการ Tuning DBMS แก้ได้ วิธีแก้คือต้องไปไล่แก้ข้อมูลให้ถูกต้องหรือไปเพิ่มเงื่อนไขในการทำงานเช่น ถ้าสมัคร User ใหม่ต้องทำการซื้อสกุลเงินหนึ่งที่มีในระบบเลย หรือถ้าต้องการเพิ่มสกุลเงินใหม่ก็ต้องมีคนซื้อสกุลเงินนั้นอย่างน้อยหนึ่งคน ซึ่งอันนี้ยังพอเป็นไปได้ แต่ถ้าเรื่อง Data inconsistency คุณจะทำยังไงในเมื่อข้อมูลมันไม่ถูกต้องสอดคล้องกัน คุณจะโทรไปหา User แต่ละคนเพื่อถามว่า EMAIL ของคุณคืออันไหนกันแน่เหรอ หรือถ้าไม่โทรคุณจะเอาอะไรตัดสินใจว่าอันไหนถูก หากลองคิดแบบนี้แล้วคุณคิดว่าเราควรทำหรือไม่ควรทำ Normalization ล่ะ เพราะปัญหาหนึ่งแก้ได้ด้วยเงินกับความรู้เทคนิค อีกปัญหาหนึ่งต้องสร้างเงื่อนไขที่ทำให้การดำเนินธุรกิจมีความยากขึ้น

สรุป

สำหรับตอนนี้เราได้รู้แล้วว่า Normalization คืออะไร มันมีไว้เพื่อแก้ปัญหาอะไร แล้วมันจำเป็นต้องทำไหม เมื่อเราเข้าใจที่มาที่ไปและเหตุผลแล้ว ในตอนต่อไปเราจะไปดูว่าการทำ Normalization นั้นทำอย่างไรกันครับ