จะสร้างตารางแยกต่างหากสำหรับผลิตภัณฑ์ประเภทต่างๆหรือไม่?


25

ฉันกำลังออกแบบฐานข้อมูลและฉันมีความคิดที่สองเกี่ยวกับการตัดสินใจออกแบบเริ่มต้นของฉัน ...

ประเภทสินค้ามีดังนี้ ... รุ่นชิ้นส่วนชุดอุปกรณ์ทดแทนและตัวเลือก

ตัวเลือก A (การออกแบบครั้งแรก): ฉันวางแผนที่จะมีตารางแยกต่างหากสำหรับผลิตภัณฑ์ประเภทข้างต้น ฉันจะบอกว่าประมาณ 75% ของเขตข้อมูลจะเหมือนกันในแต่ละตาราง

ฉันสร้างผลิตภัณฑ์แต่ละประเภทเป็นตารางแยกเนื่องจากความสัมพันธ์ที่ฉันต้องการสร้างระหว่างแต่ละประเภท ตัวอย่างเช่นรุ่นสามารถมีตัวเลือกมากมายและตัวเลือกสามารถมีหลายรุ่น ตัวเลือกยังสามารถมีได้หลายส่วนและส่วนหนึ่งสามารถมีตัวเลือกมากมาย ... และอื่น ๆ ...

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

ตัวเลือก B จะช่วยลดความซับซ้อนของการออกแบบฐานข้อมูลได้อย่างมาก ฉันไม่ต้องกังวลเกี่ยวกับการอ้างอิงกลุ่มของตารางเมื่อดึงข้อมูลออกมาเพื่อสอบถาม ...


2
ที่จุดนี้ฉันขอแนะนำให้คุณสร้างสเปรดชีตที่เลย์เอาต์ตารางของคุณและกรอกข้อมูลด้วย สิ่งนี้จะเปิดเผยจุดอ่อนที่อาจมีอยู่
Michael Riley - AKA Gunny

คุณจะชี้กุญแจต่างประเทศไปที่ผลิตภัณฑ์ต่าง ๆ ได้อย่างไรหากอยู่ในตารางที่ต่างกัน โปรดอ่านการสืบทอดของตาราง
Neil McGuigan

คำตอบ:


8

ถ้านี่คือการตัดสินใจออกแบบของฉันฉันอาจจะไปกับ 'ตัวเลือก C' (ตัวเลือกที่ปรับเปลี่ยนก) เพิ่มเติม

ก่อนอื่นทำไมไม่ 'ตัวเลือก B':

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

อีกกลยุทธ์การจัดทำดัชนีจะต้องแสดงรายการเขตข้อมูลนั้นเสมอ เนื่องจากมีเพียง 4 ประเภทดัชนีความเป็นหัวใจต่ำมาก ( SELECT * FROM product_table WHERE type='X'โดยทั่วไปจะทำการสแกนแบบเต็มตาราง)

ตัวเลือก C

  • สร้างตารางหลักที่มีเฉพาะคอลัมน์ที่ทุกประเภทแชร์
  • สร้างแต่ละประเภทผลิตภัณฑ์ตามที่เป็นตารางของตัวเองพร้อมกับคอลัมน์แต่ละอันโดยมีหนึ่งรายการพิเศษ: ลิงก์ไปยังตารางหลัก
  • สร้างตาราง 'ลิงก์' แต่ละรายการ: Product_Option, Model_option ฯลฯ พร้อมลิงก์ไปยังคีย์ที่เกี่ยวข้อง
  • สำหรับผู้ที่มีลิงค์ซึ่งกันและกัน (MODEL_OPTION, OPTION_MODEL) ให้ไปข้างหน้าและสร้างตารางเหล่านั้นเช่นกัน สิ่งนี้จะเพิ่มความชัดเจนในการเข้าร่วมของคุณสำหรับทุกคนที่ดู

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


