การออกแบบฐานข้อมูลและตารางที่ดีที่สุดสำหรับพันล้านแถวของข้อมูล [ปิด]


74

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

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

ข้อมูลที่ฉันต้องการจัดเก็บ (ตอนนี้) คือรหัสสถานที่, เวลาประทับ (วันที่และเวลา), อุณหภูมิและการใช้ไฟฟ้า

เกี่ยวกับปริมาณข้อมูลที่ต้องจัดเก็บนี่เป็นเพียงการประมาณ แต่มีบางสิ่งตามสายเหล่านี้:
20 000+ ตำแหน่ง 720 บันทึกต่อเดือน (วัดรายชั่วโมงประมาณ 720 ชั่วโมงต่อเดือน), 120 เดือน (สำหรับ 10 ปีย้อนหลัง ) และอีกหลายปีในอนาคต การคำนวณอย่างง่ายให้ผลลัพธ์ต่อไปนี้:

20 000 สถาน x 720 x 120 บันทึกเดือน (10 ปีหลัง) = 1 728 000 000 ระเบียน

เหล่านี้เป็นบันทึกที่ผ่านมาบันทึกใหม่จะถูกนำเข้ารายเดือนเพื่อให้เป็นประมาณ 20 000 x 720 = 14 400 000 ระเบียนใหม่ต่อเดือน

ที่ตั้งโดยรวมจะเติบโตอย่างต่อเนื่องเช่นกัน

ในข้อมูลทั้งหมดนั้นการดำเนินการต่อไปนี้จะต้องถูกดำเนินการ:

  1. ดึงข้อมูลสำหรับวันที่และช่วงเวลาที่แน่นอน: บันทึกทั้งหมดสำหรับรหัสสถานที่ตั้งที่แน่นอนระหว่างวันที่ 01.01.2013 และ 01.01.2017 และระหว่าง 07:00 ถึง 13:00
  2. การดำเนินการทางคณิตศาสตร์อย่างง่ายสำหรับวันที่และช่วงเวลาที่แน่นอนเช่น MIN, MAX และ AVG อุณหภูมิและการใช้ไฟฟ้าสำหรับรหัสที่ตั้งที่แน่นอนเป็นเวลา 5 ปีระหว่าง 07:00 - 13:00 น.

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

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

ตัวเลือกหลักของฉันคือ Cassandra และ MongoDB แต่ฉันเนื่องจากฉันมีความรู้ จำกัด และไม่มีประสบการณ์จริงเมื่อพูดถึงข้อมูลขนาดใหญ่และ NoSQL ฉันไม่แน่ใจ ฉันยังอ่านว่า PostreSQL จัดการกับปริมาณข้อมูลดังกล่าวได้ดี

คำถามของฉันมีดังต่อไปนี้:

  1. ฉันควรใช้ฐานข้อมูล NoSQL สำหรับข้อมูลจำนวนมาก ถ้าฉันไม่สามารถติดกับ MySQL?
  2. ฉันควรใช้ฐานข้อมูลใด
  3. ฉันควรเก็บวันที่และเวลาแยกจากกันทำดัชนี (ถ้าเป็นไปได้) เพื่อจัดทำดัชนีและประมวลผลข้อมูลอย่างรวดเร็วสำหรับช่วงเวลาและวันที่ที่กำหนดหรือสามารถทำได้ด้วยการเก็บบันทึกเวลาไว้ในคอลัมน์เดียว?
  4. วิธีการสร้างแบบจำลองข้อมูลอนุกรมเวลามีความเหมาะสมที่นี่หรือไม่และหากคุณไม่สามารถให้คำแนะนำสำหรับการออกแบบตารางที่ดีได้

ขอขอบคุณ.


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

