Организация журналирования пользовательских событий

rotoZOOM

ACM maniac
Привет всем!

Хочу спросить совета у опытных разрабов.
Суть задачи.
Есть тематический портал (php, mysql).
Требуется написать систему журналирования (логирования) всех возможных действий зарегистрированных пользователей (в том числе и админов), таких как создание/удаление/редактирование объектов, связей между объектами, фотогаллерей товаров и т.д.
А самое главное - это потом при выводе отчета (списка событий) реализовать систему фильтрации, в которой можно было бы отфильтровать только необходимые события и не показывать остальные, например фильтр:
Дата: с такого по такое-то
Пользователи:
- Иванов;
- Петров;
- Сидоров.
Действия с товарами:
- изменение цены;
- смена главного фото товара;
- смена скидки.

Смысл в том, что этих всевозможных атрибутов фильтрации до ж..., много короче.

Мои мысли по этому поводу:

1. Создать таблицу в БД events {id, event_date, user_id, type_id},
где type_id - это тип события.
Для каждого типа события создать свою таблицу с привязкой по FK к events, например:
event_goods_edit {event_id, .... специфические поля для данного типа события}
Плюсы: фильтрация осуществляется силами БД.
Минусы: при добавлении атрибутов придется менять структуру таблиц, а это значит, что желательно
сразу внести все необходимые поля в структуру, что выльется в кучу таблиц, с большим количеством полей. Генерирование запросов по фильтрам потащат за собой кучу JOIN'ов.

2. Создать таблицу в БД events {id, event_date, user_id, event},
где event - это сериализированный (или сериализованнный) объект базового класса Event.
Для каждого типа события написать свой класс, а фильтрацию осуществлять уже php'ями, а не БД.
Плюсы - фильтр генерируется автоматом при редактировании иерархии классов Event, ООП'эшная структура, не требуется дополнительных дата мэпперов.
Минусы - скорость работы/загрузка сервака при большом диапазоне выборки.

Какие-то такие сумбурные мысли.

В каком направлении копать?

P.S. забыл упомянуть, что каждое событие редактирования должно сохранять предыдущее значение параметра и установленное.
 

KorP

Новичок
Я не догнал, при добавлении каких атрибутов в 1-м варианте придётся менять структуру таблиц? 0_о
зачем для каждого типа своя таблица? сделай таблицу эвентов, запихай их туда все и по айдишникам связывай, не вижу проблемы ни со структурой, ни с выборкой
 

rotoZOOM

ACM maniac
Я может как то неправильно объяснил. Существует большое количество событий, больше 100, связанных с разными таблицами, их все в одну пихать что-ли?
 

rotoZOOM

ACM maniac
events_type тогда вообще не нужен, достаточно все в 1 хранить, а типы захардкодить в программе.
 

Ragazzo

TDD interested
rotoZOOM
была похожая задача, когда я сказал нечто вида "типы захардкодить в программе.", меня хотели "закидать стульями" :D :D :D
 

rotoZOOM

ACM maniac
в одной нельзя - читай про нормализацию
Я в курсе про нормализацию, собственно это и есть первый пункт.
В итоге получится куча таблиц и выборка в виде многоэтажного джойна.
Ragazzo, не все захардкоженное является говнокодом. :)
 

Ragazzo

TDD interested
rotoZOOM
Хз, я думаю проще добавить 1 строку в таблицу БД, чем потом искать по кучи строк где и что находится. мы все таки не стали хардкодить :)
 

KorP

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

rotoZOOM

ACM maniac
KorP, если все делать в одной таблице events {id, date, user_id, type, content}, то это как раз второй случай, когда тип content'а зависит от type, и БД'шный фильтр применить можно только по date,user_id, type.
Этого будет достаточно, если только потом не поступит запрос: "А можно сделать фильтр только по конкретному товару ?"

Breeze, имеется в виду 100-200 типов событий.
 

KorP

Новичок
rotoZOOM
Ну под одной таблицей я имел ввиду две (как я выше уже расписал): таблица эвентов и справочник эвентов,это и будет 3НФ
 

rotoZOOM

ACM maniac
KorP, в таблицах которые ты привел нет самого эвента, я так понимаю он будет в events?
И для чего вообще вторая таблица events_type? Просто для текстового описания типа?
 

KorP

Новичок
rotoZOOM, а у тебя в этих же таблицах нет самого юзера, но это тебя почему то не смущает.
у тебя таблица эвентов + 2 джоина: один к справочнику юзеров, вторая к справочнику евентов
текстовое описание, или что ты там туда ещё захочешь запихнуть
вообще не понимаю откуда столько обсуждений таких примитивных вещей....
 

rotoZOOM

ACM maniac
KorP, я быть может не догоняю чего-то в твоих выкладках, поэтому приведу пример.
Пусть будут эти две таблицы (опустим юзеров, там все понятно).
events {id, user_id, date, type_id, event_content}
events_type {id, desc} // пока не понимаю для чего эта таблица в таком виде

Теперь. Контроллер компаний генерирует эвент: "пользователь Ктулху изменил название компании с Цветочки на Ромашки"
Понятно, чем будет являться user_id, date. Type - подбирается исходя из типа сообщения, тип примерно такой:

Таблица events_type:

id | desc
----+-----------
.... | .......
31 | Изменение названия компании
.... | .......
----+-----------

таким образом, type_id = 31

Что кладется в event_content?
Сериализованный объект класса ChangeCompanyTitleEvent ?
 

KorP

Новичок
rotoZOOM
ты невнимательно читаешь, отсюда твой вопрос и непонимание. где в моём примере ты нашёл event_content?
 
Сверху