PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Objek Besar sialan itu

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rumus Koefisien Korelasi Pearson dalam SQL

  2. Tetapkan nilai dalam ketergantungan bagan Helm

  3. Cara terbaik untuk menghitung catatan dengan interval waktu sewenang-wenang di Rails+Postgres

  4. Bagaimana saya bisa menggunakan UUID di SQLAlchemy?

  5. Fungsi Postgres mengembalikan tabel tidak mengembalikan data dalam kolom