Giới thiệu
PostgreSQL cung cấp cho các nhà phát triển cơ hội lựa chọn giữa hai phương tiện lưu trữ có thể có cho dữ liệu nhị phân lớn:Bytea và LargeObjects.
Các Đối tượng Lớn đã có từ lâu và PostgreSQL có một cách thông minh để lưu trữ dữ liệu nhị phân lớn. Nó làm như vậy bằng cách chia nó thành nhiều phần LOBLKSIZE (một phần tư của BLCKSZ). Bằng cách đó, các bộ giá trị từ pg_largeobject không tràn trên bàn bánh mì nướng.
Mặt khác bytea lưu trữ dữ liệu nhị phân trực tiếp trong bộ tuple, điều này có thể dẫn đến hiệu suất kém tùy thuộc vào giao diện giản đồ của bạn.
Điều này nghe có vẻ tuyệt vời nếu bạn có một giao diện thông minh để xử lý việc thao tác các tệp nhị phân này, đặc biệt nếu bản cập nhật chỉ sửa đổi một phần nhỏ của toàn bộ tệp nhị phân.
Nhưng thông thường, chúng tôi không bận tâm đến việc viết mã tận dụng lợi thế này và thay vào đó chúng tôi viết lại toàn bộ dữ liệu nhị phân.
Một trong những điều mà tôi tin rằng khiến mọi người chấp nhận các đối tượng lớn là các chức năng có sẵn để nhập và xuất tệp trực tiếp từ máy chủ cơ sở dữ liệu sang hệ thống tệp của nó. Có một vấn đề ở đây:nếu ứng dụng nằm trên một máy chủ khác, bạn sẽ cần thêm mã để di chuyển tệp đến vị trí cần thiết.
Một vấn đề bạn có thể gặp phải
Những ngày trước, tôi đã phải kiểm tra một cơ sở dữ liệu được sử dụng để lưu trữ thông tin về các phiên người dùng từ hệ thống Java CAS. Tôi thấy có gần 100 triệu đối tượng lớn trong cơ sở dữ liệu, không phải là những đối tượng quá lớn.
Tôi đã xem qua bảng người dùng để kiểm tra các trường có oid và sau đó tôi tham chiếu chéo các giá trị trong các trường đó với pg_largeobject_metadata bàn. Tôi thấy rằng 96% những đồ vật lớn đó là những đồ vật mồ côi. Đó là những đối tượng lớn không được tham chiếu bởi bất kỳ bộ giá trị nào từ bảng người dùng.
Điều tra thêm đã kết luận rằng Hibernate không quan tâm đến việc xóa các đối tượng lớn mà nó tạo ra khi xóa hoặc cập nhật các bộ giá trị có các trường oid. Vì vậy, nó đã tạo ra một lượng lớn khối phồng mà không thể làm sạch bằng cách hút bụi mà phải được loại bỏ khỏi bảng pg_largeobjects theo cách thủ công.
Trong trường hợp cụ thể của cơ sở dữ liệu CAS, truy vấn này được dùng để xác định các đối tượng lớn vẫn đang được sử dụng:
SELECT unnest(array[expiration_policy, authentication, services_granted_access_to]) FROM public.ticketgrantingticket UNION SELECT unnest(array[expiration_policy, service]) FROM public.serviceticket
Truy vấn có thể được sử dụng để loại trừ khỏi danh sách các đối tượng lớn cần loại bỏ những đối tượng nào. Một cái gì đó như thế này:
SELECT lo_unlink(pg_largeobject_metadata.oid) FROM pg_largeobject_metadata WHERE pg_largeobject_metadata.oid NOT IN ( SELECT unnest(array[expiration_policy, authentication, services_granted_access_to]) FROM public.ticketgrantingticket UNION SELECT unnest(array[expiration_policy, service]) FROM public.serviceticket )
Kết luận
Các đối tượng lớn có các vấn đề của chúng, giống như các loại dữ liệu khác (đặc biệt là khi sử dụng các loại để lưu trữ dữ liệu nhị phân lớn). Các nhà phát triển và quản trị viên cơ sở dữ liệu tùy thuộc vào việc tận dụng những ưu điểm và giảm thiểu nhược điểm.
Chúng tôi đã đưa ra một truy vấn khả thi để thực hiện việc dọn dẹp, nhưng cũng có một tiện ích mở rộng tuyệt vời giúp dọn dẹp các đối tượng lớn bị mất tích bằng trình kích hoạt:Trình quản lý đối tượng lớn
Một số người có thể thích chạy truy vấn thanh lọc trong những giờ yên tĩnh thay vì thực hiện trình kích hoạt vào mỗi CẬP NHẬT và XÓA . Trên các hệ thống có CẬP NHẬT rất rất thấp và / hoặc XÓA tỷ lệ, một trình kích hoạt trên mỗi bảng có oid lĩnh vực này, có vẻ là một giải pháp thanh lịch hơn. Và bất kỳ sự mất hiệu suất nào do phải thực thi chức năng kích hoạt sẽ là không cần thiết.
Trong mọi trường hợp, các đối tượng lớn vẫn có nhiều người hâm mộ, rất có thể là do các chức năng bên trong được cung cấp để nhập và xuất dữ liệu nhị phân trực tiếp vào hệ thống tệp cục bộ. Với bytea, bạn thường sử dụng nhiều bộ nhớ hơn ở cấp ứng dụng. Đây là một thủ tục rất phổ biến để đọc hoàn toàn trường nhị phân thành một biến sau đó xử lý nó.
Tôi có thể viết điều gì đó về việc sử dụng bytea mà tôi đã sử dụng trong một trong những phát triển trước đây của mình trong một bài đăng blog trong tương lai.