6
ฉันได้จัดเก็บตารางหลาย TB ที่มีหลายสิบพันล้านแถวใน MS SQL Server 2008-2014 โดยใช้คีย์ที่ดี (วันที่ยุค) การบีบอัดการแบ่งพาร์ติชันและมั่นใจว่าคิวรี / ดัชนีของฉันอยู่ในแนวเดียวกันกับพาร์ติชัน ฉันต้องย้ายไปที่ NoSQL (Hadoop) เมื่อฉันเริ่มรับข้อมูลเพตาไบต์เพื่อวิเคราะห์และจัดทำดัชนีแตกต่างกัน NoSQL ควรมีข้อควรพิจารณาอื่น ๆ และในกรณีนี้ดูเหมือนจะไม่เหมาะสม
Ali Razeghi

3
@AliRazeghi Hadoop ไม่มีส่วนเกี่ยวข้องกับ SQL หรือ NoSQL - เป็นเพียงเครื่องมือเก็บข้อมูล มีอินเทอร์เฟซ SQL มากมายที่ Hadoop สำรองไว้
mustaccio

3
อะไรคือข้อ จำกัด ของคุณ: เงินที่จะใช้จ่ายกับซอฟต์แวร์ / ใบอนุญาต?
user3067860

1
เมื่อคุณมีเงินไม่ จำกัด ฉันก็จะแนะนำให้ซื้ออุปกรณ์ SAP HANA มันยอดเยี่ยมสำหรับการรวมกลุ่มบนชุดข้อมูลขนาดใหญ่ แต่คุณคงไม่มีเงินไม่ จำกัด
ฟิลิปป์

คำตอบ:


90

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

  1. อย่าใช้ NoSQL สำหรับสิ่งนี้ ข้อมูลมีโครงสร้างสูงและเหมาะกับฐานข้อมูลเชิงสัมพันธ์อย่างสมบูรณ์
  2. ฉันใช้ SQL Server 2016 เป็นการส่วนตัวและฉันไม่มีปัญหาในการใช้การคำนวณข้ามปริมาณข้อมูลนั้น เดิมทีมันเป็นอินสแตนซ์ PostgreSQL เมื่อฉันเริ่มงานของฉันและมันไม่สามารถจัดการปริมาณข้อมูลได้เหมือนใน AWS ขนาดเล็ก
  3. ฉันขอแนะนำให้แยกส่วนชั่วโมงของวันที่ออกและจัดเก็บแยกจากวันที่นั้น เชื่อฉันเรียนรู้จากความผิดพลาดของฉัน!
  4. ฉันจัดเก็บรายการข้อมูลส่วนใหญ่ที่ชาญฉลาด (DATE, TIME, DATAPOINT_ID, VALUE) แต่นั่นไม่ใช่วิธีที่ผู้คนต้องการตีความข้อมูล เตรียมพร้อมสำหรับข้อความค้นหาที่น่ากลัวต่อข้อมูลและการหมุนรอบตัวจำนวนมหาศาล อย่ากลัวที่จะสร้างตารางที่ไม่ทำให้เป็นมาตรฐานสำหรับชุดผลลัพธ์ที่ใหญ่เกินไปที่จะคำนวณได้ทันที

เคล็ดลับทั่วไป: ฉันเก็บข้อมูลส่วนใหญ่ระหว่างฐานข้อมูลสองฐานข้อมูลแรกเป็นข้อมูลอนุกรมเวลาแบบตรงและถูกทำให้เป็นมาตรฐาน ฐานข้อมูลที่สองของฉันถูกยกเลิกการทำให้เป็นมาตรฐานและมีข้อมูลที่รวบรวมไว้ล่วงหน้า เร็วที่สุดเท่าที่ระบบของฉันเป็นฉันไม่ทราบเลยว่าผู้ใช้ไม่ต้องการรอ 30 วินาทีสำหรับการโหลดรายงาน - แม้ว่าฉันคิดว่า 30 วินาทีในการบีบอัดข้อมูล 2 TB นั้นเร็วมาก

