Normalization (นอร์มัลไลเซชัน) ลดปัญหาการซ้ำซ้อนของข้อมูลในฐานข้อมูล

 

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

     การทำนอร์มัลไลเซชัน จะประกอบด้วย Normal Form (นอร์มัลฟอร์ม) แบบต่าง ๆ ที่มีเงื่อนไขของการทำให้อยู่ในรูปของนอร์มัลฟอร์มที่แตกต่างกันไป ขึ้นอยู่กับผู้ออกแบบฐานข้อมูลว่า ต้องการลดความซ้ำซ้อนในฐานข้อมูลให้อยู่ในระดับใด ซึ่งประกอบด้วยนอร์มัลฟอร์มแบบต่าง ๆ ดังต่อไปนี้

     – นอร์มัลฟอร์มที่ 1 (First Normal Form : 1NF)
     – นอร์มัลฟอร์มที่ 2 (Second Normal Form : 2NF)
     – นอร์มัลฟอร์มที่ 3 (Third Normal Form : 3NF)
     – บอยซ์คอดด์นอร์มัลฟอร์ม (Boyce-Codd Normal Form : BCNF)
     – นอร์มัลฟอร์มที่ 4 (Fourth Normal Form : 4NF)
     – นอร์มัลฟอร์มที่ 5 (Fifth Normal Form : 5NF)

     สรุป Normalization คือ กระบวนที่ดำเนินการอย่างเป็นลำดับ เพื่อลดปัญหาการซ้ำซ้อนของข้อมูล  ในการใช้งานจริง ๆ แล้วเราใช้แค่ 3NF ก้อเพียงพอ เพราะ BCNF, 4NF และ 5NF เป็นฐานข้อมูลที่ไม่ค่อยมีโอกาสพบหรือพบน้อยมาก ในชีวิตประจำวันเพียงแค่ 0.01% ดังนั้นเราควรเริ่มศึกษาเพียงแค่ 1-3NF ก็น่าจะเพียงพอ

การแปลงให้อยู่ในรูปนอร์มัลฟอร์มที่ 1 (First Normal Form : 1NF)
ทุก ๆ field ในแต่ละ record จะเป็น single value นั่นคือ ในตารางหนึ่ง ๆ จะไม่มี
ค่าของกลุ่มข้อมูลที่ซํ้ากัน (Repeating Group) ตัวอย่างเช่น ตารางดังต่อไปนี้

กลุ่มข้อมูลที่ซํ้ากัน (Repeating Group)
กลุ่มข้อมูลที่ซํ้ากัน (Repeating Group)

สรุป คือ นอร์มัลไลเซชันระดับที่ 1 (First normal form : 1NF) เป็น การขจัดแอตตริบิว หรือกลุ่ม
แอตตริบิวที่ซํ้ากันไปอยู่ในเอนทิตีลูก เพื่อแต่ละรายการในเอนทิตี ไม่มีค่าของแอตตริบิวหรือค่าของกลุ่ม
แอตตริบิวที่ซํ้ากัน

การขจัดแอตตริบิว หรือกลุ่ม แอตตริบิวที่ซํ้ากัน ให้อยู่ใน 1 NF
การขจัดแอตตริบิว หรือกลุ่ม แอตตริบิวที่ซํ้ากัน ให้อยู่ใน 1 NF

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

การแปลงให้อยู่ในรูปนอร์มัลฟอร์มที่ 2 (Second Normal Form : 2NF)
     1. ฟังก์ชันนัลดีเพนเดนซี (Functional Dependency: FD)
           ในการทำนอร์มัลไลเซชัน จะต้องมีความเข้าใจหลักการของฟังก์ชันดีเพนเดนซี (Function Dependency : FD) เสียก่อน โดยมีคำจำกัดความคือ B ขึ้นอยู่กับ A ถ้าทราบค่าของ A ก็จะทำให้รู้ค่าของ B ได้

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

     2. พาเชียลดีเพนเดนซี (Partial Dependency)
           พาร์เชียลดีเพนเดนซี หมายถึง การที่มีแอตทริบิวต์บางแอตทริบิวต์ ที่ขึ้นอยู่กับเพียงบางส่วนของคีย์หลักเท่านั้น ตัวอย่างเช่น จากตารางในภาพข้างล่าง แอตทริบิวต์ชื่อพนักงานจะขึ้นอยู่กับคีย์รหัสพนักงาน ในขณะที่แอตทริบิวต์ชื่อแผนก จะขึ้นอยู่กับคีย์รหัสแผนก จะเห็นว่า ข้อมูลที่อยู่ในรีเลชันเดียวกัน แต่ไม่ได้ขึ้นอยู่กับคีย์ใดคียหนึ่งทั้งหมด แต่จะขึ้นอยู่กับคีย์ใดคีย์หนึ่งเพียงบางส่วนเท่านั้น

ข้อมูลที่อยู่ในรีเลชันเดียวกัน แต่ไม่ได้ขึ้นอยู่กับคีย์ใดคียหนึ่งทั้งหมด
ข้อมูลที่อยู่ในรีเลชันเดียวกัน แต่ไม่ได้ขึ้นอยู่กับคีย์ใดคียหนึ่งทั้งหมด

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

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

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