5
ตอนนี้มีเพียง 4 ประเภท แต่จะเกิดอะไรขึ้นถ้ามีเพิ่มอีกในภายหลัง ฉันแน่ใจว่าตารางผลิตภัณฑ์หลักของ Amazon เดิมเรียกว่า "หนังสือ" แต่คุณคิดว่าพวกเขามีตารางแยกต่างหากสำหรับผลิตภัณฑ์ทุกประเภทตอนนี้หรือไม่ ฉันไม่คิดว่าแต่ละประเภทควรมีตารางของตัวเอง แต่คุณสามารถใช้โมเดล EAV สำหรับคุณสมบัติเพิ่มเติมที่แต่ละประเภทอาจมีร่วมกัน
Aaron Bertrand

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

1
ตัวเลือก C: จำเป็นต้องมีตารางลิงก์หรือไม่ ฉันคิดว่า Product_Option PK จะตรงกับ PK ของตารางผลิตภัณฑ์และนั่นจะสร้างการเชื่อมโยงเพื่อเชื่อมโยงทั้งสองตาราง
จ่ายเงิน

ใช้ Product_option เป็นตัวอย่างสคีมาจะเป็น (ในใจของฉัน): id, productID, optionID productIDจะเป็น FK ไปproduct.idและoptionIDเป็น FK option.idไป นั่นคือสิ่งที่ฉันหมายถึงโดยตารางการเชื่อมโยง และใช่มีความจำเป็นในการออกแบบนี้เพื่ออนุญาตให้ผลิตภัณฑ์เดียวเชื่อมโยงกับตัวเลือกหลายตัว
Derek Downey

โอเคฉันเข้าใจแล้ว. ฉันอ่านผิดที่คุณพิมพ์ .. โอ๊ะโอ
จ่ายเงิน

7

ฉันขอแนะนำให้คุณเริ่มต้นด้วยโมเดลเชิงสัมพันธ์ "ถูกต้อง" ตัวเลือกของคุณ A. หากการใช้งานทั่วไปของโมเดลนั้นนำคุณไปสู่

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

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


2

เสียงนี้คล้ายกันมากกับตั๋วเงินของวัสดุ / หลาย cardinalities heirarcy ที่อธิบายในพอล Neilsen บทที่ 17ของSQL Server 2008 ในพระคัมภีร์

ทั้งบทเป็นบทอ่านที่ดีมากและมีหัวข้อเฉพาะที่กล่าวถึงปัญหาแบบตัวต่อตัวของคุณในหน้า 416-419

นี่คือการอภิปรายที่ดีที่สุดที่ฉันได้เห็นเกี่ยวกับชนิดของชิ้นส่วนที่ถูกระเบิดของการออกแบบข้อมูล


โซลูชันนี้มีลักษณะคล้ายกับตัวเลือก B (หากฉันเข้าใจอย่างถูกต้องซึ่งฉันไม่แน่ใจ) ฉันมีตารางหลัก (ผลิตภัณฑ์) และตาราง "ลิงก์" (หรือที่รู้จักกันในชื่อตาราง / BillsofMaterials) เพื่อสร้างการเชื่อมโยงระหว่างรุ่นตัวเลือกชุดอุปกรณ์ ฯลฯ ถูกต้องหรือไม่
จ่ายเงิน

ฉันคิดว่าปัญหานี้เกิดขึ้นเนื่องจากมีตัวเลือก ให้นำตัวเลือกออกจากการอภิปรายเพียงเล็กน้อย ชิ้นส่วนเป็นหน่วยที่เล็กที่สุด กลุ่มของชิ้นส่วนทำขึ้นแบบ กลุ่มชิ้นส่วนทดแทนในรูปแบบของชุดประกอบขึ้นเป็นชุดย่อยของรูปแบบ จนถึงตอนนี้ดีมาก ตอนนี้ชิ้นส่วนมีตัวเลือกให้สมมติว่ามีความเรียบง่ายนี้ครอบคลุมทั้งสองประเภทสี (ดำ, แดง, โครม) และวัสดุ (โลหะ, ไม้, พลาสติก) คุณยังกล่าวถึงว่ารุ่นมีตัวเลือก ตัวเลือกรุ่นนั้นแยกจากตัวเลือกชิ้นส่วนหรือตัวแบบดูเหมือนจะมีตัวเลือกเท่านั้นเนื่องจากชิ้นส่วนทำให้รุ่นแตกต่างกันหรือไม่?
Michael Riley - AKA Gunny

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