หากต้องการอธิบายรายละเอียดว่าเพราะเหตุใดฉันจึงแนะนำให้จัดเก็บชั่วโมงแยกจากวันที่นี่เป็นเหตุผลบางประการที่ฉันทำเช่นนั้น:

  1. วิธีการนำเสนอข้อมูลไฟฟ้าคือการสิ้นสุดเวลา- ดังนั้น 01:00 จึงเป็นค่าเฉลี่ยของพลังงานไฟฟ้าสำหรับชั่วโมงก่อนหน้าและ 00:00 คือชั่วโมงสิ้นสุดวันที่ 24 (นี่เป็นสิ่งสำคัญเพราะคุณต้องค้นหาวันที่สองวันเพื่อรวมค่า 24 ชั่วโมง - วันที่คุณ กำลังมองหาบวกเครื่องหมายแรกของวันรุ่งขึ้น) อย่างไรก็ตามข้อมูลสภาพอากาศจะถูกนำเสนอในลักษณะไปข้างหน้า (จริงและคาดการณ์สำหรับชั่วโมงถัดไป) จากประสบการณ์ของฉันกับข้อมูลนี้ผู้บริโภคต้องการวิเคราะห์ผลกระทบที่อากาศมีต่อราคา / อุปสงค์ หากคุณใช้การเปรียบเทียบวันที่แบบตรงคุณจะต้องเปรียบเทียบราคาเฉลี่ยของชั่วโมงก่อนหน้ากับอุณหภูมิเฉลี่ยของชั่วโมงถัดไปแม้ว่าจะประทับเวลาเหมือนกันDATETIME คอลัมน์.
  2. ประสิทธิภาพ. ฉันจะบอกว่าอย่างน้อย 90% ของรายงานที่ฉันสร้างเป็นกราฟโดยปกติจะวางแผนราคาเทียบกับชั่วโมงสำหรับวันเดียวหรือช่วงวันที่ การแยกเวลาออกจากวันที่สามารถทำให้ความเร็วของแบบสอบถามที่ใช้ในการสร้างรายงานขึ้นอยู่กับช่วงวันที่ที่คุณต้องการดู ไม่ใช่เรื่องแปลกสำหรับผู้บริโภคที่ต้องการเห็นวันเดียวปีต่อปีสำหรับ 30 ปีที่ผ่านมา (ในความเป็นจริงสำหรับสภาพอากาศนี้จะต้องสร้างบรรทัดฐาน 30 ปี) - นี้อาจช้า แน่นอนคุณสามารถเพิ่มประสิทธิภาพการสืบค้นและเพิ่มดัชนีและเชื่อฉันฉันมีดัชนีบ้าที่ฉันไม่ต้องการ แต่มันทำให้ระบบทำงานได้อย่างรวดเร็ว
  3. ผลผลิต ฉันเกลียดที่จะต้องเขียนโค้ดชิ้นเดียวกันมากกว่าหนึ่งครั้ง ฉันเคยเก็บวันที่และเวลาในคอลัมน์เดียวกันจนกว่าฉันจะต้องเขียนแบบสอบถามเดียวกันซ้ำแล้วซ้ำอีกเพื่อแยกส่วนเวลา หลังจากที่ในขณะที่ฉันเพิ่งเบื่อที่จะต้องทำเช่นนี้และแยกมันไปยังคอลัมน์ของตัวเอง รหัสน้อยคุณต้องเขียนโอกาสน้อยที่มีข้อผิดพลาดในนั้น นอกจากนี้เมื่อต้องเขียนรหัสให้น้อยลงก็หมายความว่าคุณสามารถทำให้รายงานของคุณเร็วขึ้นไม่มีใครต้องการรอรายงานทั้งวัน
  4. ผู้ใช้ปลายทาง ไม่ใช่ผู้ใช้ปลายทางทั้งหมดที่เป็นผู้ใช้ระดับสูง (เช่นทราบวิธีการเขียน SQL) การมีข้อมูลที่จัดเก็บในรูปแบบที่สามารถนำเข้าสู่ Excel (หรือเครื่องมืออื่น ๆ ที่คล้ายกัน) ด้วยความพยายามน้อยที่สุดจะทำให้คุณเป็นฮีโร่ในสำนักงาน หากผู้ใช้ไม่สามารถเข้าถึงหรือจัดการข้อมูลได้อย่างง่ายดายพวกเขาจะไม่ใช้ระบบของคุณ เชื่อฉันฉันออกแบบระบบที่สมบูรณ์แบบเมื่อสองสามปีก่อนและไม่มีใครใช้มันเพราะเหตุผลนี้ การออกแบบฐานข้อมูลไม่ได้เกี่ยวกับการปฏิบัติตามกฎ / แนวทางที่กำหนดไว้ล่วงหน้าเท่านั้น แต่ยังเกี่ยวกับการทำให้ระบบใช้งานได้

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


