SQLとフラグ

もちろん、それはSQLサーバーのCapture The Flagゲームモードではなく、ビットフラグの使用に関するものです。 ビット操作は、環境や開発言語に関係なく、おそらくパン操作に関係するすべての人によく知られています。 しかし、私の意見では、フラグの使用は日常的なツールよりも多くの人にとってエキゾチックです。 Habréでは、enumを介してフラグを操作する便利な.NET機能の可能性が何度も言及されていますが、SQLを使用するとフラグを使用する絶好の機会も得られます。



それで、簡単な例を見てみましょう-特定のアプリケーションでは、特定のユーザー通知システムがあるはずです。 フォーラムを構築していて、ユーザーがメールで通知を受信できるようにするとします:選択したトピックの新しい応答、新しい個人的なメッセージ、フォーラムニュースタスクを簡単に確認すると、簡単なテーブルデザインが得られます。

tblUsers {userID(PK)int、name as nvarchar(50)、password as nvarchar(50)}

tblUserAlerts {intとしてのuserID(FK)、intとしてのalertID(FK)}

tblAlerts {intとしてのアラートID(PK)、nvarcharとしてのメッセージ(50)}





つまり、ユーザーテーブル、アラートのテーブルがあり、各ユーザーが複数のアラートを選択できるようにするために、それらの関係は補助テーブルを介して実装されます。 データは次のようになります。

tblUsers

1、「Vasya」、「slypryp4r0l」



tblUserAlerts

1、1



tblAlerts

1、「新しいプライベートメッセージを受信しました」



次に、フラグを使用した例を見てみましょう。

tblUsers {ユーザーID(PK)int、名前nvarchar(50)、パスワードnvarchar(50)、アラートint}、

tblAlerts {intとしてのアラートID(PK)、nvarcharとしてのメッセージ(50)}



このオプションでは、同じ機能を取得し、追加のテーブルなしで実行します。 tblAlertsテーブルでは、同じintを使用してalertIDをフラグビットとして設定し(サイズはアラートオプションの数によって異なります)、tblUsersテーブルでは、アラートフィールドにアラートマスクビットが表示されます。 3種類のアラートを作成するとします。したがって、tblAlertsテーブルには、alertIDフィールドにフラグがある4(アラートなし+前述の3タイプ)行があります。 最初のIDは0になります-ビットでは、それぞれ0000の値になります-通知はありません。 次に、毎回異なるビットを点灯してアラートを追加します(各識別子は2の累乗になります):0001 = 1、0010 = 2、0100 = 4:

tblAlerts

0、NULL

1、「選択したトピックの新しい回答」

2、「新しいプライベートメッセージを受信しました」

4、「ニュースがあります!」



次に、たとえば、ニュースやプライベートメッセージに関するアラートにユーザーを登録する必要があります。 これを行うには、これらのアラートの識別子を要約し、0110 = 6を取得します。

tblUsers

1、「Vasya」、「slypryp4r0l」、6



次に、tblUsersテーブルにクエリを作成して、ニュースを購読しているユーザーを見つけましょう。

SELECT * FROM tblUsers WHERE (tblUsers.alert & 4) > 0







この操作の意味は簡単です:

0110-マスク

0100-ニュースフラグ

0100-結果(つまり、マスクとフラグの共通部分がある場合、結果はゼロより大きくなります)



良い面-あなたは比較してマスクすることができます。 すべてのタイプのアラート1 + 2 + 4 = 7にサブスクライブしているユーザーのリストを取得するとします。

SELECT * FROM tblUsers WHERE (tblUsers.alert & 7) = 7







マスク6と7の間に交差点がありますが、結果は7とは異なることに注意してください

0110-ユーザーマスク

0111-検証マスク

0110-結果(7または6の交差または最小= 6)



同様に、返信の通知またはプライベートメッセージの通知1 + 2 = 3のいずれかにサブスクライブしているユーザーのリストに要求を行うことができます。

SELECT * FROM tblUsers WHERE (tblUsers.alert & 3) > 0







肯定的な結果は、1、2、および3の値(つまり、2つのアラートのいずれか、または両方)でユーザーマスクをチェックすると見なされます。



このような簡単な方法で、ミドルウェアテーブルを削除し、クエリを簡素化することもできます。 ただし、標準では識別子が比較されるため、標準の視覚的なクエリエディターを介して何らかのアクション(JOINなど)を実行することはできない場合があります。 比較をビット操作で手動で置き換える必要があります。

SELECT tblUsers.*, tblAlerts.*

FROM tblUsers INNER JOIN tblAlerts ON (tblUsers.alerts & tblAlerts.alertID) = tblAlerts.alertID








All Articles