นั่นไม่ใช่วิธีที่คุณใช้คำถามของคุณ ข้อความอ้างอิง: "ตัวอย่างเช่น Model สามารถมีตัวเลือกมากมายและตัวเลือกสามารถมีได้หลายรุ่นตัวเลือกยังมีได้หลายส่วนและส่วนหนึ่งสามารถมีตัวเลือกมากมาย ... และต่อไป ... " ณ จุดนี้ฉันแนะนำให้คุณ สร้างสเปรดชีตที่เลย์เอาต์ตารางของคุณและกรอกข้อมูลด้วยข้อมูล สิ่งนี้จะเปิดเผยจุดอ่อนที่อาจมีอยู่
Michael Riley - AKA Gunny

0

หากคุณสามารถถ่ายภาพสถานการณ์ที่น่าจะเกิดขึ้นซึ่งจะมีการสืบค้นบ่อย ๆ ที่ข้ามประเภทผลิตภัณฑ์ทั้งสี่ (และดูเหมือนว่าจะเกิดขึ้นกับฉัน) แสดงว่าตัวเลือก B ของคุณดีที่สุด

แทนที่จะปล่อยให้ฟิลด์ nullable ที่ไม่ได้ใช้จำนวนมากในตารางผลิตภัณฑ์ทำไมไม่เพิ่มตาราง ModelProduct ตาราง PartProduct ตาราง ReplacementPartKitProduct และมีเพียงฟิลด์ที่แตกต่างกันสำหรับประเภทเหล่านั้นในตารางเหล่านั้น ใช้คีย์หลักเดียวกันในตารางเหล่านั้นเป็นตารางผลิตภัณฑ์ของคุณ เข้าร่วมตารางผลิตภัณฑ์และ ModelProduct เมื่อคุณต้องการทำงานกับรุ่น ต้องการตรวจสอบว่าบันทึกของผลิตภัณฑ์ที่คุณมีนั้นเป็นส่วนหนึ่ง เพียงแค่เข้าร่วมซ้ายจาก Product to PartProduct และถ้า PartProduct [PrimaryKey] ไม่ใช่ null คุณมีส่วน ถ้ามันเป็นโมฆะมันไม่ได้เป็นส่วนหนึ่ง อีกวิธีหนึ่งคุณสามารถเพิ่มเขตข้อมูลชนิดผลิตภัณฑ์ลงในตารางผลิตภัณฑ์


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

ในขณะที่มีหลายปัจจัยที่มีผลต่อการตัดสินใจ "ถูกต้อง" มีสองปัจจัยกว้าง ๆ ที่ควรพิจารณา 1: ข้อกำหนดด้านประสิทธิภาพโดยรวม 2: การปรับตัว / ความซับซ้อน / การบำรุงรักษา หนึ่งในสองนั้นอาจมีความสำคัญมากกว่าอีกเล็กน้อย ถ้าคุณต้องการความเร็วให้ denormalize โดยติดกับ Option A คุณจะมีการทำซ้ำ คาดว่า หากคุณต้องการเล่นซอกับสคีมาเป็นประจำและความเร็วไม่ใช่ปัจจัยที่สำคัญที่สุดตัวเลือกบีคุณจะได้รับ "ถูกต้อง" โดยการรู้ถึงลำดับความสำคัญของคุณไม่ใช่โดยการยึดมั่นใน
Alan McBee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.