Pengantar
PostgreSQL memberi pengembang kesempatan untuk memilih di antara dua kemungkinan fasilitas penyimpanan untuk data biner besar:Bytea dan LargeObjects.
Objek Besar telah ada sejak lama, dan PostgreSQL memiliki cara cerdas untuk menyimpan data biner besar. Ia melakukannya dengan membaginya menjadi potongan-potongan LOBLKSIZE (keempat dari BLCKSZ). Dengan begitu tupel dari pg_largeobject tidak tumpah di atas meja roti panggang.
Sebaliknya bytea menyimpan data biner secara langsung di tuple, yang dapat menyebabkan kinerja yang buruk tergantung pada tampilan skema Anda.
Kedengarannya bagus jika Anda memiliki antarmuka yang cerdas untuk menangani manipulasi file biner ini, khususnya jika pembaruan hanya memodifikasi sebagian kecil dari keseluruhan file biner.
Tapi biasanya kami tidak repot menulis kode yang memanfaatkan ini, dan sebaliknya kami menulis lagi seluruh data biner.
Salah satu hal yang saya yakini membuat orang mengadopsi objek besar adalah fungsi yang tersedia untuk mengimpor dan mengekspor file langsung dari server database ke sistem filenya. Ada kontra untuk ini:jika aplikasi berada di server yang berbeda, Anda akan memerlukan lebih banyak kode untuk memindahkan file ke lokasi yang diperlukan.
Masalah yang mungkin Anda hadapi
Beberapa hari terakhir saya harus memeriksa database yang digunakan untuk menyimpan informasi sesi pengguna dari sistem Java CAS. Saya menemukan ada hampir 100 juta objek besar dalam database, tidak terlalu besar.
Saya memeriksa tabel pengguna memeriksa bidang yang memiliki oid bidang, lalu saya melakukan referensi silang nilai dalam bidang tersebut dengan pg_largeobject_metadata meja. Saya menemukan bahwa 96% dari benda-benda besar di mana yang yatim piatu. Itu adalah objek besar yang tidak direferensikan oleh tuple mana pun dari tabel pengguna.
Penyelidikan lebih lanjut menyimpulkan bahwa Hibernate tidak mengurus pembersihan objek besar yang dibuatnya saat menghapus atau memperbarui tupel dengan bidang oid. Jadi itu menghasilkan sejumlah besar kembung yang tidak dapat dibersihkan dengan menyedot debu, tetapi harus dibersihkan dari tabel pg_largeobjects secara manual.
Dalam kasus khusus database CAS, kueri ini berfungsi untuk mengidentifikasi objek besar yang masih digunakan:
SELECT unnest(array[expiration_policy, authentication, services_granted_access_to]) FROM public.ticketgrantingticket UNION SELECT unnest(array[expiration_policy, service]) FROM public.serviceticket
Kueri dapat digunakan untuk mengecualikan dari daftar objek besar mana yang akan dihapus. Sesuatu seperti ini:
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 )
Kesimpulan
Objek besar memiliki masalah, sama seperti tipe data lainnya (terutama saat menggunakan tipe untuk menyimpan data biner besar). Terserah pengembang dan administrator database untuk mengambil keuntungan dari pro dan mengurangi kontra.
Kami memberikan kueri yang memungkinkan untuk melakukan pembersihan, tetapi ada juga ekstensi yang bagus yang membersihkan objek besar yatim piatu dengan pemicu:Pengelola Objek Besar
Beberapa orang mungkin lebih suka menjalankan kueri pembersihan selama jam tenang daripada menjalankan pemicu pada setiap UPDATE dan HAPUS . Pada sistem dengan PEMBARUAN yang sangat, sangat rendah dan/atau HAPUS rate, pemicu untuk setiap tabel yang memiliki oid lapangan, tampaknya solusi yang lebih elegan. Dan kehilangan performa karena harus menjalankan fungsi pemicu akan menjadi tidak berguna.
Bagaimanapun, objek besar masih memiliki penggemar yang hebat, kemungkinan besar karena fungsi internal yang disediakan untuk mengimpor dan mengekspor data biner langsung ke sistem file lokal. Dengan byte Anda biasanya menggunakan lebih banyak memori di tingkat aplikasi. Ini adalah prosedur yang sangat umum untuk membaca bidang biner sepenuhnya menjadi variabel dan kemudian memprosesnya.
Saya mungkin menulis sesuatu tentang menggunakan byte yang saya gunakan di salah satu pengembangan masa lalu saya di posting blog mendatang.