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

หรือติดต่อเข้ามาทาง Inbox ที่ เฟซบุ๊ค ผมครับ

หน้าหลัก
ข่าวสาร - บทความ ทั้งหมด
VB 6/VB.Net
ASP/ASP.Net
จับฉ่ายคอมพิวเตอร์
เรียนรู้ผ่าน Flash Movie
บทความที่มีผู้ตอบล่าสุด  
 RSS Feeds
 ดาวน์โหลดโปรแกรม RSS Reader ได้ที่นี่ ...   Download โปรแกรม RSS Reader

Forum - www.g2gnet.com
Webmaster - www.g2gnet.com
Visitors - Session views
 5 1 2 8 4 6 3

7 ธันวาคม พ.ศ.2549
243 Users On-Line.
Visitors - Page views
 8 4 2 4 5 0 2
1 กุมภาพันธ์ พ.ศ.2551

Google   
เว็บ g2gnet.com
ขนาดตัวอักษร:  

เรียนรู้ Visual Basic 6.0 กับ ฐานข้อมูล MS Access ภาค 11/1

Category »  VB 6/VB.Net
โดย : Webmaster เมื่อ 29/11/2550 14:59:00
(อ่าน : 27616) 

สำหรับในภาคนี้ มันจำเป็นอย่างยิ่งที่เราต้องมาทำความความใจกับการออกแบบตารางข้อมูล (Table) กันให้ดีเสียก่อน เพราะเป็นเรื่องที่พี่น้องหลายต่อหลายคนมองข้ามมันไป ถ้าหากเราออกแบบตารางผิดเพี้ยนไป (หรือแม้แต่ตอนที่อยากจะพัฒนาปรับปรุงโปรแกรมของตัวเอง) เราก็ต้องตามมานั่งแก้โค้ดในตัวโปรแกรมตามไปด้วยเสมอ มันไม่ง่ายนัก และ ไม่สนุกเอาซ่ะเลยหรอกครับ ... พี่น้อง อนึ่ง ... อันไหน Field, Record, Entity หรือ Attribute ผมไม่ขอกล่าวถึง เพราะว่าทุกท่านสามารถหาอ่านได้โดยทั่วไป แต่ผมจะว่าไปถึงเรื่องที่ไม่มีใครเคยกล่าวถึงมาก่อน ... โปรดเข้าใจ และ เห็นใจในตัวกระผมด้วยน่ะครับ เหอๆๆๆๆๆ
คำเตือน
บทความนี้จะได้ผลอย่างเต็มที่ ก็ต่อเมื่อพี่น้องต้องปลดเปลื้องพันธนาการจากหลักการ และ ทฤษฎีที่พี่น้องเคยได้เห็น เคยได้ยินมา ออกจากความคิดไปก่อนด้วยน่ะครับ 55555 ...


การออกแบบ Flow Control เพื่อควบคุมลำดับการทำงานของโปรแกรม
เอาไว้ให้ดูไปพลางๆก่อน ... ตอนต่อไปจะไล่เรียงการทำงานในแต่ละขั้นตอนให้พี่น้องได้ทราบ


ตารางฐานข้อมูล ... ต้นแบบ

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


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

