Keuntungan dan kerugian menggunakan topeng bit dalam database

22

Belum lama ini saya berbicara dengan kolega saya dan dia jelas-jelas menentang penggunaan topeng bit karena sulit untuk memahami semua nilai yang disimpan dalam database. Menurut pendapat saya tidak selalu ide buruk untuk menggunakannya, misalnya untuk menentukan peran pengguna saat ini. Kalau tidak, Anda perlu menyimpannya di tabel terpisah, yang akan menyebabkan satu lagi BERGABUNG. Bisakah Anda memberi tahu saya jika saya salah? Adakah efek samping lain, keuntungan / kerugian dari penggunaan bit mask?

Alex Ovechkin
sumber
2
Mungkin lebih masuk akal untuk memiliki basis data membuat topeng bit secara internal dan menyajikan bit sebagai kolom terpisah untuk Anda. Persyaratan Anda dapat berubah.
Simon Richter
1
Jika Anda tidak menggunakan gabungan, Anda tidak menggunakan basis data relasional seperti yang dimaksudkan.
Pieter B

Jawaban:

38

Saya bekerja dengan aplikasi yang menggunakan bitmasks untuk menyimpan tugas peran pengguna. Rasa sakit di pantat. Jika ini membuat saya bias, bersalah seperti yang dituduhkan.

Jika Anda sudah menggunakan basis data relasional, ini merupakan anti-pola yang melanggar sebagian besar teori relasional dan semua aturan normalisasi. Ketika Anda membangun penyimpanan data Anda sendiri, itu mungkin bukan ide yang buruk.

Ada yang namanya terlalu banyak tabel yang bergabung, tetapi database relasional dibangun untuk menangani hal ini. Banyak yang memiliki fitur tambahan jika kinerja menjadi masalah: indeks, tampilan yang diindeks, dll. Bahkan jika nilai yang Anda cari tidak terlalu sering berubah, yang merupakan keuntungan bagi Bitmask, kelebihan dari keharusan mengelola pengindeksan adalah cukup mudah di database.

Meskipun database melakukan pekerjaan yang baik dalam mengumpulkan data, mereka bisa menjadi lamban ketika Anda mulai memperkenalkan hal-hal seperti rumus kompleks atau Fungsi Skalar ke dalam kumpulan data. Anda dapat melakukan bitwise di aplikasi Anda, tetapi jika semua yang Anda lakukan adalah mendapatkan data terkait (mencari peran pengguna), Anda tidak mengambil keuntungan dari apa yang dilakukan penyimpanan data Anda yang terbaik.

Argumen terakhir saya yang menentangnya adalah kesederhanaan untuk pengembang lain. Anda memiliki pengguna, peran, dan tugas. Ini set hubungan banyak-ke-banyak (karena ada lebih dari satu hubungan) yang sangat umum, itu harus mudah dikelola. Itu hanya hal-hal CRUD.

JeffO
sumber
8
Database relasional adalah tempat terburuk untuk bitmask. Biaya penyimpanan tidak begitu buruk lagi sehingga beberapa bergabung dan meja tambahan akan menghancurkan Anda. Itu tentu membuat segalanya lebih sulit untuk dipikirkan. Menyimpan izin sebagai bit (1/0) dalam database di tabel mereka sendiri dan mewakili mereka dalam kode dengan flag. Tampaknya cukup tepat dan layak. Pengembang mendapatkan flag sederhana dan DB telah menormalisasi tabel. Semua orang bahagia.
Mike McMahon
3
Setuju, saya digunakan untuk mendukung aplikasi yang menggunakan topeng bit untuk peran pengguna dan hak istimewa dalam database-nya. Itu adalah mimpi buruk. Menggunakan int 32 bit, kami kehabisan bit, jadi seseorang memiliki ide bagus untuk menambahkan lebih banyak topeng bit, dan kemudian dengan tumpang tindih, jadi bit 4 dalam satu kolom berarti bit 8 di kolom lain ini, dan mereka tidak sinkron. Aye aye aye. Sulit untuk mengindeks karena indeks menyimpan nilai kolom diskrit, bukan bit individual di dalamnya, sehingga Anda tidak dapat mencari baris where some_bit_mask & 12 > 0tanpa pemindaian baris-demi-baris.
Brandon
Pada akhir hari, banyak-ke-banyak user_role_mapatau user_priv_mapmeja akan cukup.
Brandon
@MikeMcMahon, bisakah Anda menyelam lebih dalam dalam desain tabel dan bagaimana saya harus memetakannya dalam kode untuk mencapai hasil yang Anda bicarakan?
Alex Ovechkin
2
@ usr - Never say never. Tentu Anda dapat menggunakan bitmasks, tetapi saya tidak akan menggunakannya dalam aplikasi yang menggunakan basis data relasional. Mungkin ada beberapa kasus tepi ketika berhadapan dengan data legacy atau kebutuhan super untuk kecepatan.
JeffO
24