ฉันโชคดีที่ใช้วันที่ Epoch แต่คำแนะนำของคุณน่าสนใจสำหรับกรณีการใช้งานของคุณ ขอบคุณสำหรับการแบ่งปัน.
Ali Razeghi

ฉันเก็บวันที่ / เวลาเป็น UTC แต่เดิมผู้บริโภคบ่นเพราะพวกเขาจะต้องปรับเวลาท้องถิ่น ในที่สุดการออกแบบของฉันเปลี่ยนไปเพื่อให้ผู้บริโภคสามารถใช้ข้อมูลได้ง่ายขึ้น
Mr.Brownstone

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

1
ฮาร์ดแวร์ของคุณเป็นอย่างไร
สุนัข

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

57

ดัชนี PostgreSQL และ BRIN

ทดสอบด้วยตัวคุณเอง นี่ไม่ใช่ปัญหาสำหรับแล็ปท็อปอายุ 5 ปีที่มี ssd

EXPLAIN ANALYZE
CREATE TABLE electrothingy
AS
  SELECT
    x::int AS id,
    (x::int % 20000)::int AS locid,  -- fake location ids in the range of 1-20000
    now() AS tsin,                   -- static timestmap
    97.5::numeric(5,2) AS temp,      -- static temp
    x::int AS usage                  -- usage the same as id not sure what we want here.
  FROM generate_series(1,1728000000) -- for 1.7 billion rows
    AS gs(x);

                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series gs  (cost=0.00..15.00 rows=1000 width=4) (actual time=173119.796..750391.668 rows=1728000000 loops=1)
 Planning time: 0.099 ms
 Execution time: 1343954.446 ms
(3 rows)

ดังนั้นใช้เวลา 22 นาทีในการสร้างตาราง ส่วนใหญ่เนื่องจากตารางเป็น 97GB ที่เรียบง่าย ต่อไปเราจะสร้างดัชนี

CREATE INDEX ON electrothingy USING brin (tsin);
CREATE INDEX ON electrothingy USING brin (id);    
VACUUM ANALYZE electrothingy;

ใช้เวลานานพอสมควรในการสร้างดัชนีเช่นกัน แม้ว่าพวกเขาจะเป็น BRIN พวกเขามีเพียง 2-3 MB และพวกเขาเก็บไว้ใน RAM ได้อย่างง่ายดาย การอ่าน 96 GB ไม่ได้เกิดขึ้นทันที แต่ไม่ใช่ปัญหาที่แท้จริงสำหรับแล็ปท็อปของฉันที่ภาระงานของคุณ

ตอนนี้เราค้นหามัน

explain analyze
SELECT max(temp)
FROM electrothingy
WHERE id BETWEEN 1000000 AND 1001000;
                                                                 QUERY PLAN                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=5245.22..5245.23 rows=1 width=7) (actual time=42.317..42.317 rows=1 loops=1)
   ->  Bitmap Heap Scan on electrothingy  (cost=1282.17..5242.73 rows=993 width=7) (actual time=40.619..42.158 rows=1001 loops=1)
         Recheck Cond: ((id >= 1000000) AND (id <= 1001000))
         Rows Removed by Index Recheck: 16407
         Heap Blocks: lossy=128
         ->  Bitmap Index Scan on electrothingy_id_idx  (cost=0.00..1281.93 rows=993 width=0) (actual time=39.769..39.769 rows=1280 loops=1)
               Index Cond: ((id >= 1000000) AND (id <= 1001000))
 Planning time: 0.238 ms
 Execution time: 42.373 ms
