โอกาสในการออกแบบฐานข้อมูลใหม่: การออกแบบตารางใดที่จะใช้สำหรับการรวบรวมข้อมูลเซ็นเซอร์นี้


13

พื้นหลัง

ฉันมีเครือข่ายเซ็นเซอร์ประมาณ 2,000 ตัวซึ่งแต่ละตัวมีจุดข้อมูลประมาณ 100 จุดที่เรารวบรวมในช่วงเวลา 10 นาที จุดข้อมูลเหล่านี้มักจะเป็นค่า int แต่บางจุดเป็นสตริงและลอย ข้อมูลนี้ควรเก็บไว้ 90 วันหากเป็นไปได้และยังมีประสิทธิภาพ

การออกแบบฐานข้อมูล

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

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

สำหรับรุ่นถัดไปฉันเปลี่ยนเป็น Microsoft SQL Server Express และวางข้อมูลเซ็นเซอร์ทั้งหมดลงในตารางขนาดใหญ่หนึ่งตาราง นอกจากนี้ยังใช้งานได้และช่วยให้เราสามารถสอบถามเพื่อค้นหาค่าในเซ็นเซอร์ทั้งหมดที่น่าสนใจ อย่างไรก็ตามฉันวิ่งเข้าไปในขีด จำกัด 10GB สำหรับเวอร์ชัน Express และตัดสินใจที่จะเปลี่ยนกลับเป็น MySQL แทนที่จะลงทุนใน SQL Server Standard

คำถาม

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

ฉันควรแยกตารางนี้ออกเป็นบางวิธีเพื่อเพิ่มประสิทธิภาพหรือไม่ หรือเป็นเรื่องปกติที่จะมีโต๊ะขนาดใหญ่แบบนี้หรือไม่?

ฉันมีดัชนีในคอลัมน์ ID เซ็นเซอร์และการประทับเวลาซึ่งค่อนข้างเป็นขอบเขตที่กำหนดไว้สำหรับการค้นหาใด ๆ (เช่นรับข้อมูลสำหรับเซ็นเซอร์ X จากเวลา A ถึงเวลา B)

ฉันได้อ่านนิดหน่อยเกี่ยวกับการแบ่งและการแบ่งพาร์ติชัน แต่ไม่รู้สึกว่าเหมาะสมในกรณีนี้


แก้ไข:

จากความคิดเห็นและคำตอบจนถึงตอนนี้ข้อมูลเพิ่มเติมบางอย่างอาจมีประโยชน์:

ไม่ใช่ที่เก็บข้อมูลไม่ จำกัด :ปัจจุบันฉันไม่เก็บข้อมูลในช่วง 90 วันที่ผ่านมา ทุกวันฉันเรียกใช้คิวรีที่ลบข้อมูลที่เก่ากว่า 90 วัน ถ้ามันกลายเป็นสิ่งสำคัญในอนาคตฉันจะเก็บมากขึ้น แต่ตอนนี้มันเพียงพอแล้ว สิ่งนี้จะช่วยให้ขนาดในการตรวจสอบและประสิทธิภาพสูง (เอ้อ)

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

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

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


แก้ไข 2:

การใช้ข้อมูล:ในที่สุดข้อมูลส่วนใหญ่ไม่เคยถูกมองหรือจำเป็นเนื่องจากเรามักจะมุ่งเน้นเฉพาะรายการที่มีปัญหาเท่านั้น แต่ในการพยายามค้นหาปัญหาเราใช้เครื่องมือต่าง ๆ เพื่อค้นหาข้อมูลและกำหนดรายการที่จะซูมเข้า

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

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

SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);

(ในเวอร์ชั่น MySQL ดั้งเดิมที่เซ็นเซอร์แต่ละตัวมีตารางของตัวเองจะมีการออกแบบสอบถามสามแบบแยกกัน แต่จะรวมผลลัพธ์ในซอฟต์แวร์เพื่อสร้างกราฟ)

