Haruskah saya menggunakan bit string PostgreSQL?

18

Saya telah belajar tentang bit stringtipe data belakangan ini, dan saya cukup ingin tahu tentang:

  1. Di bagian bawah halaman dokumen ini ada kalimat:

    ... ditambah 5 atau 8 byte overhead tergantung pada panjang string

  2. Bagaimana bit string ditangani dalam bahasa lain seperti PHP, Java, C #, C ++, dll., Melalui driver seperti Npgsql, ODBC, dll.

Untuk pertanyaan # 1, menggunakan smallint atau bigint akan jauh lebih efisien penyimpanan, dan mungkin akan menawarkan peningkatan kinerja karena bilangan bulat didukung di mana-mana. Sebagian besar bahasa pemrograman menangani operasi bit pada bilangan bulat dengan mudah. Jika itu masalahnya, apa gunanya memperkenalkan tipe data bit-string? Apakah ini Hanya untuk kasus yang membutuhkan sedikit topeng? Pengindeksan bidang bit mungkin? Saya lebih ingin tahu tentang bagaimana pengindeksan bidang bit dilakukan di PostgreSQL.

Untuk # 2, saya bingung, lebih dari sekadar ingin tahu. Sebagai contoh, bagaimana jika saya menyimpan topeng bit hari minggu di bidang bit (7), satu bit untuk sehari, dengan bit terendah mewakili hari Senin. Lalu saya meminta nilai dalam PHP dan C ++. Apa yang akan saya dapatkan? Dokumentasi mengatakan saya akan memiliki string bit, namun string bit bukanlah sesuatu yang dapat saya gunakan secara langsung - seperti halnya integer. Maka dalam hal ini, haruskah saya menyerah pada bidang bit?

Adakah yang bisa menjelaskan mengapa dan kapan saya harus menggunakan sedikit atau sedikit variasi?

Jackey Cheung
sumber
2
Jawaban Erwin pada SO sangat bagus (dan jika Anda tidak keberatan menyalinnya ke @Erwin, akan berguna jika ada di sini), tetapi saya ingin menambahkan kehati-hatian saya sendiri: dalam kebanyakan kasus Anda tidak akan merenungkan menyimpan informasi dalam bit string pada RDBMS - menggunakan kolom boolean terpisah dalam solusi normal terlepas dari 'efisiensi' penyimpanan.
Jack Douglas
@ JackDouglas: Saya tidak keberatan menyalin jawaban saya. Saya bertanya-tanya: apakah menduplikasi jawaban di situs SE adalah ide yang bagus?
Erwin Brandstetter
@ Erwin Saya tidak mengerti mengapa tidak - ada beberapa tumpang tindih antara situs dan keduanya seharusnya berdiri sendiri (jadi misalnya kita tidak akan - dan lagi pula tidak bisa - menutup pertanyaan di sini sebagai duplikat jika ada pertanyaan identik pada SO). Fokus kami lebih pada masalah 'ahli', tetapi IMO jawaban Anda sesuai dengan kategori yang ada :)
Jack Douglas
@ JackDouglas: Yah, masuk akal. Dan bagaimana mungkin aku bisa tidak setuju setelah pujian yang kau berikan itu? ;)
Erwin Brandstetter

Jawaban:

18

Jika Anda hanya memiliki beberapa variabel, saya akan mempertimbangkan untuk menjaga booleankolom terpisah .

  • Pengindeksan mudah. Secara khusus, indeks pada ekspresi mudah.
  • Kondisi untuk kueri dan pengindeksan parsial mudah untuk ditulis dan dibaca dan bermakna.
  • Kolom boolean menempati 1 byte. Untuk hanya beberapa variabel ini menempati ruang paling sedikit.
  • Berbeda dengan kolom boolean opsi lain memungkinkan NULLnilai untuk bit individual jika Anda membutuhkannya. Anda selalu dapat menentukan kolom NOT NULLjika tidak.

Mengoptimalkan penyimpanan

Jika Anda memiliki lebih dari satu variabel penuh tangan tetapi kurang dari 33, sebuah integerkolom dapat memberikan yang terbaik bagi Anda. (Atau biginthingga 64 variabel.)

  • Menempati 4 byte pada disk.
  • Pengindeksan sangat cepat untuk pencocokan tepat ( =operator).
  • Menangani nilai-nilai individual mungkin lebih lambat / kurang nyaman dibandingkan dengan bit stringatau boolean.

Dengan lebih banyak variabel, atau jika Anda ingin memanipulasi nilai-nilai banyak, atau jika Anda tidak memiliki tabel besar dan ruang disk / RAM tidak ada masalah, atau jika Anda tidak yakin harus memilih apa, saya akan mempertimbangkan bit(n)ataubit varying(n) .

  • Menempati setidaknya 5 byte (atau 8 untuk string yang sangat panjang) ditambah 1 byte untuk setiap kelompok 8 bit (dibulatkan ke atas).
  • Anda dapat menggunakan fungsi string bit dan operator secara langsung.

Contohnya

Untuk hanya 3 bit informasi, setiap booleankolom bertahan dengan 3 byte, integerkebutuhan 4 byte dan bit string6 byte (5 +1).

Untuk 32 bit informasi, yang integermasih membutuhkan 4 byte, bit stringmenempati 9 byte untuk yang sama (5 + 4) dan booleankolom menempati 32 byte.

Bacaan lebih lanjut

Erwin Brandstetter
sumber
Ya aku setuju denganmu. Saat ini, saya menggunakan samllint untuk menyimpan bit mask di hari kerja. Ini cocok dengan kasus ini, efisiensi penyimpanan / kinerja luas. Namun, jika saya akan memiliki lebih banyak pengindeksan / penyaringan pada topeng bit, itu akan gagal, karena kinerja yang rendah.
Jackey Cheung
3

Semua tipe PostgreSQL berguna untuk beberapa hal dan kurang bermanfaat untuk yang lain. Secara umum, Anda mendapatkan lebih banyak dari mengkhawatirkan fungsionalitas terlebih dahulu dan kinerja nanti. PostgreSQL memiliki sejumlah besar fungsi untuk memanipulasi berbagai jenis tipe data dan ini tidak terkecuali.

Saya harapkan pada lapisan aplikasi, kecuali driver db Anda menanganinya melalui semacam konversi jenis, Anda akan mendapatkan representasi string dan harus menangani ini. Jadi mungkin bermanfaat atau tidak berguna dalam kapasitas itu.

Di mana itu mungkin berguna adalah ketika Anda ingin memilih catatan berdasarkan pada operasi bitwise, seperti bitwise atau atau bitwise dan, atau memanipulasi data dalam query SQL. Kecuali jika Anda melakukan ini, banyak fitur PostgreSQL yang lebih esoteris kurang membantu.

Perhatikan juga untuk string informasi biner yang lebih panjang ada antarmuka objek besar yang memungkinkan Anda melakukan streaming dll. Dan antarmuka bytea yang memungkinkan representasi string yang lebih ringkas.

tl; dr: Jika Anda membutuhkannya, Anda akan tahu itu. Kalau tidak, simpan file itu di bagian "khusus untuk penggunaan di masa mendatang" di pikiran Anda.

Chris Travers
sumber