การทำงานกับ Large Objects (LOB, File, Image)

Sharing is caring!

PostgreSQL รองรับการจัดเก็บข้อมูลประเภท Large Objects (LOB) เช่น ไฟล์ PDF, รูปภาพ, วิดีโอ หรือ Binary Data ขนาดใหญ่ การทำงานกับ LOB สามารถทำได้หลายวิธี ทั้งการใช้ BYTEA และการใช้ระบบ Large Object API ของ PostgreSQL โดยตรง

1. การเก็บข้อมูลแบบ BYTEA

วิธีง่ายที่สุดคือใช้ BYTEA ซึ่งสามารถเก็บ Binary Data เช่น ไฟล์และรูปภาพได้โดยตรง แต่ไม่เหมาะกับข้อมูลที่ใหญ่มากเกินไป (>1GB)

CREATE TABLE files (
  id SERIAL PRIMARY KEY,
  filename TEXT,
  data BYTEA
);
  

การ Insert ข้อมูลแบบ BYTEA

INSERT INTO files (filename, data)
VALUES ('example.png', pg_read_binary_file('/path/example.png'));
  

2. การใช้ Large Object API

PostgreSQL มี Large Object API ที่รองรับไฟล์ใหญ่กว่า 1GB โดยใช้ฟังก์ชันเช่น lo_import, lo_export, lo_open

การ Import ไฟล์เข้า Large Object

SELECT lo_import('/path/document.pdf');
  

การ Export ไฟล์ออกจาก Large Object

SELECT lo_export(12345, '/tmp/output.pdf');
  

3. การจัดการ Large Object ผ่านโค้ด

นอกจาก SQL ยังสามารถทำงานกับ Large Object ผ่านโค้ดในภาษาโปรแกรมต่าง ๆ

Java (JDBC)

Connection conn = DriverManager.getConnection(url, user, pass);
conn.setAutoCommit(false);

LargeObjectManager lobj = ((PGConnection)conn).getLargeObjectAPI();
int oid = lobj.createLO(LargeObjectManager.READ | LargeObjectManager.WRITE);

LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
File file = new File("example.pdf");
FileInputStream fis = new FileInputStream(file);

byte[] buf = new byte[2048];
int s;
while ((s = fis.read(buf, 0, 2048)) > 0) {
    obj.write(buf, 0, s);
}
obj.close();
fis.close();
conn.commit();
  

Node.js (pg)

const { Client } = require('pg');
const fs = require('fs');

const client = new Client({ connectionString: "postgres://postgres:secret@localhost/mydb" });
await client.connect();

const fileData = fs.readFileSync("example.png");
await client.query("INSERT INTO files (filename, data) VALUES ($1, $2)", ["example.png", fileData]);

await client.end();
  

Golang (pq)

db, _ := sql.Open("postgres", "user=postgres password=secret dbname=mydb sslmode=disable")
file, _ := os.ReadFile("example.jpg")
_, err := db.Exec("INSERT INTO files (filename, data) VALUES ($1, $2)", "example.jpg", file)
if err != nil {
    log.Fatal(err)
}
  

4. ข้อควรพิจารณา

  • BYTEA → เหมาะกับไฟล์ขนาดเล็กถึงปานกลาง
  • Large Object API → เหมาะกับไฟล์ขนาดใหญ่
  • ใช้ External Storage (S3, MinIO) สำหรับไฟล์ขนาดใหญ่มาก และเก็บ Metadata ใน PostgreSQL
  • ควรสร้าง Index บนชื่อไฟล์หรือคีย์หลักเพื่อให้ค้นหาข้อมูลง่าย

5. การ Monitor และจัดการ

สามารถดู Large Objects ที่มีอยู่ทั้งหมดได้จากตาราง pg_largeobject

SELECT * FROM pg_largeobject_metadata;
  

หากไม่ได้ใช้งาน Large Object ควรลบเพื่อลดขนาดฐานข้อมูล

SELECT lo_unlink(12345);
  

สรุป

PostgreSQL รองรับการทำงานกับ Large Objects ได้ทั้งแบบ BYTEA และ Large Object API การเลือกวิธีขึ้นอยู่กับขนาดไฟล์และ Use Case ของระบบ หากไฟล์ไม่ใหญ่มาก ใช้ BYTEA ก็เพียงพอ แต่ถ้าไฟล์ใหญ่ควรใช้ Large Object API และในระบบขนาดใหญ่ควรพิจารณาเก็บไฟล์ใน External Storage เช่น S3

SEO Keywords

PostgreSQL Large Object,Postgres BYTEA Example,Postgres lo_import lo_export,Store File PostgreSQL,Save Image in PostgreSQL,Postgres LOB Best Practices

Leave a Reply

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *