มันเป็นการปฏิบัติที่ไม่ถูกต้องหรือไม่ที่จะเก็บไฟล์ขนาดใหญ่ (10 MB) ไว้ในฐานข้อมูล?


188

ขณะนี้ฉันกำลังสร้างเว็บแอปพลิเคชันที่อนุญาตให้ผู้ใช้จัดเก็บและแชร์ไฟล์ขนาด 1 MB - 10 MB

สำหรับฉันแล้วดูเหมือนว่าการจัดเก็บไฟล์ในฐานข้อมูลจะทำให้การเข้าถึงฐานข้อมูลช้าลงอย่างมาก

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

ฉันทำงานใน PHP และ MySQL สำหรับโครงการนี้ แต่เป็นปัญหาเดียวกันสำหรับสภาพแวดล้อมส่วนใหญ่ ( Ruby on Rails , PHP , .NET ) และฐานข้อมูล (MySQL, PostgreSQL )


9
คำถามที่เกี่ยวข้องกับ DBA.SE: ไฟล์ - ในฐานข้อมูลหรือไม่?
Nick Chammas

11
แปลกใจที่ไม่มีใครโพสต์การวิจัย MS ที่ทำในเรื่องนี้ (สำหรับ SQL Server 2008): เพื่อ BLOB หรือไม่เพื่อ BLOB: การจัดเก็บวัตถุขนาดใหญ่ในฐานข้อมูลหรือระบบแฟ้ม
Oded

2
ขนาดใหญ่เป็นปริมาณสัมพัทธ์ฉัน (และอื่น ๆ อีกมากมายอาจ) ไม่เห็น10MBว่ามีขนาดใหญ่ในระบบที่ทันสมัย

27
นี่คือหัวข้อตามคำถามที่พบบ่อย - มันพอดีภายใต้หัวข้อย่อย "รูปแบบการออกแบบ" (สแลช antipatterns) และ "สถาปัตยกรรมซอฟต์แวร์" ทำไมมันปิด
Izkata

21
ฉันไม่เห็นความคลุมเครือในคำถามเหมือนตอนนี้ ฉันไม่รู้ว่าทำไมมันถึงปิด
reinierpost

คำตอบ:


139

เหตุผลที่สนับสนุนการจัดเก็บไฟล์ในฐานข้อมูล:

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

เหตุผลในการจัดเก็บไฟล์ในฐานข้อมูล:

  1. ขนาดของไฟล์ไบนารีแตกต่างกันระหว่างฐานข้อมูล บน SQL Server เมื่อไม่ได้ใช้วัตถุ FILESTREAM เช่นจะเป็น 2 GB หากผู้ใช้ต้องการจัดเก็บไฟล์ที่มีขนาดใหญ่ขึ้น (เช่นพูดว่าภาพยนตร์) คุณต้องกระโดดผ่านห่วงเพื่อให้เกิดเวทมนตร์นั้นขึ้น
  2. เพิ่มขนาดของฐานข้อมูล แนวคิดทั่วไปหนึ่งข้อที่คุณควรคำนึงถึง: ระดับของความรู้ที่จำเป็นในการรักษาฐานข้อมูลขึ้นอยู่กับสัดส่วนของขนาดของฐานข้อมูลนั่นคือฐานข้อมูลขนาดใหญ่มีความซับซ้อนในการดูแลมากกว่าฐานข้อมูลขนาดเล็ก การจัดเก็บไฟล์ในฐานข้อมูลสามารถทำให้ฐานข้อมูลมีขนาดใหญ่ขึ้นมาก แม้ว่าการสำรองข้อมูลเต็มรูปแบบทุกวันจะเพียงพอ แต่ด้วยขนาดฐานข้อมูลที่ใหญ่ขึ้นคุณอาจไม่สามารถทำเช่นนั้นได้อีก คุณอาจต้องพิจารณาวางไฟล์ลงในกลุ่มไฟล์อื่น (หากฐานข้อมูลรองรับนั้น) ปรับแต่งการสำรองเพื่อแยกการสำรองข้อมูลจากการสำรองไฟล์ ฯลฯ ไม่มีสิ่งเหล่านี้เป็นไปไม่ได้ที่จะเรียนรู้ แต่ทำ เพิ่มความซับซ้อนในการบำรุงรักษาซึ่งหมายถึงต้นทุนต่อธุรกิจ ฐานข้อมูลที่มีขนาดใหญ่ยังใช้หน่วยความจำมากขึ้นเมื่อพยายามเก็บข้อมูลลงในหน่วยความจำให้มากที่สุด
  3. ความสามารถในการพกพาอาจเป็นปัญหาหากคุณใช้คุณสมบัติเฉพาะของระบบเช่นFILESTREAMวัตถุของ SQL Server และจำเป็นต้องโยกย้ายไปยังระบบฐานข้อมูลอื่น
  4. รหัสที่เขียนไฟล์ไปยังฐานข้อมูลอาจเป็นปัญหา บริษัท หนึ่งที่ฉันปรึกษาไม่กี่เดือนที่ผ่านมาในบางจุดเชื่อมต่อส่วนหน้าของ Microsoft Access กับเซิร์ฟเวอร์ฐานข้อมูลของพวกเขาและใช้ความสามารถของ Access ในการอัปโหลด "อะไร" โดยใช้การควบคุมวัตถุของ Ole หลังจากนั้นพวกเขาเปลี่ยนไปใช้การควบคุมที่แตกต่างซึ่งยังคงพึ่งพา Ole ต่อมามีคนเปลี่ยนอินเทอร์เฟซเพื่อเก็บไบนารีดิบ การแยกวัตถุ Ole เหล่านั้นเป็นระดับใหม่ของนรก เมื่อคุณจัดเก็บไฟล์ในระบบไฟล์จะไม่มีเลเยอร์เพิ่มเติมที่เกี่ยวข้องกับการตัด / ปรับแต่ง / แก้ไขไฟล์ต้นฉบับ
  5. มันมีความซับซ้อนในการแสดงไฟล์ไปยังเว็บไซต์ ในการดำเนินการกับคอลัมน์ไบนารีคุณต้องเขียนตัวจัดการเพื่อสตรีมไฟล์ไบนารีจากฐานข้อมูล คุณสามารถทำได้แม้ว่าคุณจะเก็บเส้นทางของไฟล์ แต่คุณไม่ต้องทำเช่นนี้ อีกครั้งการเพิ่มตัวจัดการเป็นไปไม่ได้ แต่เพิ่มความซับซ้อนและเป็นอีกจุดหนึ่งของความล้มเหลว
  6. คุณไม่สามารถใช้ประโยชน์จากที่เก็บข้อมูลบนคลาวด์ได้ สมมติว่าวันหนึ่งคุณต้องการจัดเก็บไฟล์ของคุณในที่ฝากข้อมูล Amazon S3 หากสิ่งที่คุณเก็บไว้ในฐานข้อมูลคือพา ธ ไฟล์คุณจะสามารถเปลี่ยนเป็นพา ธ ที่ S3 ได้ เท่าที่ฉันรู้ว่ามันเป็นไปไม่ได้ในทุกสถานการณ์ด้วย DBMS ใด ๆ

IMO ซึ่งถือว่าการจัดเก็บไฟล์ในฐานข้อมูลหรือไม่ว่า "ไม่ดี" ต้องการข้อมูลเพิ่มเติมเกี่ยวกับสถานการณ์และข้อกำหนด ขนาดและ / หรือจำนวนไฟล์จะเล็กหรือไม่? ไม่มีแผนที่จะใช้ที่เก็บข้อมูลบนคลาวด์หรือไม่? ไฟล์ดังกล่าวจะถูกนำไปใช้กับเว็บไซต์หรือไบนารีที่ปฏิบัติการได้เหมือนกับแอพพลิเคชั่นของ Windows หรือไม่?

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


ทำไมคุณไม่สามารถใช้ CDN นี่เป็นสถานการณ์ที่ได้รับการสนับสนุนซึ่งมี CDN ทุกตัวที่ฉันเคยได้ยินมา
Billy ONeal

@BillyONeal - คุณไม่สามารถใช้ CDN และจัดเก็บไฟล์ในฐานข้อมูล นอกจากว่าคุณจะโอเคกับการทำซ้ำคุณจะไม่มีทั้งคู่
โทมัส

3
เอ่อจุดรวมของ CDN คือการทำซ้ำ CDN เพียงแค่แคชเป้าหมายของที่อยู่เว็บ - ข้อกำหนดเพียงอย่างเดียวคือมีโฮสต์ HTTP ที่ให้บริการเนื้อหาและเนื้อหานั้นเปลี่ยนแปลงไปน้อยมาก (CDN ควรจะเป็นอย่างไรในโลกที่จะบอกว่าคุณดึงภาพมาจากไหน?)
Billy ONeal

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

@BillyONeal - ความเห็นของคุณเป็นคำตอบที่ดีที่สุด คุณสามารถได้รับประโยชน์ทั้งหมดของการจัดเก็บฐานข้อมูล แต่ไม่มีปัญหา
B เซเว่น

89

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

แต่! ฐานข้อมูลบางอย่างเช่นSQL Serverมีชนิดคอลัมน์ FILESTREAM ในกรณีนี้ข้อมูลของคุณจะถูกจัดเก็บในไฟล์แยกต่างหากบนเซิร์ฟเวอร์ฐานข้อมูลและมีการบันทึก ID ในไฟล์ไว้ในตารางเท่านั้น ในกรณีนี้ฉันไม่เห็นเหตุผลที่จะไม่เก็บข้อมูลไว้ในเซิร์ฟเวอร์ SQL ไฟล์จะถูกรวมโดยอัตโนมัติเป็นส่วนหนึ่งของการสำรองข้อมูลเซิร์ฟเวอร์และฐานข้อมูลและไฟล์จะไม่ซิงค์กัน ปัญหาเกี่ยวกับข้อเสนอแนะของ Tony ในการจัดเก็บชื่อไฟล์คือฐานข้อมูลและระบบไฟล์ไม่สามารถซิงค์ได้ ฐานข้อมูลจะอ้างสิทธิ์ไฟล์ที่มีอยู่เมื่อถูกลบบนดิสก์ หากกระบวนการกำลังแก้ไขฐานข้อมูลแล้วขัดข้องไฟล์และฐานข้อมูลจะไม่ตรงกัน (เช่นไม่มีACIDกับไฟล์ที่อยู่นอกฐานข้อมูล)


21
ฉันไม่เห็นด้วยกับข้อความว่า `หากกระบวนการกำลังแก้ไขฐานข้อมูลและขัดข้องไฟล์และฐานข้อมูลจะไม่ตรงกัน 'หากคุณรวมกระบวนการทั้งหมดในธุรกรรม (สร้างไฟล์ตรวจสอบไฟล์อัปเดตฐานข้อมูล) และโยนข้อความแสดงข้อผิดพลาด เมื่อมีอะไรผิดพลาดมันค่อนข้างง่ายที่จะทำให้พวกมันซิงค์กัน
briddums

3
ฉันกับ briddums ที่: พิจารณาสถานการณ์: จัดเก็บไฟล์ไปยังระบบแฟ้ม (โดยไม่ต้องลบเก่า), การปรับปรุงฐานข้อมูล, ประสบความสำเร็จในการลบไฟล์เก่า, เมื่อย้อนกลับลบไฟล์ใหม่ สถานการณ์กรณีที่เลวร้ายที่สุด - หากกระบวนการขัดจังหวะคุณมีไฟล์เด็กกำพร้า แต่คุณมักจะมีไฟล์อ้างอิงโดย DB ในรุ่นที่ถูกต้อง
vartec

2
ปัญหาที่อาจเกิดขึ้นอื่น ๆ ด้วยวิธีการของไฟล์ / ฐานข้อมูล: 1) คุณต้องทำการอัพเดทแบบ copy-on-write หากกระบวนการของคุณขัดข้องระหว่างการอัปเดตสถานะฐานข้อมูลจะถูกย้อนกลับไฟล์จะไม่ทำงาน 2) การทำเช่นนี้ต้องมีการรวบรวมขยะบางส่วนของไฟล์เก่า 3) การจัดเก็บทุกอย่างในฐานข้อมูลหมายความว่าเวอร์ชันของฐานข้อมูลและไฟล์ซิงค์กันหลังจากทำการสำรองข้อมูล กู้คืนฐานข้อมูลของคุณกลับสู่สถานะ 2 สัปดาห์ที่ผ่านมา ... ตอนนี้เนื้อหาของไฟล์ในเวลานั้นคืออะไร?
ทิโมธี Baldridge

3
@briddums - ไม่เนื่องจาก SQL Server รวมเข้ากับระบบไฟล์โดยตรงและจัดการไฟล์เหล่านั้นในนามของระบบปฏิบัติการ ฉันไม่ได้ใช้ด้วยตนเอง แต่เอกสารทำให้ดูเหมือนว่าFILESTREAMและลูกหลานของFileTables จะให้สิ่งที่ดีที่สุดทั้งสองโลก: ไฟล์ถูกผูกไว้แน่นกับฐานข้อมูลและข้อมูลที่เกี่ยวข้อง (ช่วยให้คุณสามารถจัดการข้อมูลของคุณจากส่วนกลาง) ฐานข้อมูล
Nick Chammas

1
ฉันเห็นด้วยกับนิค เราได้แทนที่ระบบ Disk + DB ของเราด้วยคอลัมน์ FILESTREAM และไม่เคยมองย้อนกลับไป เป็นเรื่องที่ดีมากที่สามารถผูกไฟล์กับตารางอื่น ๆ ผ่าน FK ได้ ดังนั้นคุณสามารถพูดได้ว่า "แต่ละคนต้องมีเอกสาร HR อย่างน้อยหนึ่งรายการที่เกี่ยวข้องกับพวกเขา" หรืออย่างอื่น
ทิโมธี Baldridge

35

ใช่มันเป็นการปฏิบัติที่ไม่ดี

ผลกระทบต่อประสิทธิภาพใน DB:

  • หากคุณทำSELECTกับคอลัมน์ BLOB ใด ๆ คุณจะเข้าถึงดิสก์ได้ตลอดเวลาโดยไม่มี BLOBs คุณจะมีโอกาสได้รับข้อมูลโดยตรงจาก RAM (ฐานข้อมูลปริมาณสูงจะถูกปรับให้เหมาะสมกับตารางใน RAM)
  • การจำลองแบบจะช้าลงการจำลองแบบล่าช้าสูงเนื่องจากจะต้องผลัก BLOB ไปยังทาส ความล่าช้าในการจำลองแบบสูงจะทำให้เกิดสภาพการแข่งขันทุกประเภทและปัญหาการซิงโครไนซ์อื่น ๆ เว้นแต่ว่าคุณจะคำนึงถึงเรื่องนั้นอย่างชัดเจน
  • การสำรอง / กู้คืนฐานข้อมูลจะใช้เวลานานกว่ามาก

ความเร็วได้เปรียบ - ไม่มี ! ในขณะที่ระบบไฟล์รุ่นเก่าบางรุ่นอาจไม่รองรับไดเรกทอรีที่มีไฟล์นับล้านไฟล์ แต่ที่ทันสมัยที่สุดไม่มีปัญหาเลยและในความเป็นจริงก็ใช้โครงสร้างข้อมูลแบบเดียวกับ BDs (โดยทั่วไปคือ B-trees) ยกตัวอย่างเช่น ext4 (ค่าเริ่มต้นระบบแฟ้มลินุกซ์) ใช้Htree

สรุป: มันจะขัดขวางประสิทธิภาพของฐานข้อมูลของคุณและจะไม่ปรับปรุงประสิทธิภาพการดึงไฟล์

นอกจากนี้เนื่องจากคุณกำลังพูดถึงเว็บแอปพลิเคชัน - การให้บริการไฟล์คงที่โดยตรงจากระบบไฟล์โดยใช้เว็บเซิร์ฟเวอร์ที่ทันสมัยซึ่งสามารถทำsendfile()syscall ได้คือการปรับปรุงประสิทธิภาพอย่างมาก แน่นอนว่าเป็นไปไม่ได้หากคุณดึงไฟล์จากฐานข้อมูล พิจารณาตัวอย่างเช่นเกณฑ์มาตรฐานนี้โดยแสดงNgnix ทำ 25K req / s พร้อม 1,000การเชื่อมต่อพร้อมกันบนแล็ปท็อประดับต่ำ การโหลดแบบนั้นจะทำให้ดีบีชนิดใดชนิดหนึ่งทอด


6
+1 ให้เว็บเซิร์ฟเวอร์ของคุณทำสิ่งที่ดีที่สุดโดยให้บริการไฟล์จากดิสก์ อย่าทำให้มันถาม PHP เพราะ PHP จะต้องถาม MySQL เป็นต้น
deizel

3
โปรแกรมเมอร์จะเรียนรู้เมื่อใดว่าประสิทธิภาพไม่ได้เป็นสิ่งที่สำคัญ?
reinierpost

2
@reierierpost: ฮ่า ๆ อาจเป็นเมื่อเราได้รับเอกศิลปศาสตร์ ;-)
vartec

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

1
@BillyONeal: ฉันเห็นด้วยมี "วิธีแก้ปัญหา" ที่จะใช้งานได้ฉันเห็นการตั้งค่า PHP สำหรับมือสมัครเล่นที่มีภาพใน MySQL ค่อนข้างมาก อย่างไรก็ตามในการตั้งค่าดังกล่าวฐานข้อมูลจะไม่สนับสนุน BLOBs ที่มีปริมาณการใช้งานสูง
vartec

18

ฉันจะเน้นในเรื่องนี้และปฏิบัติตามหลักการ "ยังไม่ได้เพิ่มประสิทธิภาพ" สร้างโซลูชันที่สมเหตุสมผลในขณะนี้และเป็นแนวทางที่คุณมีทรัพยากรในการพัฒนาเพื่อนำไปใช้อย่างเหมาะสม มีปัญหาที่อาจเกิดขึ้นมากมาย แต่สิ่งเหล่านั้นไม่จำเป็นต้องกลายเป็นปัญหาที่แท้จริง เช่นมันอาจจะไม่เป็นปัญหาหากคุณมีผู้ใช้ 100 คน มันอาจจะมีปัญหาหากคุณมี 100,000 10,000,000 ผู้ใช้ แต่ในกรณีหลังนี้ควรมีพื้นฐานสำหรับทรัพยากรการพัฒนาเพิ่มเติมเพื่อจัดการกับปัญหาทั้งหมด

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

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

สมมติว่าคุณมีคลาสFileสำหรับแสดงไฟล์ที่อ่านในฐานข้อมูลจากนั้นผลกระทบการเข้ารหัสของการย้ายไฟล์ในภายหลังจะน้อยที่สุด


นี่เป็นข้อเสนอแนะที่ยอดเยี่ยม อย่าเริ่มแก้ปัญหาที่คุณไม่มี
HeavyE

16

Microsoft เปิดตัวกระดาษขาวเกี่ยวกับเรื่องนี้ไม่กี่ปีหลัง มันมุ่งเน้นที่ SqlServer แต่คุณอาจพบข้อมูลที่น่าสนใจบางส่วนในนั้น:

เพื่อ BLOB หรือไม่ที่จะ BLOB? ที่เก็บวัตถุขนาดใหญ่ในฐานข้อมูลหรือระบบไฟล์?

บทสรุปที่กระชับมากของพวกเขาคือ:

เมื่อเปรียบเทียบระบบไฟล์ NTFS และ SQL Server 2005 นั้น BLOBS ที่เล็กกว่า 256KB จะได้รับการจัดการอย่างมีประสิทธิภาพมากขึ้นโดย SQL Server ในขณะที่ NTFS นั้นมีประสิทธิภาพมากกว่าสำหรับ BLOBS ที่มีขนาดใหญ่กว่า 1MB

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


4
คุณควรรู้ว่า NTFS เริ่มทำงานผิดปกติอย่างมากเมื่อคุณใส่ไฟล์ ~ 100K ลงในไดเรกทอรีเดียว การเข้าถึงไฟล์จะช้าลงเล็กน้อย (อย่างน้อยลำดับความสำคัญ) และการดำเนินการเปิดไฟล์จะเริ่มต้นล้มเหลว (เห็นได้ชัด) โดยการสุ่ม ฉันเคยได้รับผลกระทบนี้ในระบบ Windows 2008 และ Windows 7 เมื่อฉันกระจายไฟล์อีกครั้งในหลายไดเรกทอรีทุกอย่างกลับสู่ปกติ ฉันไม่รู้ว่าสถานการณ์ดีขึ้นตั้งแต่นั้นมาหรือไม่
Ferruccio

11

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

Tom Kyte ดูเหมือนจะเห็นด้วย :

ฉันรู้ว่าไม่มีข้อได้เปรียบในการจัดเก็บข้อมูลที่ฉันต้องการเก็บไว้เป็นเวลานานนอกฐานข้อมูล

หากอยู่ในฐานข้อมูลฉันสามารถ

ให้แน่ใจว่ามีการจัดการอย่างมืออาชีพ

ได้รับการสนุบสนุน, ช่วยเหลือ

กู้คืนได้ (ส่วนที่เหลือของข้อมูล)

ปลอดภัย

ปรับขนาดได้ (ลองวางเอกสาร 100,000 รายการในไดเรกทอรีเดียวตอนนี้วางเอกสารไว้ในตาราง - อันใดอันหนึ่ง 'ปรับขนาด' - ไม่ใช่ไดเรกทอรี)

ฉันสามารถยกเลิกการลบ (ย้อนหลัง) ได้อย่างง่ายดาย

ฉันมีล็อค

ฉันได้อ่านความสอดคล้อง ...


8

ใช่.

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

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

ถ้าคุณไม่มีเหตุผลที่ดีจริงๆอย่าทำดีกว่าเสมอในการให้บริการไฟล์คงที่จากระบบไฟล์


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

1
ความเข้าใจของฉันคือคำถามเกี่ยวกับการให้บริการไฟล์ที่ผู้ใช้อัปโหลด "ขณะนี้ฉันกำลังสร้างเว็บแอปพลิเคชันที่อนุญาตให้ผู้ใช้จัดเก็บและแชร์ไฟล์ [... ] ดูเหมือนว่าฉันจะเก็บไฟล์ไว้ในฐานข้อมูล [... ]" ฉันไม่คิดว่ามันจะสะดวกที่จะทำ DB ทิ้งกับหลายเมกะไบต์ blobs ในฐานข้อมูล ใช่: มันยากที่จะจัดการกับไฟล์; การซิงก์การเก็บถาวรทั้งหมดยากขึ้น อย่างไรก็ตามมันไม่ยากไปกว่านี้อีกแล้วการเสียสละประสิทธิภาพออนไลน์เพื่อบันทึกสองสามบรรทัดในสคริปต์สำรองคืนต่อไปของคุณนั้นเป็นความผิดพลาดครั้งใหญ่
Evan P.

5

Tom Kyte ชื่อดังได้เขียนว่าพวกเขา (Oracle) กำลังใช้ฐานข้อมูล Oracle เป็นไฟล์เซิร์ฟเวอร์และมันทำงานได้อย่างสมบูรณ์แบบดียิ่งเร็วกว่าระบบไฟล์ปกติด้วยการทำธุรกรรมเต็มรูปแบบไม่มีการสูญเสียประสิทธิภาพและการสำรองข้อมูลเดียว

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

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

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

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


สวัสดีเมื่อคุณพูดว่า "การใช้ ... Oracle สำหรับการจัดเก็บไฟล์นั้นไม่มีประสิทธิภาพ" ถ้าหากเราใช้ Oracle ในการจัดเก็บข้อมูลที่ไม่ใช่ไฟล์อื่นอยู่แล้ว สิ่งนั้นจะยังคงมีประสิทธิภาพหรือไม่?
Xiao Peng - ZenUML.com

RE: "คุณต้องระวังอย่างมากเมื่อมีคนแก้ไขไฟล์" ... ในฐานะ Oracle DBA เดิมฉันต้องแนะนำให้เก็บไฟล์ขนาดใหญ่ออกจากฐานข้อมูลและไม่อนุญาตให้แก้ไขไฟล์ ผู้คนทำผิดพลาด วิธีปฏิบัติที่เป็นประโยชน์เพียงวิธีเดียวในการจัดการการย้อนกลับ (เลิกทำ) ของไฟล์เหล่านั้นคือการใช้ระบบ Copy On Write สำหรับพวกเขา ดังนั้นเวอร์ชันทั้งหมดจึงได้รับการปรับปรุงและเก็บถาวร ที่เก่าแก่ที่สุดสามารถถูกย้ายออกไปยังที่เก็บข้อมูลระยะไกลโพสต์ที่ประมวลผลเพื่อรวมการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ ไว้ในที่เก็บถาวรเดียวและอื่น ๆ
DocSalvager

5

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


4

คุณอาจพบปัญหานี้บางอย่าง:

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

แน่นอนคุณยังได้รับประโยชน์บางอย่าง:

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

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


1

ระบบการจัดการเนื้อหา Enterpirse บางระบบเช่น SiteCore กำลังใช้ฐานข้อมูลหนึ่งเพื่อจัดเก็บข้อมูลหน้าและฐานข้อมูลอื่นเพื่อจัดเก็บไฟล์ พวกเขากำลังใช้ MS SQL Server


คำถามนี้ถามคำถามนี้อย่างไร
ริ้น

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

1

สำหรับการใช้งานจริงนี่คือสิ่งที่คุณอาจกังวล:

ประโยชน์:

  1. เนื้อหาไฟล์ทั้งหมดจะถูกซิงโครไนซ์กับตารางของคุณอย่างแน่นอน ดังที่ความคิดเห็นข้างต้นกล่าวว่าการสำรองข้อมูลนั้นสะดวกมากเพราะคุณไม่จำเป็นต้องซิงค์ข้อมูลกับระบบไฟล์
  2. จากการเข้ารหัสคุณสามารถรับเนื้อหาไฟล์ได้โดยตรงจากตัวเลือก SQL
  3. จากการสืบค้นคุณสามารถกรองเนื้อหาไฟล์หรือขนาดของมันอย่างชัดเจนจากคำสั่ง SQL

ข้อเสีย:

  1. เปรียบเทียบกับฐานข้อมูลที่มีโครงสร้างแบบ Semantically เหมือนกัน แต่ไม่ได้จัดเก็บเนื้อหาไฟล์ฐานข้อมูลของคุณมีแนวโน้มที่จะใช้หน่วยความจำเพิ่มขึ้นอย่างมากเมื่อทำการสืบค้น
  2. การสำรองข้อมูลอัตโนมัติอาจทำให้เกิดปัญหาประสิทธิภาพ แต่ไม่มาก สมมติว่าเซิร์ฟเวอร์ฐานข้อมูลของคุณสำรองข้อมูลทุก ๆ 6 ชั่วโมงและฐานข้อมูลเหล่านั้นที่คุณจัดเก็บไฟล์ 10 MB ต่อเรคคอร์ด สถานการณ์นั้นไม่ใช่สิ่งที่คุณต้องการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.