2017-02-08 7 views
0

J'ai mis en place une gestion simple des droits, basée sur l'ajout binaire.MySQL: Sélectionnez Items pour une navigation basée sur les droits binaires

Chaque entrée de navigation dans ma base de données suit cette structure:

Navigation Entries Table et ainsi de suite ..

Chaque utilisateur a son propre niveau d'accès ..

user = 3 (1 + 2 - niveau d'accès) admin = 15 (1 + 2 + 4 + 8)

Jusqu'ici tout va bien. Mon problème est maintenant, en sélectionnant les champs correspondants de la table via MySQL. Ma première approche était de sélectionner toutes les entrées avec un access_level < = la somme des utilisateurs access_level, mais très vite je me suis rendu compte que cela incluait aussi d'autres pages avec un access_level inférieur.

+0

mai i demander pourquoi cette approche? – PhpDude

Répondre

1

Vous devez utiliser un binaire ET pour voir si le bit est défini. vous pouvez également utiliser un champ ensemble. c'est aussi un bitfield avec nommer chaque bit.

ET comme ceci:

WHERE (access_level & 15); 

échantillon - create table et remplir

mysql> CREATE TABLE `access_table` (
    -> `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    -> `item_text` VARCHAR(32) DEFAULT NULL, 
    -> `url` VARCHAR(32) DEFAULT NULL, 
    -> `access_level` SET('home','help','backend','admin') DEFAULT NULL, 
    -> PRIMARY KEY (`id`) 
    ->) ENGINE=INNODB DEFAULT CHARSET=utf8; 
Query OK, 0 rows affected (0,02 sec) 

mysql> 
mysql> INSERT INTO `access_table` (`id`, `item_text`, `url`, `access_level`) 
    -> VALUES 
    ->  (1, 'home', '/home', 'home'), 
    ->  (2, 'help', '/help', 'help'), 
    ->  (3, 'backend', '/backend', 'backend'), 
    ->  (4, 'hoadmpage', '/admin', 'admin'); 
Query OK, 4 rows affected (0,00 sec) 
Records: 4 Duplicates: 0 Warnings: 0 

mysql> 

échantillon - afficher toutes les lignes et sélectionnez une par les bits

mysql> SELECT *,access_level+0 FROM ACCESS_TABLE; 
+----+-----------+----------+--------------+----------------+ 
| id | item_text | url  | access_level | access_level+0 | 
+----+-----------+----------+--------------+----------------+ 
| 1 | home  | /home | home   |    1 | 
| 2 | help  | /help | help   |    2 | 
| 3 | backend | /backend | backend  |    4 | 
| 4 | hoadmpage | /admin | admin  |    8 | 
+----+-----------+----------+--------------+----------------+ 
4 rows in set (0,00 sec) 

mysql> 
mysql> SELECT *,access_level+0 
    -> FROM ACCESS_TABLE 
    -> WHERE (access_level & 15); 
+----+-----------+----------+--------------+----------------+ 
| id | item_text | url  | access_level | access_level+0 | 
+----+-----------+----------+--------------+----------------+ 
| 1 | home  | /home | home   |    1 | 
| 2 | help  | /help | help   |    2 | 
| 3 | backend | /backend | backend  |    4 | 
| 4 | hoadmpage | /admin | admin  |    8 | 
+----+-----------+----------+--------------+----------------+ 
4 rows in set (0,00 sec) 

mysql> SELECT *,access_level+0 
    -> FROM ACCESS_TABLE 
    -> WHERE (access_level & 7); 
+----+-----------+----------+--------------+----------------+ 
| id | item_text | url  | access_level | access_level+0 | 
+----+-----------+----------+--------------+----------------+ 
| 1 | home  | /home | home   |    1 | 
| 2 | help  | /help | help   |    2 | 
| 3 | backend | /backend | backend  |    4 | 
+----+-----------+----------+--------------+----------------+ 
3 rows in set (0,00 sec) 

mysql> SELECT *,access_level+0 
    -> FROM ACCESS_TABLE 
    -> WHERE (access_level & 9); 
+----+-----------+--------+--------------+----------------+ 
| id | item_text | url | access_level | access_level+0 | 
+----+-----------+--------+--------------+----------------+ 
| 1 | home  | /home | home   |    1 | 
| 4 | hoadmpage | /admin | admin  |    8 | 
+----+-----------+--------+--------------+----------------+ 
2 rows in set (0,00 sec) 

mysql> 
+0

c'était loin la meilleure réponse que j'ai jamais eu ici. Merci beaucoup. Je n'ai jamais pensé que la solution serait aussi simple. Merci!! –

+1

désolé - voici une autre utilisation avec ** IN ** qui peut mieux lire (seulement) si vous voulez ** WHERE (niveau d'accès IN ('home', 'help', 'admin')); ** afin que vous puissiez diriger Précisez ce que vous cherchez –