จัดเก็บรูปภาพลงฐานข้อมูลหรือจัดเก็บเป็นไฟล์ดีกว่ากัน
มีคำถามบ่อยๆถึงวิธีการจัดเก็บรูปภาพบน Server ว่าใช้วิธีไหนถึงจะเหมาะสม ระหว่างการจัดเก็บลงฐานข้อมูลและการจัดเก็บเป็นไฟล์
การเก็บข้อมูลรูปภาพลงฐานข้อมูล อาศัยการเก็บข้อมูลเป็น blob ลงฐานข้อมูล (blob ถูกจัดเก็บเป็นไบนารี่)
image/png เปลี่ยนไปตาม mime ของข้อมูลรูปภาพที่จัดเก็บไว้
จริงอยู่ว่าการจัดเก็บข้อมูลรูปภาพลงฐานข้อมูลโดยตรง จะทำให้เราสามารถจัดการกับข้อมูลและรูปภาพได้ง่าย เช่นการลบข้อมูล จะสามารถลบรูปภาพออกไปด้วยทันทีเมื่อมีการลบเร็คคอร์ด แต่การเก็บข้อมูลรูปภาพลงบนฐานข้อมูลโดยตรงก็มีข้อเสียที่สำคัญกว่า
มีคำถามเพิ่มเติมว่า แล้วการเก็บ file path ของรูปภาพควรเก็บเฉพาะชื่อไฟล์ หรือเก็บแบบ fullpath ดี
การเก็บข้อมูลรูปภาพลงฐานข้อมูล อาศัยการเก็บข้อมูลเป็น blob ลงฐานข้อมูล (blob ถูกจัดเก็บเป็นไบนารี่)
$image = base64_encode(file_get_contents('/path/to/file.png'));
- อ่านไฟล์ด้วย file_get_contents() ได้ข้อมูลของไฟล์ออกมา (ใช้ฟังก์ชั่นอื่นก็ได้ที่สามารถอ่านเนื้อหาของไฟล์ออกมาได้)
- เข้ารหัสเนื้อหาด้วยที่อ่านได้ด้วย base64 ซึ่งจริงๆแล้วเราไม่ต้องเข้ารหัสก็ได้ แต่เหตุผลที่ควรจะเข้ารหัส (เป็น base64) เนื่องจาก
- ด้านความปลอดภัย การจัดเก็บเนื้อหาของไฟล์ตรงๆ อาจมีการแอบแทรกคำสั่งที่ไม่พึงประสงค์ลงในไฟล์รูปภาพที่จัดเก็บได้ ซึ่งอาจทำให้การ insert ข้อมูลมีปัญหา
- tag IMG รองรับข้อมูลประเภท base64 อยู่แล้ว ทำให้การนำข้อมูลรูปภาพออกมาใช้ไม่ต้องเสียเวลาแปลงอีก
- จัดเก็บข้อมูลที่เข้ารหัสแล้วลงฐานข้อมูล
<img src="data:image/png;base64,'.$image.'">
image/png เปลี่ยนไปตาม mime ของข้อมูลรูปภาพที่จัดเก็บไว้
จริงอยู่ว่าการจัดเก็บข้อมูลรูปภาพลงฐานข้อมูลโดยตรง จะทำให้เราสามารถจัดการกับข้อมูลและรูปภาพได้ง่าย เช่นการลบข้อมูล จะสามารถลบรูปภาพออกไปด้วยทันทีเมื่อมีการลบเร็คคอร์ด แต่การเก็บข้อมูลรูปภาพลงบนฐานข้อมูลโดยตรงก็มีข้อเสียที่สำคัญกว่า
- ไฟล์รูปภาพมักมีขนาดใหญ่ อาจตั้งแต่หลายร้อยไบท์ ไปจนถึงระดับเม็กกะไบท์ ซึ่งถ้ามีหลายๆเร็คคอร์ด อาจทำให้ได้ Database ที่ใหญ่มาก (นิยมเรียกว่า Database บวม) ซึ่งส่งผลให้ Database ทำงานได้ช้า
- การเข้ารหัสแบบ Base64 ยังทำให้ได้ข้อมูลที่มีขนาดใหญ่กว่าข้อมูลต้นฉบับอีก (เนื่องจากต้องแปลงข้อมูลไบนารี่ให้เป็นสตริงค์ที่สามารถอ่านได้)
- การ query รูปภาพจากฐานข้อมูล ต้องอาศัยการทำงานของฐานข้อมูล ซึ่งเป็นการเพิ่มภาระให้กับ Server ในการส่งข้อมูลกลับมา ในขณะที่การเก็บเป็นไฟล์ สามารถใช้ความสามารถของ Server (เช่น NGINX) ในการส่งไฟล์กลับมาซึ่งมีประสิทธิภาพมากกว่าหลายเท่าตัว
มีคำถามเพิ่มเติมว่า แล้วการเก็บ file path ของรูปภาพควรเก็บเฉพาะชื่อไฟล์ หรือเก็บแบบ fullpath ดี
- การเก็บแบบ fullpath ไม่เหมาะสมเป็นอย่างยิ่ง เพราะหากมีการเปลี่ยนแปลงหรือย้าย Server อาจจะทำให้หาไฟล์ไม่เจอทันที (เนื่องจากแต่ละ Server อาจมีที่อยู่ไม่ตรงกัน)
- การเก็บแบบอ้างอิงจาก root ของ server มักใช้ในกรณีที่ ที่อยู่ของไฟล์ไม่แน่นอน
- เก็บเฉพาะชื่อไฟล์ (ส่วนตัวใช้วิธีนี้เป็นส่วนใหญ่) เนื่องจากผมจะออกแบบโครงสร้างของเว็บไซต์ให้การอัปโหลดไปรวมอยู่ที่เดียว (เช่น images/) ข้อดีก็คือ เราสามารถควบคุมได้ง่าย (เช่นการป้องกัน hotlink) และข้อดีที่ดีกว่าคือข้อมูลที่จัดเก็บใน Daatabse มีขนาดเล็กที่สุด