SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 02.08.2012 17:12:37

ksado
Участник
Зарегистрирован: 02.08.2012
Сообщений: 3

Возможно ли построить такой запрос?

Для начала опишу задачу:
Необходимо написать хелпер для squid, который мог бы определять уровень доступа для пользователя, в зависимости от данных в БД. Сам хелпер пишу на С, но в процессе написания, столкнулся с проблемой написания запроса к БД. Хочу ограничится одним запросом для всех случаев.

В хелпер попадает два значения - имя пользователя и запрашиваемый сайт. Есть 3 таблицы данных:

Users
  -ID  (поле ид)
  -Name (имена пользователей)
  -Access (уровни доступа(1,2,3) для пользователей)

DstDomain
  -ID (поле ид)
  -site (сайты)
  -rlevel (уровни доступа(1,2,3) для сайтов)

Main - таблица соответствия уровня доступа к запрашиваемому сайту
Usr              Dst           level
No user      rlevel 1    Base
Access 1    rlevel 2    Limited
Access 2    rlevel 3    Normal
Access 3    ALL         Full

Уровень Limited должен включал все сайты с уровнем Base; уровень Normal должен включать все сайты с уровнем Limited и Base. НО НЕ НАОБОРОТ

допустим в запрос попадает пользователь, которого нет в таблице Users, тогда проверяется запрашиваемый сайт в таблице DstDomain и если он с уровнем доступа rlevel 1, то пользователю присваивается уровень Base, если запрашиваемого сайта нет в таблице DstDomain или он с каким то другим уровнем доступа(rlevel2 или rlevel3) то ничего не возвращается.

Вторая ситуация.
В запрос попадает пользователь с уровнем доступа 1, тогда если запрашиваемый сайт с уровнем доступа 2 или 1 то пользователю назначается  уровень Limited. Если уровня доступа у сайта нет или он равен 3, то ничего не возвращается. По аналогии все остальные уровни доступа.

И самое главное, что бы в любой момент можно было добавить в БД еще один уровень доступа для пользователей и сайтов, дописать таблицу соответствия и хелпер смог бы назначать новые уровни доступа без изменения в теле программы.

Пы.Сы. Подскажите подойдет ли такая структура БД и натолкните на идею написания запроса (знаю MySQL на базовом уровне).

Пы.Пы.Сы. Структура БД можно изменять, главное что бы исполняло основную функцию - на основании имени и запрашиваемого сайта, определяло уровень доступа.
Вообщем буду рад любым идеям и советам!

Неактивен

 

#2 02.08.2012 18:15:05

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Возможно ли построить такой запрос?

Таблицу соответствия лучше сделать избыточной
Usr              Dst           level
No user      rlevel 1    Base
Access 1    rlevel 1    Limited
Access 1    rlevel 2    Limited
Access 2    rlevel 1    Normal
Access 2    rlevel 2    Normal
Access 2    rlevel 3    Normal
...


И решать задачу в три простых запроса:
1) по имени пользователя определяем access
2) по имени сайта -- rlevel
3) select level from main where Usr = '..' and Dst = '..'

Если хотите одним запросом, то это будет медленно работающий монстр типа
SELECT level FROM Main JOIN
(SELECT `Access`, 1 o  FROM `Users` WHERE Name = 'Имя пользователя'
UNION
SELECT 'No user', 2 o  ORDER BY o LIMIT 1) t1 ON Usr=`Access`
JOIN
(SELECT rlevel FROM DstDomain WHERE site ='сайт') t2 ON Dst = rlevel;

Неактивен

 

#3 02.08.2012 19:26:12

ksado
Участник
Зарегистрирован: 02.08.2012
Сообщений: 3

Re: Возможно ли построить такой запрос?

Идея на счет избыточной таблицы просто замечательная! Уже ломал голову как строить программу, что бы был "вложенный" доступ.

По поводу 3-х запросов. Мне кажется (могу ошибаться) что один большой запрос к БД, отработает быстрее чем 3 запроса в хелпере. Хотя нужно проверять.

Сам запрос строил похожего типа, но столкнулся с проблемой, когда запрашиваемого пользователя нет в таблице Users и для него должна пройти проверка на запрашиваемые сайты с доступом rlevel1 (Base).
Получалось так, что приходит имя пользователя, которого нет в таблице Users, в результате запрос всегда ничего не возвращал!
И можно короткое пояснение к "1 o", "2 o", "t1"... Что это и для чего? С БД редко работаю, не совсем понял назначение, можно ткнуть на ман! smile

Неактивен

 

#4 02.08.2012 20:54:13

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Возможно ли построить такой запрос?

"1 o" то же что и "1 as o". Вторая колонка по имени o в которую вносятся фиксированные значения 1 и 2, а затем за счет (ORDER BY o LIMIT 1) выбирается только одно в порядке возрастания. Это и нужно как раз для случая когда нет запрашиваемого пользователя. Но лучше так не извращаться, а сделать отдельный запрос и если нет результата, то в программе присвоить доступу значение "no user".


"t1" это синоним для таблицы, которая формируется подзапросом (SELECT `Access`, 1 o  FROM `Users` WHERE Name = 'Имя пользователя'
UNION
SELECT 'No user', 2 o  ORDER BY o LIMIT 1). Как и в предыдущем случае здесь пропущено ключевое слово AS, которое является необязательным.
Дело в том, что каждая таблица в части FROM должна иметь имя и если таблица формируется за счет подзапроса, то нужно ей присвоить какое-нибудь имя, например: t1,t2, ...

Неактивен

 

#5 03.08.2012 10:53:23

ksado
Участник
Зарегистрирован: 02.08.2012
Сообщений: 3

Re: Возможно ли построить такой запрос?

Огромное человеческое спасибо за идею и пример реализации запроса!  smile

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson