Normalisation
Why normalise?
Imagine storing every club booking in one table, with the coach repeated on every row: each booking of the Chess club would carry "Mr Ng" again and again.
That repetition causes problems. If Mr Ng leaves, you must update many rows; miss one and the data becomes inconsistent. Normalisation organises tables to remove this kind of redundancy.
ทำไมต้อง Normalise?
สมมติว่าเก็บการจองคลับทุกประการใน ตารางเดียว โดยมีผู้สอนซ้ำอยู่ในทุกแถว: การจองแต่ละครั้งของChess club จะติด "Mr Ng" ซ้ำๆ ไปเรื่อยๆ
ความซ้ำซ้อนนี้ก่อให้เกิดปัญหา หาก Mr Ng ลาออก คุณต้องอัปเดต หลาย แถว หากพลาดไปหนึ่งบรรทัด ข้อมูลจะไม่สอดคล้องกัน Normalisation จัดระเบียบตารางเพื่อขจัดความซ้ำซ้อนแบบนี้ออก
The normal forms
You normalise in steps:
- 1NF — every cell holds a single value (no lists or repeating groups), and the table has a primary key.
- 2NF — already 1NF, and no non-key column depends on only part of a composite key.
- 3NF — already 2NF, and no non-key column depends on another non-key column (no transitive dependency).
In the one-table version, coach depends on the club, not on the booking — a transitive dependency, so it is not in 3NF.
Forms ที่ปกติ化了
คุณ normalise เป็นขั้นตอน:
- 1NF — ทุก cell เก็บค่าเดียว (ไม่มีลิสต์หรือกลุ่มซ้ำ) และมี primary key
- 2NF — เป็น 1NF อยู่แล้ว และไม่มีการขึ้นอยู่กับ non-key column ที่ขึ้นอยู่กับเพียง ส่วน ของ composite key
- 3NF — เป็น 2NF อยู่แล้ว และไม่มีการขึ้นอยู่กับ non-key column จาก non-key column อื่น (ไม่มี transitive dependency)
ในเวอร์ชันตารางเดียว, coach ขึ้นอยู่กับ club ไม่ใช่กับการจอง — เป็น transitive dependency ดังนั้นจึง ไม่ใช่ 3NF
The normalised design
We split the data into two tables (the ones loaded here):
club(club_id, name, coach)— each club and its coach, stored once.booking(booking_id, student, club_id)— each booking, linked by the foreign keyclub_id.
Now a coach is stored once. A JOIN puts the information back together whenever you need it — write that join below.
การออกแบบที่ปกติ化了แล้ว
เราแยกข้อมูลออกเป็นสองตาราง (那两个加载的):
club(club_id, name, coach)— แต่ละคลับและผู้สอน, เก็บ ครั้งเดียวbooking(booking_id, student, club_id)— แต่ละการจอง, เชื่อมต่อกันด้วย foreign keyclub_id.
ตอนนี้ข้อมูลถูกจัดเก็บไว้เพียงครั้งเดียว ตัว JOIN จะนำข้อมูลกลับมาประกอบใหม่เมื่อคุณต้องการ — จงเขียนคำสั่ง join ด้านล่างนี้
Common mistakes
- Split repeating groups into their own table instead of many similar columns.
- Each table should describe one kind of thing.
ข้อผิดพลาดทั่วไป
- แยกกลุ่มข้อมูลที่ซ้ำซ้อนออกเป็นตาราง riêng แทนที่จะใช้คอลัมน์ที่คล้ายคลึงกันจำนวนมาก
- แต่ละตารางควรอธิบายถึงสิ่งประเภทใดประเภทหนึ่งเท่านั้น
Reassemble the data: list each booking's student next to their club's coach, by joining booking to club on club_id, ordered by booking.booking_id. · ประกอบข้อมูลกลับ: แสดง student ของการจองแต่ละรายการข้างเคียงกับ coach ของคลับ由其连接 booking กับ club ตาม club_id, เรียงลำดับตาม booking.booking_id
Click Run to see the output here. · คลิก Run เพื่อดูผลลัพธ์ที่นี่
The split tables still answer questions together. Count how many bookings each club has: join booking to club, show club.name and COUNT(*) AS bookings, group by the club, and order by club.name. · ตารางที่แยกออกยังคงตอบคำถามร่วมกัน นับจำนวนการจองของแต่ละคลับ: เชื่อมต่อ booking กับ club, แสดง club.name และ COUNT(*) AS bookings, จัดกลุ่มโดยคลับ, และเรียงลำดับตาม club.name
Click Run to see the output here. · คลิก Run เพื่อดูผลลัพธ์ที่นี่