PostgreSQL bytea กับ smallint []


9

ฉันต้องการนำเข้าข้อมูลอนุกรมเวลาหลายช่องทางขนาดใหญ่ (100Mb - 1 GB) ลงในฐานข้อมูล PostgreSQL ข้อมูลมาจากไฟล์ฟอร์แมต EDFที่แบ่งข้อมูลเป็น "บันทึก" หรือ "ยุค" ซึ่งโดยทั่วไปแล้วแต่ละวินาที บันทึกยุคของแต่ละคนถือสัญญาณสำหรับแต่ละช่องข้อมูลเป็นอาร์เรย์ลำดับของจำนวนเต็มสั้น

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

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

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


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

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

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

@ CraigRinger ฉันไม่เห็นหลักฐานมากนักเกี่ยวกับการบีบอัดอาร์เรย์ จำเป็นต้องเปิดใช้งานในบางวิธีหรือไม่
beldaz

คำตอบ:


11

ในกรณีที่ไม่มีคำตอบใด ๆ ฉันได้สำรวจปัญหานี้เพิ่มเติมด้วยตนเอง

ดูเหมือนว่าฟังก์ชั่นที่ผู้ใช้กำหนดสามารถจัดการกับประเภทฐานทั้งหมดรวมถึง byteaและsmallint[]ดังนั้นจึงไม่ส่งผลกระทบต่อทางเลือกในการแสดงมากนัก

ฉันลองใช้การแทนหลายแบบบนเซิร์ฟเวอร์ PostgreSQL 9.4 ที่ใช้งานในเครื่องแล็ปท็อป Windows 7 ที่มีการกำหนดค่าวานิลลา ความสัมพันธ์ในการจัดเก็บข้อมูลสัญญาณจริงมีดังนี้

วัตถุขนาดใหญ่สำหรับไฟล์ทั้งหมด

CREATE TABLE BlobFile (
    eeg_id INTEGER PRIMARY KEY,
    eeg_oid OID NOT NULL
);

อาร์เรย์ SMALLINT ต่อแชนเนล

CREATE TABLE EpochChannelArray (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    channel INT,
    signal SMALLINT[] NOT NULL,
    PRIMARY KEY (eeg_id, epoch, channel)
);

BYTEA ต่อช่องสัญญาณในแต่ละยุค

CREATE TABLE EpochChannelBytea (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    channel INT,
    signal BYTEA NOT NULL,
    PRIMARY KEY (eeg_id, epoch, channel)
);

อาร์เรย์ SMALLINT 2D ต่อยุค

CREATE TABLE EpochArray (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    signals SMALLINT[][] NOT NULL,
    PRIMARY KEY (eeg_id, epoch)
);

อาร์เรย์ BYTEA ต่อยุค

CREATE TABLE EpochBytea (
    eeg_id INT NOT NULL,
    epoch INT NOT NULL,
    signals BYTEA NOT NULL,
    PRIMARY KEY (eeg_id, epoch)
);

ฉันจึงนำเข้าไฟล์ EDF ที่เลือกไว้ในแต่ละความสัมพันธ์เหล่านี้ผ่าน Java JDBC และเปรียบเทียบการเติบโตของขนาดฐานข้อมูลหลังจากการอัพโหลดแต่ละครั้ง

ไฟล์ถูก:

  • ไฟล์ A: 2706 epochs 16 ช่องแต่ละตัวอย่าง 1024 ตัว (16385 ตัวอย่างต่อ epoch), 85 MB
  • ไฟล์ B: 11897 ยุค 18 ช่องแต่ละตัวอย่าง 1024 ตัว (18432 ตัวอย่างต่อยุค) 418 MB
  • ไฟล์ C: 11746 epochs 20 ช่องแต่ละตัวอย่าง 64 ถึง 1024 ตัวอย่าง (17088 ตัวอย่างต่อยุค), 382 MB

ในแง่ของค่าใช้จ่ายในการจัดเก็บนี่คือขนาดที่ครอบครองเป็น MB สำหรับแต่ละกรณี: ราคาหน่วยเก็บในหน่วย MB

สัมพันธ์กับขนาดไฟล์ต้นฉบับวัตถุขนาดใหญ่มีขนาดใหญ่ขึ้นประมาณ 30-35% ในทางตรงกันข้ามการจัดเก็บแต่ละยุคเป็น BYTEA หรือ SMALLINT [] [] ใหญ่กว่าน้อยกว่า 10% การจัดเก็บแต่ละช่องเป็นสิ่งอันดับแยกเพิ่มขึ้น 40% ทั้ง BYTEA หรือ SMALLINT [] ดังนั้นจึงไม่แย่กว่าการจัดเก็บเป็นวัตถุขนาดใหญ่

สิ่งหนึ่งที่ผมไม่เคยได้รับการชื่นชมแรกนั่นคือ "อาร์เรย์หลายมิติต้องมีขอบเขตที่ตรงกันสำหรับแต่ละมิติ" ใน PostgreSQL ซึ่งหมายความว่าการSMALLINT[][]แสดงนั้นจะทำงานได้เมื่อทุกช่องในยุคมีจำนวนตัวอย่างเท่ากัน ดังนั้นไฟล์ C ล้มเหลวในการทำงานกับEpochArrayความสัมพันธ์

ในแง่ที่เป็นค่าใช้จ่ายในการเข้าถึงผมไม่ได้เล่นรอบกับเรื่องนี้ แต่อย่างน้อยในแง่ของการใส่ข้อมูลในขั้นต้นเป็นตัวแทนที่เร็วที่สุดที่เป็นEpochByteaและBlobFileมีEpochChannelArrayที่ช้าที่สุดการประมาณ 3 ครั้งเป็นเวลานานเป็นสองคนแรก


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

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