0

複数のビットフィールドを格納する必要がある MySQL テーブルがあります...

  • notification.id -- 自動番号 int
  • association.id -- ビット フィールド 1 -- 1 つまたは複数のアソシエーション ID (別のテーブルから取得) を格納します。
  • type.id -- ビット フィールド 2 -- この通知に適用される 1 つ以上のタイプを格納します (これも別のテーブルから取得)
  • notification.day_of_week -- ビット フィールド 3 -- 1 つ以上の曜日を格納します
  • notification.target -- 通知の送信先 -- データ型は関係ありません。このフィールドでインデックス付けや並べ替えを行うことはありませんが、おそらく電子メール アドレスを保存することになるからです。

ユーザーは、1 つまたは複数のタイプに対して、1 つまたは複数の関連付けで、1 つまたは複数の日にトリガーされるように通知を構成できます。このデータを格納するための迅速でインデックス可能な方法が必要です。

ビット フィールド 1 と 2 は、現在よりも多くの値を持つように拡張できます。現在、1 には 125、2 には 7 という高い値がありますが、どちらもさらに高くなると予想されます。

ビット フィールド 3 には曜日が格納されるため、可能な値は常に 7 つだけです。

特定の通知を送信する必要があるかどうかを判断するために、タイプ、関連付け、および日に基づいてこのテーブルをスキャンするスクリプトを頻繁に (数分ごとに) 実行する必要があります。クエリは高速である必要があり、新しいデータを簡単に追加できるほど優れています。必要に応じて結合やサブクエリなどを使用することはありませんが、これらがより高速になるとは想像できません。

最後の要件 - ここに 1000 の異なる通知が保存され、125 の関連付けの可能性、7 つのタイプ、および 7 つの曜日がある場合、単に整数を使用し、ビットフィールドを使用する代わりに行を使用するため、ビットフィールドを使用することが要件のようです。

ただし、私が聞いたところによると、特定の曜日、たとえば火曜日 (ビット フィールドの b0000100 など) からすべてを選択したい場合、ビット フィールドはインデックス化されていないため、実行できません...

SELECT * FROM \`mydb\`.\`mytable\` WHERE \`notification.day_of_week\` & 4 = 4;

私の理解では、これはインデックスをまったく使用しません。

インデックス可能な方法でこれを行う方法、または同様の方法について何か提案はありますか?

(私はかなり標準的な LAMP スタックに取り組んでおり、MySQL のインデックス作成がこれまたは同様の代替手段でどのように機能するかについての詳細を探しています。)

ありがとう!

4

2 に答える 2

0

あなたがやりたいことを達成するための「良い」方法(私が知っている)はありません。BIT データ型のサイズは 64 ビットに制限されていることに注意してください。

静的に定義できるビットの場合、MySQL は SET データ型を提供します。これは、ある意味で BIT と同じですが、別の意味で異なります。

たとえば、曜日の場合、列を定義できます

dow SET('SUN','MON','TUE','WED','THU','FRI','SAT')

組み込みの方法はありません (内部ビット表現を元に戻すことは知っていますが、列に 0 を追加するか、符号なしにキャストして、10 進表現を取得できます。

SELECT dow+0, CONVERT(dow,UNSIGNED), dow, ...

1  1  SUN
2  2  MON
3  3  SUN,MON
4  4  TUE
5  5  SUN,TUE
6  6  MON,TUE
7  7  SUN,MON,TUE

SET カラムがインデックスの先頭のカラムである場合、MySQL は「カバリング インデックス」を使用して、SET カラムの述語でクエリを満たすことができます。(つまり、EXPLAIN は 'Using where; Using index' を示します) しかし、MySQL は範囲スキャンを実行するのではなく、インデックスのフル スキャンを実行している可能性があります。(また、MyISAM エンジンと InnoDB エンジンの間には違いがあるかもしれません。)

SELECT id FROM notification WHERE FIND_IN_SET('SUN',dow)

SELECT id FROM notification WHERE (dow+0) MOD 2 = 1

しかし...この使用法は非標準であり、実際にはお勧めできません。1 つには、この動作は保証されておらず、MySQL は将来のリリースでこの動作を変更する可能性があります。

于 2012-08-02T21:48:28.893 に答える
0

これについてもう少し調査したところ、上で概説したようにインデックス作成を機能させる方法がないことに気付きました。そこで、曜日などのエントリを格納する補助テーブル (WordPress のメタ テーブル形式に似たもの) を作成しました。必要に応じてこれらのテーブルを結合します。幸いなことに、現時点で 10,000 を超えるエントリがあるとは予想していないため、すぐに参加できるはずです。

誰かが持っているなら、私はまだより良い答えに興味があります!

于 2012-08-07T13:06:49.953 に答える