Anda telah menyebutkan pro dan kontra yang relevan:

  • Bidang bit menghemat ruang.
  • Mereka menyimpan data dalam catatan itu sendiri, jadi Anda tidak perlu BERGABUNG untuk menemukannya. (Tetapi masing-masing bidang bendera dalam catatan akan melakukan hal yang sama.)
  • Mereka dapat dibaca dengan buruk jika Anda ingin bekerja secara produktif dengan output SQL mentah.

Memutuskan apa yang harus dilakukan memerlukan lebih banyak info:

  • Seberapa langka ruang disk untuk kasus penggunaan Anda?
  • Apakah Anda benar-benar membaca peran pengguna begitu sering sehingga waktu untuk BERGABUNG dengannya adalah hambatan?
  • Apakah Anda akan membaca output SQL dan membuat keputusan berdasarkan itu - atau apakah catatan basis data tidak dapat dibaca tidak material, seperti fakta bahwa kode mesin sistem Anda tidak dapat dibaca?

Jadi yang harus Anda lakukan adalah mengumpulkan faktor-faktor risiko dan kemudian menimbangnya , untuk melihat apakah pro lebih besar daripada kontra.

Kilian Foth
sumber
Terima kasih atas jawaban Anda, setuju sepenuhnya dengan pemikiran Anda, tetapi secara umum apakah ini anti-pola? Dan apakah Anda menggunakan topeng di proyek Anda?
Alex Ovechkin
12
@ Alex Tidak ada yang namanya "praktik terbaik" yang dapat memutuskan apa yang harus dilakukan dalam kasus Anda. Jika Anda sangat kekurangan ruang, menggunakan bidang bit adalah praktik terbaik. Jika Anda ingin menggunakan output SQL dalam laporan kepada CEO, menggunakan nama berbicara adalah praktik terbaik. Tetapi Anda adalah satu-satunya yang mengetahui keadaan ini, oleh karena itu komunitas tidak dapat memberi Anda resep yang selalu valid.
Kilian Foth
Mengambil argumen ruang sebagai "beri". Pertanyaan tentang apakah menggunakan bit mask berdiri atau jatuh pada apakah itu memberikan manfaat lebih dan di atas ini.
Robbie Dee
Anda juga SETIAP perlu memproses informasi dalam database, atau apakah itu selalu dibaca ke dalam aplikasi sebelum menggunakannya.
Ian
1
"Apakah Anda akan membaca output SQL dan membuat keputusan berdasarkan itu - atau apakah data base record yang tidak dapat dibaca tidak material, seperti fakta bahwa kode mesin dari sistem Anda tidak dapat dibaca?" Saya kira saya tidak dapat berbicara untuk semua pengembang, tetapi ketika saya sedang berkembang, sangat umum bagi saya untuk mulai memilih data dari DB untuk memahami atau memeriksa sesuatu. Jadi saya berpendapat bahwa biasanya , jawaban untuk ini adalah, "Ya, seseorang akan melakukannya."
jpmc26
18

Jika Anda benar-benar, benar-benar , benar-benar kekurangan ruang disk, maka Anda mungkin mempertimbangkan bitmap untuk hak akses pengguna. Jika kinerja adalah kekhawatiran Anda, lupakan saja semuanya, karena memisahkannya sebenarnya akan lebih lambat. Anda tidak dapat mengindeks bidang yang dipetakan secara bermakna, menghasilkan pemindaian tabel basis data, yang [hampir] selalu menjadi pembunuh kinerja.

Kecuali Anda Amazon atau Netflix, jumlah data yang terlibat dalam izin pengguna akan diabaikan dibandingkan dengan semua yang Anda pegang.

Setiap DBMS yang serius dapat menangani "gabung ekstra" itu tanpa berkedip.

Phill W.
sumber
7
+1: Basis data relasional yang baik dikembangkan oleh orang-orang yang benar-benar pandai dalam apa yang mereka lakukan. Siapa pun pada level yang perlu meredam sedikit kinerja terakhir yang mungkin Anda dapatkan dengan menggunakan bidang bit tidak perlu mengajukan pertanyaan. Modelkan data, kemudian temukan bagian yang tidak berkinerja.
Blrfl
Memiliki bergabung akan membuat kode aplikasi lebih kompleks, sehingga banyak yang turun ke MANA peran diproses.
Ian
4
@Ian memiliki gabung sepertinya tidak lebih rumit daripada perlu tahu cara menguraikan izin bitmasked.
Brad
@Brad, Pikirkan enum yang merupakan kumpulan flag di C #, dengan nilainya disimpan "sebagaimana adanya" dalam database, C # cold tidak dapat menjadi lebih sederhana. Jika gabungan digunakan, maka kode C # harus mengatasi hubungan "1 ke banyak".
Ian
Saya juga harus menambahkan bahwa jika Anda memiliki beberapa kolom boolean dalam sebuah tabel, sebagian besar database akan mencari cara untuk menekannya menjadi ruang sesedikit mungkin dan akan mengurus bit-twiddling untuk Anda.
Blrfl
8

