Общее·количество·просмотров·страницы

воскресенье, 5 декабря 2010 г.

Система контроля доступа сайта

Как это реализовать грамотно?
Я столкнулся с ситуацией, когда существующее приложение использовало матрицу доступа в виде представления, то есть делалась выборка по всем пользователям и по всем объектам. Нетрудно представить, что это работает только тогда когда количество объектов и особенно пользователей невелико, так как количество строк в представлении = пользователи*объекты. При условии индексирования представления это работало быстро в MSSQL Server, но не работало быстро в некоторых других базах данных. По мере роста числа пользователей приложение работало всё медленнее.
Первым шагом было использование хранимых процедур или функций, в зависимости от базы данных, возвращающих одну строку с id объекта и полями типа доступа. Типов доступа на самом деле немного, поэтому нет смысла разделять строку на отдельные значения.
Итак, мы имеем для объекта поле Flags int. Типы доступа хранятся там. Это изначальное ограничение - на самом деле поле должно быть типа bigint, чтобы увеличить количество флагов. Этого значения должно хватить, если не хватает, в логике приложения есть проблемы. Правда, увеличение количества полей снижает скорость выборки, но не критично.

Запись флагов:
Flags = Flags | 2 (OR)
Проверка установки флага:
(Flags & 2) = 2 (AND)
Снятие флага:
Flags = Flags ^ 2 (XOR)
Мы можем использовать степени двойки если вы делаете всё в программном коде.

Следующий этап - как контролировать доступ.
Я выбрал избыточность данных, так как это - наиболее быстрый доступ, но можно и полагаться на кэширование хранимой процедуры. При избыточности важно контролировать логику приложения, чтобы данные изменялись синхронно.
Итак я выбираю все строки для данного пользователя из имеющегося представления(индексировано), которое в дальнейшем было конвертировано
в хранимую процедуру, и записываем их в таблицу связанную с активными в данный момент пользователями. Итого имеем записи в таблице для одного пользователя и всех объектов.
Выигрыш:
50000 пользователей и 200 объектов - 1000000 записей
50 пользователей онлайн и 200 объектов - 10000.
Нетрудно представить как повышается скорость выборки (и радуется провайдер хостинга).
Особенно при том , что эта таблица соединена JOINами при разных выборках.
Прелесть такого подходя и в том, что мы можем кэшировать в этой таблице недавние данные и это придаёт гибкость приложению.

Итак:
1. В хранимой процедуре контролируем доступ. Если в таблице доступа присутствуют записи для пользователя, используем их, если нет, делаем выборку.
2. Периодически чистим таблицу активных пользователей по времени последней активности и удаляем также из таблицы доступа
id пользователя удалённые из первой таблицы.

Комментариев нет:

Отправить комментарий