การแปลงให้อยู่ในรูปนอร์มัลฟอร์มที่ 3 (Third Normal Form : 3NF)
     ในหนึ่งรีเลชันจะประกอบคีย์แอตทริบิวต์และนอนคีย์แอตทริบิวต์ คีย์แอตทริบิวต์จะต้องเป็นตัวกำหนดความหมายหรือการมีอยู่ของแอตทริบิวต์อื่น ๆ ที่อยู่ในรีเลชันเสมอ

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

ตัวอย่างรีเลชัน การทำงานของพนักงาน
ตัวอย่างรีเลชัน การทำงานของพนักงาน

     2. นิยามของนอร์มัลฟอร์มที่ 3
          รีเลชันจะอยู่ในรูปของนอร์มัลฟอร์มที่ 3 ก็ต่อเมื่อมีคุณสมบัติตามเงื่อนไขดังต่อไปนี้
              1. รีเลชันนั้นเป็นนอร์มัลฟอร์มที่ 2 อยู่แล้ว
              2. รีเลชันนั้นไม่มีทรานซิทีฟดีเพนเดนซี

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

รีเลชันสองรีเลชัน คือรีเลชันพนักงาน และรีเลชันตำแหน่งงาน
รีเลชันสองรีเลชัน คือรีเลชันพนักงาน และรีเลชันตำแหน่งงาน

การแปลงให้อยู่ในรูปบอยซ์คอดด์นอร์มัลฟอร์ม (Boyce-Codd Normal Form : BCNF)

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

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

ตัวอย่าง รีเลชันข้อมูลการเรียน
ตัวอย่าง รีเลชันข้อมูลการเรียน

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

ทำการแตกตารางออกมาให้อยู่ในรูปของบอยซ์คอดด์นอร์มัลฟอร์ม
ทำการแตกตารางออกมาให้อยู่ในรูปของบอยซ์คอดด์นอร์มัลฟอร์ม

การแปลงให้อยู่ในรูปนอร์มัลฟอร์มที่ 4 (Fourth Normal Form : 4NF)
     ในขณะที่การทำให้อยู่ในรูปของนอร์มัลฟอร์มต่าง ๆ ที่ผ่านมา จะเกี่ยวข้องกับการขึ้นตรงต่อกันของข้อมูลในแต่ละแอตทริบิวต์หรือฟังก์ชันนัลดีเพนเดนซี แต่การทำให้อยู่ในรูปของนอร์มัลฟอร์มที่ 4 จะเกี่ยวข้องกับรูปแบบของการขึ้นตรงต่อกันของข้อมูลในระดับที่ซับซ้อนกว่า

     1. มัลติแวลูดีเพนเดนซี (Multivalued Dependency)
ถ้าแต่ละแอตทริบิวต์ในหนึ่งรีเลชัน แบ่งออกเป็นกลุ่มของข้อมูลอิสระ เช่นแอตทริบิวต์ X, Y และ Z แบ่งออกเป็นกลุ่มข้อมูลของ X, Y และ Z ที่เป็นอิสระต่อกัน มัลติแวลลูดีเพนเดนซี X –>> Y หมายถึงว่าค่า X หนึ่งค่าสามารถที่จะบอกค่า Y ได้หลาย ๆ (X Multi-Determinse Y) ไม่ว่า Z จะมีค่าเป็นอะไรก็ตาม

ตัวอย่าง

ตัวอย่าง รีเลชันของโครงการก่อสร้าง
ตัวอย่าง รีเลชันของโครงการก่อสร้าง

     2. นิยามของนอร์มัลฟอร์มที่ 4
           รีเลชันจะอยู่ในรูปของนอร์มัลฟอร์มที่ 4 ก็ต่อเมื่อมีคุณสมบัติตามเงื่อนไขดังต่อไปนี้
                1. รีเลชันนั้นเป็นบอยซ์คอดด์นอร์มัลฟอร์มอยู่แล้ว
                2. รีเลชันนั้นไม่มีทริเวียลมัลติแวลูดีเพนเดนซี

     จากรีเลชันในภาพข้างบน เราสามารถขจัดทริเวียลมัลติแวลูดีเพนเดนซี โดยการแตกรีเลชันดังกล่าวออกเป็นรีเลชันย่อย 2 รีเลชัน ซึ่งจะทำให้ทั้งสองรีเลชันอยู่ในรูปของนอร์มัลฟอร์มที่ 4 ดังภาพข้างล่าง