ความหมายของคำว่า ...
"สิ่งที่เหมือนกันให้ตัดออก"
นั่นก็คือลองพิจารณาจากฟิลด์ ProductGroupName (กลุ่มสินค้า) ในตารางต้นแบบ เราจะพบว่ามันมีโอกาสซ้ำๆกัน หรือ เหมือนกันได้หลายครั้ง ดังนั้นผมจะทำการตัดฟิลด์นี้ออกจากตารางต้นแบบ เพื่อนำไปสร้างเป็นตารางขึ้นมาใหม่ โดยให้ชื่อว่าตาราง tblProductGroup และจากตารางตัวนี้ผมจะทำการสร้าง Primary Key หรือชื่อฟิลด์ว่า PK เพื่อสื่อให้พี่น้องได้เห็นว่านี่คือ "คีย์หลักของตารางนี้ ... ไม่ได้เกี่ยวข้อง หรือ เป็นคีย์หลักให้กับตารางอื่น" แน่นอนครับเจ้า PK นี้จะต้องกำหนดไว้ให้เป็นแบบเลขจำนวนเต็มด้วย ทีนี้ลองย้อนกลับมาที่ตารางต้นแบบ ผมก็จะทำการเพิ่มฟิลด์เข้าไปใหม่โดยให้ชื่อว่า ProductGroupFK และเป็นเลขจำนวนเต็มด้วย
เจตนาของผมก็คือ ...
"สิ่งที่ตัดออกไปก็ดึงมันเข้ามาเชื่อมต่อความสัมพันธ์กันเข้าไปใหม่"
การเชื่อมต่อความสัมพันธ์ หรือ Relative มันก็คือ การใช้คีย์รอง - Foreign Key (ProductGroupFK) จากตารางหลัก - Master (ในที่นี้ คือ tblProduct ซึ่งมันมีคีย์หลักอยู่แล้ว คือ PK) เชื่อมโยงไปหาคีย์หลัก - Primary Key (PK) ของตารางย่อย - Detail (ในที่นี้ คือ tblProductGroup) และเป็นการใช้งาน "ชนิดของข้อมูล - Data Type" แบบเดียวกัน นั่นคือ 1 = 1 หรือ 2 = 2 แต่ว่า 1 = "1" แบบนี้ถือว่าไม่ถูกต้อง ... มองออกมั้ยครับ ... พี่น้อง

การสร้างความสัมพันธ์ของตารางข้อมูล