Kembali ketika penyimpanan mahal, anugerah dengan topeng bit adalah mereka menghemat ruang. Pada hari-hari data besar, ini bukan masalah dulu.

Mengambil contoh yang Anda kutip - memiliki peran disimpan sebagai bit mask akan menjadi semacam bau kode dari sudut pandang desain database karena akan melanggar bentuk normal pertama . Dalam hal ini, mereka anti-pola.

Semua ini dikatakan, tidak harus satu atau yang lain. Anda bisa menyimpan data sebagai bit mask dan kemudian memiliki tampilan yang dapat menarik peran pengguna dengan cepat. Anda juga akan mendapat manfaat dengan melihat sekilas pengguna mana yang memiliki peran yang sama.

Robbie Dee
sumber
2

Satu-satunya keuntungan menggunakan bitmask adalah jika arti bit fields tidak statis. Tabel relasional hanya berfungsi dengan baik jika Anda tahu sebelumnya apa setiap bidang pada catatan: Anda harus mengidentifikasi bidang dalam CREATE TABLEpernyataan DDL.

Jika arti dari masing-masing bidang bit dapat dikonfigurasi saat runtime, atau sebaliknya tidak diketahui sebelumnya, maka mungkin masuk akal untuk menyimpan boolean sebagai bidang bit. Bahkan kemudian, adalah mungkin untuk menentukan meja dengan bidang sewenang-wenang: field_1, field_2, dll ini memberi Anda lebih bersih desain relasional, meskipun masih tidak ideal. Apakah ini preferensial untuk bidang bit sebagian besar adalah masalah pendapat, karena tidak ada solusi yang ideal.

Jika Anda tahu apa yang diwakili bit selama pengembangan, lalu buat bidang untuk setiap bit dan berikan nama yang bermakna .

Berhati-hatilah dengan efek platform bagian dalam . Jika Anda akhirnya mendefinisikan bidang yang acak tapi diketik dengan baik itu adalah satu hal, tetapi jika Anda melangkah terlalu jauh dari itu, Anda akan menemukan kembali basis data relasional ... di dalam basis data relasional.


sumber
2

Saya tidak setuju dengan bitmask. Saya menemukan sebagian besar pencela mereka tidak mengerti biner dan heksadesimal. Untuk kejelasan, gunakan mnemonik yang baik.

Keuntungan yang tidak disebutkan di atas adalah kemampuan untuk menambahkan makna baru ke topeng bit tanpa penambahan kolom yang berpotensi memakan waktu. Desainer db kami (yang mendahului saya) memilikinya di meja yang sekarang mendapat 5 juta catatan baru setiap hari. Menambahkan kolom baru untuk mewakili perilaku baru akan membutuhkan waktu yang lama, sementara mendefinisikan bit baru (kita telah mengkonsumsi 33 dari 64) tidak memerlukan tabel untuk dibangun kembali.

Tidak, topeng bit tidak dapat diindeks tetapi membangun 33 indeks akan menjadi konyol dan akan memperlambat penyisipan ke perayapan. Pencarian tabel menggunakan tanggal & catat indeks "pemilik", karenanya indeks pada topeng bit ini, jika mungkin, tidak akan pernah digunakan.

GB
sumber
Ini kasus yang menarik. Saya kira Anda dapat mencapai hal yang sama dengan cara yang halal dan eksplisit, dengan mendefinisikan kolom "cadangan" di atas meja, dan kemudian menggunakannya sesuai kebutuhan. Anda kemudian dapat setidaknya mengindeks kolom ini secara selektif, jika Anda memilih untuk melakukannya.
Steve
1

Jika tujuannya hanya untuk menghemat ruang disk, saya pikir itu ide yang buruk:

  • lihat biaya GB hari ini,
  • bandingkan dengan biaya waktu mereka yang menulis laporan dan pertanyaan dan harus mencari tahu apa yang ada di lapangan, dan bagaimana cara mengatasi bit tertentu, perbandingan biaya / manfaat mungkin berakhir di sisi yang salah.
  • jika Anda bekerja dengan database SQL, operasi akses bit tambahan yang diperlukan di banyak kueri mungkin juga menghabiskan lebih banyak waktu komputasi daripada yang diperlukan

Namun ada beberapa kasus, yang bisa jusitfiy penggunaan bidang bit:

  • jika bit Anda mewakili satu set bendera kompleks yang selalu Anda tangani bersama sebagai satu kesatuan,
  • bahkan lebih jika Anda perlu menerapkan beberapa algoritma pencocokan pola pada set ini,
  • dan terutama jika data ini tidak termasuk dalam kriteria seleksi yang paling sering digunakan.
Christophe
sumber