(9 rows)

อัปเดตด้วยการประทับเวลา

ที่นี่เราสร้างตารางที่มีการประทับเวลาที่แตกต่างกันเพื่อตอบสนองคำขอการจัดทำดัชนีและค้นหาในคอลัมน์การประทับเวลาการสร้างใช้เวลานานขึ้นเล็กน้อยเนื่องจากto_timestamp(int)ช้ากว่าnow()(ซึ่งแคชสำหรับธุรกรรม)

EXPLAIN ANALYZE
CREATE TABLE electrothingy
AS
  SELECT
    x::int AS id,
    (x::int % 20000)::int AS locid,
    -- here we use to_timestamp rather than now(), we
    -- this calculates seconds since epoch using the gs(x) as the offset
    to_timestamp(x::int) AS tsin,
    97.5::numeric(5,2) AS temp,
    x::int AS usage
  FROM generate_series(1,1728000000)
    AS gs(x);

                                                               QUERY PLAN                                                                
-----------------------------------------------------------------------------------------------------------------------------------------
 Function Scan on generate_series gs  (cost=0.00..17.50 rows=1000 width=4) (actual time=176163.107..5891430.759 rows=1728000000 loops=1)
 Planning time: 0.607 ms
 Execution time: 7147449.908 ms
(3 rows)

ตอนนี้เราสามารถเรียกใช้แบบสอบถามด้วยค่าการประทับเวลาแทน ,,

explain analyze
SELECT count(*), min(temp), max(temp)
FROM electrothingy WHERE tsin BETWEEN '1974-01-01' AND '1974-01-02';
                                                                        QUERY PLAN                                                                         
-----------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=296073.83..296073.84 rows=1 width=7) (actual time=83.243..83.243 rows=1 loops=1)
   ->  Bitmap Heap Scan on electrothingy  (cost=2460.86..295490.76 rows=77743 width=7) (actual time=41.466..59.442 rows=86401 loops=1)
         Recheck Cond: ((tsin >= '1974-01-01 00:00:00-06'::timestamp with time zone) AND (tsin <= '1974-01-02 00:00:00-06'::timestamp with time zone))
         Rows Removed by Index Recheck: 18047
         Heap Blocks: lossy=768
         ->  Bitmap Index Scan on electrothingy_tsin_idx  (cost=0.00..2441.43 rows=77743 width=0) (actual time=40.217..40.217 rows=7680 loops=1)
               Index Cond: ((tsin >= '1974-01-01 00:00:00-06'::timestamp with time zone) AND (tsin <= '1974-01-02 00:00:00-06'::timestamp with time zone))
 Planning time: 0.140 ms
 Execution time: 83.321 ms
(9 rows)

ผลลัพธ์:

 count |  min  |  max  
-------+-------+-------
 86401 | 97.50 | 97.50
(1 row)

ดังนั้นใน 83.321 ms เราสามารถรวบรวม 86,401 ระเบียนในตารางที่มี 1.7 พันล้านแถว นั่นควรจะสมเหตุสมผล

สิ้นสุดชั่วโมง

การคำนวณการสิ้นสุดชั่วโมงก็ค่อนข้างง่ายเช่นกันตัดส่วนเวลาที่บันทึกไว้ลงแล้วเพิ่มชั่วโมง

SELECT date_trunc('hour', tsin) + '1 hour' AS tsin,
  count(*),
  min(temp),
  max(temp)
FROM electrothingy
WHERE tsin >= '1974-01-01'
  AND tsin < '1974-01-02'
GROUP BY date_trunc('hour', tsin)
ORDER BY 1;
          tsin          | count |  min  |  max  
------------------------+-------+-------+-------
 1974-01-01 01:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 02:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 03:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 04:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 05:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 06:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 07:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 08:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 09:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 10:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 11:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 12:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 13:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 14:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 15:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 16:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 17:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 18:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 19:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 20:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 21:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 22:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-01 23:00:00-06 |  3600 | 97.50 | 97.50
 1974-01-02 00:00:00-06 |  3600 | 97.50 | 97.50