มาถึง ณ จุดนี้บางท่านก็งงล่ะซิ ไหงชื่อฟิลด์ที่ใช้เชื่อมโยงมันถึงมีชื่อต่างกัน ???
  • ไม่จำเป็นต้องมีชื่อเหมือนกันครับพี่น้อง ... เราเป็นคนออกแบบเอง เราก็ต้องรู้เองนั่นแหละว่าเราจะเอาตัวไหน ไปเชื่อมกับตัวไหน ในกรณีตัวอย่างนี้ผมถึงได้ตั้งชื่อของ Foreign Key ให้มันลงท้ายด้วย FK ส่วน Primary Key ก็จะมีอยู่แล้วในทุกๆตารางก็จะให้ชื่อว่า PK (เวลาตั้งชื่อฟิลด์ต่างๆก็ให้มันสอดคล้อง หรือ ใกล้เคียงกันหน่อยน่ะครับ)
  • สิ่งที่สำคัญ ... โปรดฟังซ้ำ "ชนิดของข้อมูล" จะต้องให้เหมือนกัน หากเรากำหนดให้มันเป็น Number ก็จะต้องเป็น Number ทั้งคู่ แต่ต้องเลือกเอาว่าจะเป็น Byte, Integer หรือ Long Integer อีกต่างหาก เกณฑ์การเลือกก็ให้คิดง่ายๆว่า ปริมาณข้อมูลของตารางย่อยนั้นๆ ทั้งในวันนี้ หรือ อนาคต จะมีความเป็นไปได้ในการจัดเก็บข้อมูลมากน้อยแค่ไหน เช่น กลุ่มสินค้ามันสามารถมีค่าเกิน 255 ค่าหรือไม่ หากไม่เกินเราก็กำหนดเป็น Byte ก็เพียงพอ แล้วเราจะรู้ค่าสูงสุดจากชนิดข้อมูลได้ไงล่ะ ... เอ้า ก็เปิด Help ดูซิครับพี่น้อง หรือ แบบง่ายๆที่ผมจะสรุปให้ฟัง คือ
    • 1 Byte มีขนาด 8 บิต กระจายเป็นเลข Binary (แบบไม่คิดเครื่องหมาย) ให้ค่าสูงสุดคือ 1 1 1 1 1 1 1 1 หรือ 128+64+32+16+8+4+2+1 = 255 (0 - 255 ในเลขฐาน 10)
    • 2 Byte มีขนาด 16 บิต หรือ Integer (แบบคิดเครื่องหมาย) มีค่าระหว่าง -32,768 ถึง 32,767 (หรือมีจำนวน 65536 ค่าในเลขฐาน 10)
    • 4 Byte มีขนาด 32 บิต หรือ Long integer (แบบคิดเครื่องหมาย) มีค่าระหว่าง -2,147,483,648 ถึง 2,147,483,647
      ณ มหาวิทยาลัยถุงก็อบแก็บ ...
      ครู : เอ้า ... นักศึกษา ค่าต่ำสุด หรือ ค่าสูงสุดเหล่านี้เราจะหามาได้ยังไง ????
      นักศึกษา (ตอบทันที) : ในหนังสือมันมีบอกเอาไว้แล้วไงครับ
      ครู : แล้วในหนังสือบอกว่าไงบ้างล่ะ
      นักศึกษา (ตอบอีกทันที) : เลขจำนวนเต็ม Integer ให้คิดเครื่องหมาย จะมีค่าระหว่าง -32,768 ถึง 32,767 ... (พร้อมๆกับคิดไปว่าครูต้องเอามาออกข้อสอบเป็นแน่แท้ อิอิอิ)
      ครู : เก่งมากทุกๆคน ...
      เฮ้อ ... เรื่องตลกน่ะ แต่ขำไม่ออกหรอก ... อ่านเรื่อง>วิธีการคิดกับตัวเลขจำนวนเต็ม ... ที่นี่ ...
    เรื่องของ "ชนิดข้อมูล" นี่เป็นเรื่องที่สำคัญมาก เพราะไม่เพียงแต่เราต้องมากำหนดไว้ในตารางข้อมูลแล้ว มันยังรวมไปถึงตอนที่เราเขียนโปรแกรมขึ้นมา เราก็ยังต้องประกาศชนิดของตัวแปรในการใช้งานมันอีกด้วย นี่ยังไม่ได้รวมกับเหล่าบรรดา Component ทั้งหลายแหล่น่ะครับ โปรแกรมของคุณจะใหญ่เทอะทะ หรือ เล็กกระจิ๋วริ๋ว มันก็อยู่ตรง ณ จุดนี้ด้วย เพราะเวลาที่ผู้ใช้งานเริ่มรันโปรแกรม สิ่งต่างๆเหล่านี้จะต้องถูกโหลดเข้าสู่หน่วยความจำหลัก (RAM) เสมอ นั่นก็หมายถึงการรับประทาน "ทรัพยากรระบบ - Resource" ที่อาจจะเพิ่มมากขึ้นตามไปด้วย สิ่งนี้เราถึงเรียกมันว่าเป็นการ "Optimized" ซึ่งเป็นกระบวนการที่ต้องทำมาทั้งในระหว่างการออกแบบ ไปยันระหว่างการเขียนโปรแกรมด้วย และ การที่กระผมเองได้ทำแยกตารางออกจากกัน ก็สืบเนื่องมาจากเหตุผลอันเดียวกันนี่เอง ... ประเดี๋ยวจะไปสรุปให้ฟังทางด้านท้ายครับ ... พี่น้อง
    พี่น้องครับ ... ลำพังเพียงแค่นี้มันยังไม่สามารถสร้างความร้าวฉาน เอ๊ย ความสัมพันธ์ขึ้นมาได้หรอก ถ้าหากพี่น้องยังไม่ได้ทำการสร้าง SQL Statement ให้กับตารางข้อมูลทั้งสอง วิธีการก็สุดแสนจะง่ายดาย ... โดยการเปิดจาก Query (หรือแบบสอบถาม) ที่อยู่ใน MS Access ขึ้นมาใช้งาน และ เลือกการสร้างแบบสอบถามในมุมมองออกแบบ จากนั้นก็ให้เลือกตารางที่เราต้องการเข้ามาเพื่อทำการสร้างความสัมพันธ์ให้กับมัน

    การสร้างความสัมพันธ์ - Query จาก MS Access
    โดยการใช้เมาส์ซ้ายไปคลิ๊กที่ ProductGroupFK ในตาราง tblProdcut จากนั้นลากไปใส่ไว้ที่ PK ในตาราง tblProductGroup มันก็จะเกิดเป็นเส้นสีดำขึ้นมา หรือ เกิดเป็นความสัมพันธ์ระหว่างฟิลด์ทั้งสองเข้าหากันอย่างสมบูรณ์


    ผลลัพธ์ที่ได้ ให้สังเกตว่าค่าของ ProductGroupFK จะมีค่าเท่ากับ PK ในตาราง tblProductGroup ... นี่แหละเราถึงได้เรียกว่า "ความสัมพันธ์"


    SQL Statement โดยใช้ Query จาก MS Access
    พี่น้องครับ ... เวลาที่ผมต้องการจะใช้งาน SQL Statement ผมไม่นิยมมานั่งเขียนประโยคคำสั่งเอาเองหรอก ... เพราะผมนิยมใช้เครื่องทุ่นแรง อย่างเจ้า MS Access นี่แหละครับกระผม

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

    การออกแบบในลักษณะ Master - Detail นั่นคือ เราจะพิจารณาจากตารางหลัก (tblProduct) เท่านั้น
    เห็นมั้ยครับว่า ตารางย่อย (Detail) ของทุกๆตารางมันก็มี Primary Key (PK) ประจำของมัน ... ก็เจ้านี่แหละมันจะเป็นตัวเชื่อมความสัมพันธ์ไปยังตารางหลัก (Master) เสมอ

    จากหลักการนี้ มันก็จะนำทางเราไปยังโครงสร้างฐานข้อมูลที่ซับซ้อนขึ้น ... เช่นแบบนี้

    ตัวอย่างงานจริง โดยผมจะพิจารณาจากตาราง tbl_AR_Invoice เป็น Master ... ตัวอื่นๆมันคือ Detail

    ภาพที่แสดงให้เห็นทางด้านบนนี้น่ะครับ ... เป็นภาพรวมของรายการขายสินค้าที่ ซึ่งผมมองมาจากตาราง tbl_AR_Invoive เป็นตารางหลัก (Master) หรือ หากเราจะพิจารณาแยกย่อยลงไปอีก โดยเพ่งเล็งไปที่ตาราง tbl_AR_InvoiceDetails เป็นหลัก ก็จะได้ดังนี้

    มองจากตาราง tbl_AR_InvoiceDetails เป็น Master แทน


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

    อนึ่งโปรดสังเกตว่าผมไม่ได้กล่าวอ้างถึงความสัมพันธ์ในประเภท One-To-One, One-To-Many หรือ Many-To-Many เลยสักกะตัวเดียว เหตุผลเหรอครับ ... ก็เพราะเราจับแยกข้อมูลในตารางออกจากกัน และ ใช้คีย์เชื่อมความสัมพันธ์กันเข้าไปแล้วนี่นาครับ .... พี่น้อง มันก็เลยทำให้ไม่ต้องมาพะวง ไม่ต้องงง ไม่ต้องมาสับสนกะเรื่องพวกนี้ จะว่าไปแล้วมันกลับกลายเป็นเรื่องของ "ธรรมชาติ" ไปในตัวมันเองน่ะซิครับ ... Amazing จริงๆครับพี่น้อง 55555
    พอมาถึงตรงนี้ ... หลายคนก็คงมีคำถามว่าทำไมต้องกระจายตารางข้อมูลกันระเบิดเถิดเทิงอย่างนี้ ... ???
      ประโยชน์ในการแยกย่อยตาราง ...
    1. เพื่อให้ถูกต้องตามทฤษฎีของการทำ Normalization ... ประเดี๋ยวท่านนักวิชาการทั้งหลายจะต่อว่าเอา ... (ประชดใครบางคน น่ะจ๊ะตัวเอง ... อิอิอิ)
    2. เพื่อลดขนาดของข้อมูลลง หรือ การ Optimized ตัวฐานข้อมูลเอง
    3. เพื่ออำนวยความสะดวกต่อผู้ใช้งาน ... ไม่ใช่วันหนึ่งๆต้องมานั่งคีย์ข้อมูลซ้ำๆซากๆ แถมคีย์ผิด คีย์ถูกอีกต่างหาก เพราะพี่โปรแกรมเมอร์ (มั่ว) แกเล่นออกแบบให้เก็บข้อมูลที่มีแต่ TextBox เต็มพรืดไปซ่ะหมด ... เหอๆๆๆๆ ... เศร้า
    4. เพื่อความถูกต้องของข้อมูล ... คือ คีย์ข้อมูลเข้าไปเพียงครั้งเดียว หากมันผิดเช่น CPU มันมีหน่วยนับเป็นตัว แต่ผู้ใช้งานกลับพิมพ์เป็นเครื่อง หากเราแก้ก็แก้ที่ตารางย่อย (tblUnit) เพียงที่เดียว ไม่ใช่ต้องตามไปแก้ในตารางสินค้า ตารางการซื้อ หรือ การขายทั้งหมด ... ใช่หรือเปล่าล่ะครับพี่น้อง
    5. มีความยืดหยุ่น สามารถขยายระบบได้ในอนาคต
    6. อื่นๆ ... แต่ตอนนี้คิดไม่ออก 55555
    พี่น้องครับ ผมขอเรียนให้ทราบอีกเรื่องหนึ่ง (ซึ่งในตำราที่พี่น้องกอดไว้แนบอก จะไม่ยอมบอกเอาไว้) ได้เลยว่า "เราออกแบบฐานข้อมูลอย่างไร เราก็ต้องเขียนโปรแกรมตามนั้น" ... แหละนี่คือปัญหาสำหรับผู้ที่คิดอยากจะเรียนรู้ทั้งหลาย ... คือให้ออกแบบตารางฐานข้อมูลน่ะก็ (พอ) ทำได้ แต่มันจะเขียนโปรแกรมขึ้นมาควบคุมลำดับการทำงานได้ยังไงน่ะซิ ... ถูกต้องมั้ยคร้าบบบบบบบบ ...
    Conclusion:
    ผมก็เป็นคนหนึ่งล่ะที่อยู่ภายใต้กฏเกณฑ์ของธรรมชาติ ไม่ว่าจะร้อน หนาว เกิด แก่ เจ็บ ตาย อย่างหลีกเลี่ยงไม่ได้ แต่ทว่าการเรียนรู้ของผม ผมไม่ยอมอยู่ภายใต้กรอบ กฏเกณฑ์ กติกา หรือ ทฤษฎีเลย สิ่งที่เรียนรู้เราก็ต้องมาลองเทียบเคียง หาคำอธิบายให้กับตัวเอง หรือ หัดคิดนอกกรอบ กันดูมั่ง ไม่ใช่แต่จะต้องใช้ประโยคอมตะ "เขาว่ากันว่า ..." มันจะไม่มีอะไรสักเรื่องเลยเหรอในชีวิตที่เราจะถามกับตัวเราเอง ... "หากทำอย่างนี้แล้ว มันจะมีผลอย่างไรล่ะ ???"

     

    เมื่อเราออกแบบฐานข้อมูลได้แล้ว ขั้นตอนต่อไปก็ต้องมาเขียนโปรแกรมตามที่เราออกแบบไว้ ... ประเดี๋ยวพี่น้องจะหงุดหงิดคิดว่าผมจะมาบ้าแต่ทฤษฎี (ของผม) ก็ลองดาวน์โหลดเอาตัวอย่างไปเพ่งกระแสจิตดูกันเล่นๆไปก่อนเถิด รอบหน้าผมจะมาสาธยายต่อครับผม ... (อันที่จริงในตัวอย่างผมมี Comment แทบจะทุกช็อตครับ)

    ดาวน์โหลด Source Code สำหรับ MS Visual Basic 6.0 - Service Pack 6
     ดาวน์โหลด Visual Basic 6.0 SP5: Run-Time Redistribution Pack
     ดาวน์โหลด Microsoft Data Access Object (MDAC) และ Jet 4.0 Update

  • จี ทู จี เน็ต ดอต คอม - g2gNet Dot Com
    เลขทะเบียนพาณิชย์อิเล็กทรอนิกส์ 0407314800231
    CopyLeft © 2004 - 2099 g2gNet.Com All rights reserved.
    Email: [email protected] หรือ โทร. 08-6862-6560