ビットマスク
ビットマスクの元々の問題は、データモデリングの規則に反することです(こことここをさらに読んで、ここで別の回答で表現されています)。4バイトの符号付き整数には、異なる値(整数で)のみが含まれる場合があり、それらを使用すると計算が困難になります。このトピックについて説明する前に、Stack Overflowについてさまざまな質問がありました。これは、bistmasksがどのように機能するかを理解するために使用しました。31
2 147 483 648
テストでは、ビットマスクの操作が難しいことも明らかになりました。ビット単位の演算子を理解する必要があり、移行は基本的に不可能になります。(不可能とは、最初はビットマスクを実装するのは良いことのように思えましたが、結局のところ、見返りとして得られるメリットと比較して、多額の費用がかかることがわかりました。)基本的なポータルのようなWebサイトを利用します。。私はいいえを意味します。StackOverflowを利用する例として、そしてそれが持っているユニークな特権の量。私は実際に数えようとしましたが、複雑さを失いましたが、必要な量は、31の一意の値という前述の障壁をまだ超えていないとしても、はるかに近いものです。ビットマスクの意味を変更するプロジェクトの更新により、再計算が長時間必要になる可能性が非常に高く、データベースエラーが発生すると、エラーが発生しやすくなります。
正確で正確なタイミングの数値はわかりませんが、ビットマスクの使用はACLよりも遅いと感じました。データベースのサイズ、メモリ、ストレージのフットプリントを比較すると、より大きくなり、リレーショナルデータベースとインデックス作成機能を利用する機会が少なくなります。Webサイトでのユーザー権限については、他の方法を使用する場合、ビットマスクは使用できません。
ビットマスクが機能するさまざまなシステム、つまりMaNGOS(私が最初にアイデアを思いついた)がありitem_template
、他のさまざまなテンプレートテーブルがビットマスクを使用するフラグを定義します。しかし、肝心なのは、これらのテーブルでは、値が変更される可能性は低く、ユーザーが任意に特権を取得および失うWebサイトとは対照的に、計算は読み取り専用であるということです。
サンプルコード
define('U_NIL', 0);
define('U_EXEC', 1);
define('U_WRIT', 2);
define('U_READ', 4);
$our_perm = 7;
$req_perm = U_EXEC | U_WRIT | U_READ;
var_dump( ($our_perm & $req_perm) == $req_perm ); # Will be bool(true)
$our_perm = 3;
var_dump( ... The same thing ...); # Will be bool(false)
$our_perm = U_READ;
$req_perm = U_READ | U_WRIT;
var_dumo(...); # Will be bool(false)
$our_perm = U_READ | U_WRIT | U_EXEC;
$req_perm = U_READ;
var_dump(...); # Will be bool(true)
その他。
他のさまざまな 質問がメソッドを適切に説明しているので、コード行を割愛します。私がそれを説明することは決してできません。ビットマスクは素晴らしいようで、ビットマスクはエキゾチックなようですが、本番環境に定着させる意味はありません。
ACL
元の質問で説明されたもう1つのオプションは、リレーショナルデータベースとSQL言語を利用して、データベースにアクセス許可を設定することでした。データベースにさらに2つのテーブルを作成する必要があります。
CREATE TABLE `perm_relation` (
`row_id` int(10) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL,
`perm_id` int(10) NOT NULL,
PRIMARY KEY (`row_id`),
UNIQUE `permission` (`user_id`, `perm_id`)
) ENGINE=InnoDB;
CREATE TABLE `permission` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
PRIMARY KEY (`row_id`)
) ENGINE=InnoDB;
perm_relation.perm_id
を指す外部キーになりpermission.id
、とperm_relation.user_id
の関係になりusers.id
ます。この後は、プログラミングロジックをどのように組み合わせるかだけが問題になります。
SELECT row_id FROM perm_relation
WHERE perm_id = (SELECT id FROM permission WHERE name = "U_SUPERADMIN")
AND user_id = CURRENT_USER_ID;
この方法を使用して、互換性の向上、実行の迅速化、移行の容易化を実現します。新しい権限を定義することと、任意のユーザーに一部を付与することの両方として、新しい権限を追加するのにほんの少しの時間しかかかりません。削除も同様に簡単で、テーブルを最適化して孤立した全体を削除するのに必要なSQLクエリはわずかです(たとえば、システムで定義された関連する権限なしに権限が付与されているユーザー)。
このシステムをPHP環境に実装しているため、この権限リストに依存する多くの機能を備えたある種の管理ページがあると想定できます。ユーザーが持っている権限でフィルタリングされたユーザーを一覧表示する例は、1つの例です。JOIN
このコンテキストでは、ACLはビットマスクよりもはるかに優れています。これは、ステートメントをさらに活用できるためです。
結論は、ビットマスクとリレーショナルパターンには異なる目的があるということです。上記のMaNGOSの例では、リレーショナルテーブルはやり過ぎになりますが、ビットマスクはユーザー権限システムには多すぎて非常にかさばります。