web-dev-qa-db-ja.com

データベースでビットマスクを使用する利点と欠点

少し前に同僚と話をしましたが、データベースに格納されているすべての値を理解することが難しいため、ビットマスクを使用することは絶対に反対でした。私の意見では、たとえば現在のユーザーの役割を決定するために、それらを使用することは必ずしも悪い考えではありません。それ以外の場合は、別のテーブルに格納する必要があります。これにより、JOINがもう1つ発生します。私が間違っているかどうか教えてもらえますか?他の副作用、ビットマスクを使用することの利点/欠点?

22
Alex Ovechkin

ユーザーの役割割り当てを格納するためにビットマスクを使用するアプリケーションを使用しています。お尻の痛みです。これが私を偏ったものにするなら、有罪として有罪。

すでにリレーショナルデータベースを使用している場合、それはほとんどのリレーショナル理論とすべての正規化ルールに違反するアンチパターンです。独自のデータストレージを構築する場合、それほど悪い考えではないかもしれません。

結合されるテーブルが多すぎるなどのことがありますが、これを処理するためにリレーショナルデータベースが構築されています。インデックス、インデックス付きビューなど、パフォーマンスが問題になる場合、多くの機能に追加機能があります。検索している値が頻繁に変更されない場合でも、ビットマスクの利点は、インデックスを管理する必要があることのオーバーヘッドです。データベースはかなり簡単です。

データベースはデータを集約するのに適していますが、複雑な数式やスカラー関数などをデータセットに導入し始めると、データベースが遅くなる可能性があります。アプリでビット単位で行うこともできますが、関連するデータを取得すること(ユーザーの役割を検索すること)だけを行っている場合は、データストレージの利点を最大限に活用できていません。

それに対する私の最後の議論は、他の開発者にとって単純であろう。ユーザー、役割、割り当てがあります。これは多対多のリレーションセットであり(複数のリレーションシップがあるため)、非常に一般的であり、管理が容易です。それは単なるCRUDのものです。

38
JeffO

関連する賛否両論をすでに挙げています。

  • ビットフィールドはスペースを節約します。
  • それらはレコード自体にデータを格納するので、それらを見つけるためにJOINは必要ありません。 (しかし、レコード内の個々のフラグフィールドも同じようになります。)
  • 生のSQL出力で生産的に作業したい場合は、読みにくくなります。

何をすべきかを決定するには、より多くの情報が必要です:

  • ユースケースのディスク容量はどれだけ不足していますか?
  • 実際にユーザーロールを頻繁に読み、それらを結合する時間がボトルネックになることはありますか?
  • Are SQL出力を読み取り、それに基づいて決定を下します-または、システムのマシンコードが読み取れないという事実のように、読み取り不可能なデータベースレコードは重要ではありませんか?

したがって、あなたがしなければならないことは、リスク要因を収集し、それからweightそれらを、プロが短所を上回るかどうかを確認することです。

24
Kilian Foth

もしあなたが本当にreallyreallyディスク容量に縛られているなら、あなた mightは、ユーザー権限のビットマップを検討します。パフォーマンスが気になる場合は、それらを完全に忘れてください。それらを分離すると実際に遅くなるためです。ビットマップ化されたフィールドを意味のある方法でindexできません。その結果、データベーステーブルスキャンが実行されます。

AmazonまたはNetflixでない限り、ユーザー権限に関連するデータのamountは、保持している他のすべてのものと比較してごくわずかです。

深刻なDBMSであれば、点滅することなくその「余分な結合」を処理できます。

18
Phill W.

ストレージが高価だった当時、ビットマスクの恩恵はスペースを節約したことでした。ビッグデータの時代には、これは以前の問題ではありません。

あなたが引用する例をとると-ビットマスクとして格納されたロールを持つことは、データベース設計の観点からは 第1正規形 に違反するため、コードの匂いのようなものになります。この意味で、それらはアンチパターンです。

このすべてが言われている、それはどちらかである必要はありません。データをビットマスクとして保存し、その場でユーザーロールを取得できるビューを用意できます。また、どのユーザーが同じ役割を持っているかを一目で確認できるというメリットもあります。

8
Robbie Dee

ビットマスクを使用する唯一の利点は、ビットフィールドの意味が静的でない場合です。リレーショナルテーブルは、レコードの各フィールドが事前にわかっている場合にのみ機能します。結局、CREATE TABLE DDLステートメントでフィールドを識別する必要があります。

If各ビットフィールドの意味が実行時に構成可能であるか、さもなければ事前にわからない場合、それは可能性がありますブール値をビットフィールドとして格納することは理にかなっています。それでも、任意のフィールド(field_1field_2など)を使用してテーブルを定義することが可能です。これにより、理想的ではありませんが、よりクリーンなリレーショナルデザインが得られます。どちらのソリューションも理想的ではないため、これがビットフィールドよりも優先されるかどうかは、主に意見の問題です。

開発中にビットが何を表すかがわかっている場合は、ビットごとにフィールドを作成し、意味のある名前を付けます

内部プラットフォーム効果 に注意してください。結局のところ、適切で型付けされた任意のフィールドを定義することになりますが、それよりも遠すぎると、リレーショナルデータベースを再発明することになります...リレーショナルデータベースの内部。

2
user22815

私はビットマスクについて曖昧です。彼らの中傷者のほとんどは2進数と16進数を理解していません。明確にするために、適切なニーモニックを使用してください。

上記で言及されていない利点は、時間のかかる新しい列を追加することなく、ビットマスクに新しい意味を追加できることです。私たちの前のDBデザイナーは、毎日500万件の新しいレコードを取得するテーブルにそれらを入れています。新しい動作を表す新しい列を追加するには長い時間がかかりますが、新しいビット(64のうち33を消費しました)を定義すると、テーブルを再構築する必要がありません。

いいえ、ビットマスクにインデックスを付けることはできませんが、33個のインデックスを作成するとばかげて、クロールへの挿入が遅くなります。テーブル検索は日付とレコードの「所有者」インデックスを使用するため、このビットマスクのインデックスは、可能であれば使用されません。

2
G B

目的がディスク容量を節約することだけである場合、それは悪い考えだと思います。

  • 今日のGBのコストを見て、
  • レポートとクエリを作成し、フィールドの内容と特定のビットに対処する方法を理解する必要がある人の時間のコストと比較すると、コスト/メリットの比較が間違った側で終わる可能性があります。
  • sQLデータベースを使用している場合、多くのクエリで必要な追加のビットアクセス操作も、必要以上の計算時間を消費する可能性があります

ただし、ビットフィールドの使用を正当化できる場合もあります。

  • ビットが常に全体として常に一緒に処理する複雑なフラグのセットを表す場合、
  • さらに、これらのセットにパターンマッチングアルゴリズムを適用する必要がある場合は、
  • 特に、このデータが最も頻繁に使用される選択基準に含まれていない場合。
1
Christophe