เนื่องจากdataตารางมีแถวจำนวนมาก (~ 10 ล้าน) แม้จะมีดัชนีidและdata_timestampประสิทธิภาพก็ยิ่งแย่กว่าสถานการณ์หลายตาราง (4500 แถวส่งกลับใน 9 วินาทีเมื่อเทียบกับตัวอย่างนี้น้อยกว่าหนึ่งวินาที) ความสามารถในการค้นหาเซ็นเซอร์ที่ตรงตามเกณฑ์บางอย่างนั้นจริงแล้วเป็นศูนย์ในสคีมาหลายตารางและทำให้เหตุผลในการย้ายไปยังตารางเดียว

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

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

หวังว่าข้อมูลนี้จะช่วยแสดงให้เห็นอย่างชัดเจนว่ามีการใช้ข้อมูลอย่างไรหลังจากรวบรวมและจัดเก็บข้อมูล


สำหรับคำถามนี้เพื่อให้ได้คำตอบที่ถูกต้องคุณควรขยายวิธีการใช้ข้อมูลจริง คุณนำหน้าเส้นโค้งที่ความลึกของข้อมูลที่คุณให้ไว้จนถึงตอนนี้ แต่คุณอาจถามคำถามของคุณจากมุมที่ผิด
Mark Storey-Smith

จุดดี @ Mark ฉันจะทำอย่างละเอียดเกี่ยวกับที่เช่นกัน ฉันพยายามไม่ตั้งคำถามนานเกินไปเพราะกลัวว่าจะท่วมท้น
JYelton

คำตอบ:


5

คุณควรคิดถึงการแบ่งตารางด้วยเหตุผลใหญ่ ๆ

ดัชนีทั้งหมดที่คุณมีบนตารางยักษ์แม้เพียงหนึ่งดัชนีสามารถสร้างภาระของ CPU และดิสก์ I / O จำนวนมากเพื่อทำการบำรุงรักษาดัชนีเมื่อดำเนินการ INSERTs, UPDATE และ DELETE

ฉันเขียนโพสต์ก่อนหน้านี้เมื่อวันที่ 7 ตุลาคม 2011ว่าทำไมการแบ่งพาร์ทิชันของตารางจึงเป็นประโยชน์อย่างมาก นี่คือข้อความที่ตัดตอนมาจากโพสต์ที่ผ่านมาของฉัน:

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

คุณสามารถอ่านโพสต์ทั้งหมดของฉันได้ในภายหลัง

เพื่อตัดสิทธิ์ในการไล่ล่าคุณต้องค้นคว้าและหาข้อมูลที่ไม่ค่อยได้ใช้ในตาราง 10GB ของคุณ ข้อมูลนั้นควรอยู่ในตารางเก็บถาวรที่สามารถเข้าถึงได้ง่ายหากคุณต้องการคำสั่ง adhoc สำหรับประวัติในอดีต การโอนย้ายไฟล์เก็บถาวรนั้นจาก 10GB ตามด้วยOPTIMIZE TABLEบนตาราง 10GB สามารถส่งผลให้ชุดการทำงานที่เร็วกว่าในการรัน SELECTs, INSERTs, UPDATEs และ DELETE แม้แต่ DDL ก็สามารถทำงานได้เร็วขึ้นในชุดการทำงาน 2GB มากกว่าตาราง 10GB

อัพเดท 2012-02-24 16:19 EDT