การแตกรีเลชันดังกล่าวออกเป็นรีเลชันย่อย 2 รีเลชัน
การแตกรีเลชันดังกล่าวออกเป็นรีเลชันย่อย 2 รีเลชัน

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

      1. จอยน์ดีเพนเดนซี (Join Dependency)
              ในการแยกรีเลชันออกเป็นส่วนย่อย (Decomposition) R1, R2, R3, Rn มีคุณสมบัติจอยน์ดีเพนเดนซี ก็ต่อเมื่อ R1 JOIN R2 JOIN R3 … JOIN Rn = R นั่นคือเมื่อเอารีเลชันย่อยมารวมกันก็ต้องได้รีเลชันเดิม ที่ไม่มีข้อมูลสูญหาย และไม่มีทัปเพิลที่เกินมา ที่เรียกว่า สพิวเรียสทัปเพิล (Spurious Tuple)

      2. นิยามของ 5NF รีเลชันจะเป็น 5NF ถ้า
             1. รีเลชันนั้นเป็นนอร์มัลฟอร์มที่ 4 อยู่แล้ว
             2. การแบ่งแยกรีเลชันมีคุณสมบัติจอยน์ดีเพนเดนซี

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

รีเลชัน วิชาเรียนประจำภาคอยู่ในรูปของนอร์มัลฟอร์มที่ 4
รีเลชัน วิชาเรียนประจำภาคอยู่ในรูปของนอร์มัลฟอร์มที่ 4

สามารถแยกออกได้เป็นสามตาราง

แยกออกได้เป็นสามรีเลชัน
แยกออกได้เป็นสามรีเลชัน

สามารถทำการจอยน์ทั้งสามรีเลชันรวมกลับเป็นหนึ่งรีเลชันเหมือนตารางด้านบน ได้เหมือนเดิม

กระทู้ล่าสุดจากเว็บบอร์ด
หัวข้อกระทู้
ตอบ
เปิดดู
ล่าสุด
SQL JOIN: การรวมข้อมูลจากหลายตารางในฐานข้อมูล
โดย witsarutt000 พฤ 14 มี.ค. 2024 4:07 pm บอร์ด SQL Knowledge
1
289
พฤ 14 มี.ค. 2024 5:44 pm โดย Sirayu View Topic SQL JOIN: การรวมข้อมูลจากหลายตารางในฐานข้อมูล
PHP การเปลี่ยนแปลงที่สร้างปรากฏการณ์ในโลกของเว็บ
โดย witsarutt000 พฤ 14 มี.ค. 2024 11:17 am บอร์ด PHP Knowledge
0
180
พฤ 14 มี.ค. 2024 11:17 am โดย witsarutt000 View Topic PHP การเปลี่ยนแปลงที่สร้างปรากฏการณ์ในโลกของเว็บ
ปัญหา Harddisk ขึ้น 100% เวลาเซฟไฟล์ หรือภาพ จะค้่างที่หน้าแท๊บ Expolorer
โดย Thanavat_n พ 13 มี.ค. 2024 11:02 am บอร์ด ถาม - ตอบ คอมพิวเตอร์
5
416
พ 13 มี.ค. 2024 1:34 pm โดย Thanavat_n View Topic ปัญหา Harddisk ขึ้น 100% เวลาเซฟไฟล์ หรือภาพ จะค้่างที่หน้าแท๊บ Expolorer
ตู้รองเท้า ไอเท็มวิเศษช่วยจัดระเบียบคอลเลกชันรองเท้าคู่โปรด
โดย @Foretoday อ 12 มี.ค. 2024 1:46 pm บอร์ด พูดคุยเรื่องทั่วไป จับฉ่าย
0
226
อ 12 มี.ค. 2024 1:46 pm โดย @Foretoday View Topic ตู้รองเท้า ไอเท็มวิเศษช่วยจัดระเบียบคอลเลกชันรองเท้าคู่โปรด
แนะนำสถานที่น่าเที่ยวในจังหวัดชุมพรพร้อมวิธีการเดินทาง
โดย witsarutt000 จ 11 มี.ค. 2024 6:14 pm บอร์ด พูดคุยเรื่องทั่วไป จับฉ่าย
0
177
จ 11 มี.ค. 2024 6:14 pm โดย witsarutt000 View Topic แนะนำสถานที่น่าเที่ยวในจังหวัดชุมพรพร้อมวิธีการเดินทาง
ย้าย VM ข้าม Host ด้วย scp กรณีศึกษา Vmware ESXI
โดย mindphp อ 10 มี.ค. 2024 4:36 am บอร์ด Linux - Web Server
0
272
อ 10 มี.ค. 2024 4:36 am โดย mindphp View Topic ย้าย VM ข้าม Host ด้วย scp กรณีศึกษา Vmware ESXI
IP และ vpn (VMware)
โดย ballmykids อ 10 มี.ค. 2024 2:35 am บอร์ด ถาม - ตอบ คอมพิวเตอร์
2
230
จ 11 มี.ค. 2024 3:19 pm โดย ballmykids View Topic IP และ vpn (VMware)
แบบนี้ต้องทำยังไง ในกรณีที่ Server เดิมเราได้ทำการ Raid 1 กับ HDD 2 ลูกแรกแล้ว
โดย Anonymous ศ 08 มี.ค. 2024 7:02 am บอร์ด ถาม - ตอบ คอมพิวเตอร์
1
190
ศ 08 มี.ค. 2024 8:12 pm โดย mindphp View Topic แบบนี้ต้องทำยังไง ในกรณีที่ Server เดิมเราได้ทำการ Raid 1 กับ HDD 2 ลูกแรกแล้ว