(24 rows)

Time: 116.695 ms

สิ่งสำคัญที่ควรทราบคือไม่ได้ใช้ดัชนีในการรวมตัว แต่อาจทำได้ ถ้านั่นเป็นคำถามของคุณโดยทั่วไปคุณอาจต้องการให้ BRIN อยู่ในdate_trunc('hour', tsin)นั้นปัญหาเล็ก ๆ ที่date_truncไม่สามารถเปลี่ยนไม่ได้ดังนั้นคุณต้องห่อมันก่อนเพื่อให้มันเป็นเช่นนั้น

การแยก

อีกจุดที่สำคัญของข้อมูลเกี่ยวกับ PostgreSQL เป็นที่ PG 10 นำมาแบ่งพาร์ทิชัน DDL ตัวอย่างเช่นคุณสามารถสร้างพาร์ติชันได้อย่างง่ายดายทุกปี ทำลายฐานข้อมูลขนาดเล็กของคุณให้เล็กลง ในการทำเช่นนี้คุณควรใช้และรักษาดัชนี btree มากกว่า BRIN ซึ่งจะเร็วยิ่งขึ้น

CREATE TABLE electrothingy_y2016 PARTITION OF electrothingy
    FOR VALUES FROM ('2016-01-01') TO ('2017-01-01');

หรืออะไรก็ตาม


13

มันทำให้ฉันประหลาดใจว่าไม่มีใครที่นี่ได้พูดถึงการเปรียบเทียบ - นั่นคือจนกว่า@EvanCarroll มาพร้อมกับผลงานที่ยอดเยี่ยมของเขา!

ถ้าฉันเป็นคุณฉันจะใช้เวลา (และใช่ฉันรู้ว่ามันเป็นสินค้าที่มีค่า!) การตั้งค่าระบบใช้งานสิ่งที่คุณคิดว่าจะเป็น

ความคิดของฉัน:

โซลูชัน NoSQL สามารถทำงานได้ดีมากสำหรับกรณีการใช้งานเฉพาะ แต่มีความยืดหยุ่นสูงสำหรับการค้นหาแบบเฉพาะกิจ หากต้องการความสนุกกับ NoSQL โดย Brian Aker - อดีตหัวหน้าสถาปนิกของ MySQL ดูที่นี่ !

ฉันเห็นด้วยกับ @ Mr.Brownstone ว่าข้อมูลของคุณเหมาะอย่างยิ่งกับโซลูชันเชิงสัมพันธ์ (และความคิดเห็นนี้ได้รับการยืนยันโดย Evan Carroll )!

ถ้าฉันต้องจ่ายค่าใช้จ่ายใด ๆ มันจะเป็นเทคโนโลยีดิสก์ของฉัน! ฉันจะใช้จ่ายเงินใด ๆ ที่ฉันมีให้กับ NAS หรือ SAN หรืออาจมีดิสก์ SSD บางตัวเพื่อเก็บข้อมูลรวมที่ฉันไม่ค่อยได้เขียนไว้!

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

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

พอร์ตแรกของฉันที่เป็นส่วนตัวสำหรับโครงการเช่นนี้คือ PostgreSQL ไม่ได้หมายความว่าฉันจะแยกแยะทางออกที่เป็นกรรมสิทธิ์ แต่กฎหมายของฟิสิกส์และดิสก์เหมือนกันสำหรับทุกคน! "Yae cannae beet กฎหมาย o 'ฟิสิกส์ Jim" :-)


6

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


1
ตัวอย่างของ DBMS อนุกรมเวลาคืออะไร?
บิชอป

2
ได้ดูที่นี่
Vérace

4

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

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

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

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


คุณอาจพิจารณาว่าGreenplumเป็นร้านค้าแบบเสาหากคุณกำลังมองดูสิ่งเหล่านั้น! ในฐานะ "โบนัส" - มันขึ้นอยู่กับ PostgreSQL!
Vérace

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