สองจุดที่ต้องพิจารณา

  1. จากความคิดเห็นของคุณดูเหมือนว่าการทำให้ปกติเป็นสิ่งที่คุณต้องการ
  2. คุณอาจต้องย้ายข้อมูลทุกอย่างที่มีอายุมากกว่า 90 วันไปยังตารางเก็บถาวร แต่ยังคงเข้าถึงการเก็บถาวรและชุดการทำงานในเวลาเดียวกัน หากข้อมูลของคุณคือ MyISAM ทั้งหมดฉันขอแนะนำให้ใช้เครื่องมือเก็บข้อมูล MERGE ขั้นแรกให้คุณสร้างแผนผังตาราง MERGE หนึ่งครั้งที่รวมชุดตาราง MyISAM ที่ทำงานได้และตารางเก็บถาวร MyISAM คุณจะเก็บข้อมูลน้อยกว่า 91 วันในหนึ่งตาราง MyISAM และวางข้อมูลใด ๆ ที่มีอายุมากกว่า 90 วันในการเก็บถาวร คุณจะค้นหาแผนที่ตาราง MERGE เท่านั้น

นี่คือสองโพสต์ที่ฉันทำเกี่ยวกับวิธีการใช้งาน:

นี่คือโพสต์เพิ่มเติมที่ฉันทำในตารางที่มีคอลัมน์จำนวนมาก

มีคอลัมน์มากเกินไปใน MySQL


มีคอลัมน์ที่จำเป็นน้อยกว่า แต่เซ็นเซอร์ทั้งหมดได้รับความสนใจเท่ากัน ดังนั้นฉันสามารถจินตนาการแยกตารางในแนวตั้งจะได้ประโยชน์ ตัวอย่างเช่นตาราง 20 คอลัมน์ (เข้าถึงบ่อย) และตาราง 80 คอลัมน์ (เข้าถึงไม่บ่อย) ฉันไม่แน่ใจว่านี่เป็นสิ่งเดียวกับการแบ่งพาร์ติชัน
JYelton

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

5

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

90 วันเป็นระยะเวลาตามปกติที่คุณสร้างกราฟหรือไม่ ถ้าเป็นเช่นนั้นคุณอาจมีสองตาราง: ตารางข้อมูลเซ็นเซอร์หลักที่เก็บข้อมูลจาก 90 (หรือมากกว่านั้นเล็กน้อยถ้าคุณต้องการความหย่อนบ้าง) วันที่ผ่านมาจนถึงทุกวันนี้และทุกอย่างที่เก่ากว่านั้นไปในตารางเก็บถาวร สิ่งนี้อาจช่วยลดขนาดของตารางที่รายงานเริ่มสร้างขึ้นและหวังว่าข้อมูลส่วนใหญ่ 10 GB ของคุณจะอยู่ในตารางเก็บถาวรและไม่ใช่ในตารางหลัก งานจัดเก็บลงสื่อถาวรสามารถกำหนดให้ทำงานทุกคืน

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


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

@JYelton: คุณสามารถมีเทียร์ได้มากเท่าที่คุณต้องการ ตารางล่าสุดสามารถมีได้ตั้งแต่วันนี้เท่านั้น ตารางต่อไปอาจมีได้ตั้งแต่วันนี้ถึง 2 สัปดาห์ที่ผ่านมา ตารางถัดไปอาจมีได้ตั้งแต่วันนี้ถึง 90 วันที่ผ่านมา ตารางสุดท้ายสามารถทำได้ทุกอย่าง
FrustratedWithFormsDesigner

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

@Jelelton: ใช่ฉันคิดว่าคุณเข้าใจถูกต้อง หากช่วงเวลาสอบถามเป็นมาตรฐาน (วันนี้ - 1 วัน, วันนี้ - 7 วัน, วันนี้ - 30 วัน, วันนี้ - 90 วัน) ดังนั้นฉันไม่คิดว่ามันจะยากเกินไปเพราะคุณจะรู้ว่าตารางใด ตี. หากช่วงเวลาอาจมีความยาวแตกต่างกันซึ่งจุดเริ่มต้นของช่วงอาจไม่ใช่วันที่ปัจจุบันคุณถูกต้องแล้วว่าตรรกะที่จะนำไปใช้จะได้รับความยุ่งยากและแบบสอบถามที่ข้ามตารางอาจมีราคาแพงด้วยการดำเนินงานของ UNION ในหลายตาราง
FrustratedWithFormsDesigner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.