ตารางเดี่ยวที่มีคอลัมน์เพิ่มเติมเทียบกับหลายตารางที่ทำซ้ำสคีมา


13

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

ฉันกำลังสร้างแอปพลิเคชั่นข้อมูลกีฬาที่สามารถรองรับกีฬาหลายประเภท เราสามารถจัดการ NBA, NHL, MLB, NFL ได้ แต่ละกีฬามีแนวคิดที่คล้ายกันมาก - ทีม, ตารางเวลา, การบาดเจ็บ, ข้อมูลผู้เล่น ..

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

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

ผลลัพธ์คือ schema ที่ซ้ำกันในหลายตารางและอินเทอร์เฟซที่ซ้ำซ้อนกับฐานข้อมูล (เช่น procs ที่เก็บไว้) เช่นกัน ฉันมีบางอย่างเช่น NBA_Game, NFL_Game, NBA_Team, NFL_Team และอื่น ๆ แต่ละตารางอาจมีคุณสมบัติบางอย่างที่อีกคนหนึ่งไม่ได้และอีกหลายคนที่ใช้ร่วมกัน มันพูดต่อไปประมาณ 5-10 ตารางจาก 4 หรือ 5 กีฬา ฉันยังไม่แน่ใจว่านี่เป็นสิ่งที่เลวร้ายหรือไม่ - ทางเลือกการมีตารางชุดเดียวซึ่งมีคุณสมบัติอยู่ในนั้นซึ่งไม่ใช่กีฬาทุกประเภทที่จะใช้อาจมีตัวของตัวเองที่เทอะทะเช่นกัน

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

มีทางเลือกอื่นบ้างเช่นการสืบทอดตารางที่คุณเคยใช้ในอดีตที่ใช้งานได้ดีขึ้นหรือไม่

ขอบคุณ

คำตอบ:


12

ในที่สุดมันก็ใช้งานและสถาปัตยกรรมได้

สถาปัตยกรรม

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

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

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

คุณจัดการกับผู้เล่นที่เล่นกีฬาหลายประเภทได้อย่างไร พวกเขาได้รับสองรายการ (เช่นคุณปฏิบัติต่อคนอื่น) หรือคุณกำลังพยายามทำบางสิ่งที่เฉพาะเจาะจงกับพวกเขา

ใช้

ดังนั้นสมมติว่าคุณไม่ได้เล่นกีฬาแบบไดนามิก (เช่นถ้ามีคนต้องการเพิ่มกีฬาใหม่มันต้องใช้ความพยายามในการพัฒนาเพื่อเพิ่ม)

เคยมีเวลาที่คุณแสดงผู้เล่น (หรือวัตถุอื่น ๆ ที่คุณพูดถึง) จากกีฬามากกว่าหนึ่งรายการในแต่ละครั้งหรือไม่?

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

หากคุณไม่จำเป็นต้องทำสิ่งนี้แสดงว่าแนวทางของคุณสมบูรณ์แบบที่สุด คุณสามารถหยุดอ่านได้ที่นี่

Schemas ทางเลือก

เข้าชม

ฉันเป็นแฟนของ KISS ในการพัฒนาซอฟต์แวร์ 15 ปีขึ้นไปฉันยังคงถอยกลับไปสู่ปรัชญา "สร้างสิ่งที่ง่ายที่สุดที่ทำงาน"

ดังนั้นปฏิกิริยาเริ่มต้นของฉันโดยสมมติว่าฟังก์ชั่นการค้นหาข้ามกีฬาเป็นกรณีใช้งานจริง ๆ เท่านั้นคือการสร้างมุมมอง:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

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

ฉันพยายามที่จะให้ทุกสิ่งที่กีฬาเฉพาะในความหมายดูเพื่อค้นหารหัสไม่จำเป็นต้องมีมากหรือรหัสเฉพาะเจาะจงใด ๆ (นอกจากอาจจะรู้วิธีการเชื่อมโยงไปยัง/nhl/players/player-nameVS /nfl/...หรือ แต่แอปของคุณไม่ว่า)

การสืบทอดของตาราง

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

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

แยกตารางสำหรับแอตทริบิวต์เฉพาะกีฬา

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

คู่ค่าคีย์สำหรับแอตทริบิวต์เฉพาะกีฬา

วิธีทางเลือกสมบูรณ์: มีplayersตาราง (อีกครั้งที่มีลักษณะที่เหมือนกันเช่นชื่อ) แล้วplayer_dataตารางที่มีPlayerId, Sport, ,Attribute Valueชื่อแอตทริบิวต์ที่ป้อนจะเป็นแบบเฉพาะกีฬา วิธีนี้ช่วยให้คุณสามารถเพิ่มแอตทริบิวต์ใหม่โดยไม่ต้องแก้ไข schema (รหัสของคุณยังคงต้องรู้เพื่อโหลด / แสดงพวกเขาแน่นอน) ข้อเสียคือคุณสูญเสียความถูกต้องบางอย่าง: โดยทั่วไปค่าจะเป็นเขตข้อมูลสตริงดังนั้นรหัสแอปของคุณจะต้องยืดหยุ่นและจัดการกับความล้มเหลวที่อาจเกิดขึ้นการแปลงสตริงvalueเป็นประเภทข้อมูลเฉพาะ (เช่นจำนวนเต็ม)

แน่นอนว่าแนวคิดนี้สามารถนำไปใช้กับทีมเกมและอื่น ๆ


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

5

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

บนพื้นผิวตัวอย่างของคุณดูคล้ายกันในแนวคิด (X_Game vs Y_Game และ X_Team vs Y_Team) ที่ค่าใช้จ่ายส่วนเกินของคอลัมน์สองสามคอลัมน์นั้นดูไม่สมเหตุสมผล ที่กล่าวว่าหากกีฬาแต่ละรายการจะเพิ่มคอลัมน์พิเศษหลายสิบคอลัมน์ในตารางมันจะแน่นอนเทอะทะ

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

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}

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

แน่นอน - นี่เป็นเพียงแบบจำลองโครงกระดูกเพื่อแสดงให้เห็นถึงความสัมพันธ์หลักและตัวอย่างของสิ่งที่อาจเป็นข้อมูลทั่วไปเทียบกับข้อมูลเฉพาะกีฬา
Midnotion
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.