Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 22.01.2017 20:28:02

Помогите построить структуру бд для статистики

Добрый вечер.
Имеется доска обьявлений. Обьявления ведутся 2х типов. От простых посетителей и от магазинов. Сейчас не ведется не какая статистика просмотров. На самом деле просмотры сделать не проблема. Исключение в том, что у обьявлений магазинов вместо ссылки на просмотр обьявления, идет переход на их сайт.
У меря твт возникли вопросы.
1. Думаю завести таблицу views с такой структурой:
- id
- type (enum) // в данном поле типы обьявлений offer обычные и target обьявления магазинов
- offer_id  // ид просмотренного обьявления
- ip // ип посетителя
.... Возможно что то еще
2. Ограничить накрутку. Как?
Можно ли ставить массив айдишников просмотренного обьявления, а потом проверять? Не будит ли это как то пагубно влиять?

Интересно увидеть вашу структуру и логику.
Спасибо за внимание!

Не в сети

#2 23.01.2017 06:50:27

Re: Помогите построить структуру бд для статистики

Думаю завести таблицу views с такой структурой

хаха)) я как-то видел баннерку с похожей структурой. несколько инсертов и апдейтов на каждый показ генерили настолько мощную нагрузку, что эта дрянь сжирала половину ресурсов не самого слабого сервака.

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

решение довольно простое – использовать хранилище в памяти для промежуточного или постоянного хранения этих данных – редис, мемкэш, внутрипроцессные хранилища пхп (xcache, apcu, и др.) – в таком порядке по предпочтению. редис можно использовать для постоянного хранения, к тому же он поддерживает структуры, с помощью которых управлять этими данными можно намного проще, даже если редис используется для временного хранения. на мемкэше при помощи гугла и крепкого слова тоже можно хранить разные интересные структуры данных, но он теряет всё своё состояние при рестарте – так что он только как временное хранилище подходит. хранение данных внутри процесса пхп вообще не очень надёжно – например если пхп работает в составе апача, такой кэш будет сбрасываться при ротации логов, на apache reload.

в случае с той баннеркой, я вынес счётчики в отдельные записи в мемкэше, инсерты вместо применения в базу сохранял в связанном списке на основе мемкэша тоже, и – по расписанию просто накатывал все эти изменения пакетно раз в пять минут. вместо views=views+1 на каждый показ получался views=views+150 сразу на все показы за 5 минут, инсерты объединялись в один толстый инсерт, вставляющий 150 записей. результат – нагрузка даже в час пик остаётся едва заметной.

Ограничить накрутку

... – практически нереально. можно считать уникальные показы отдельно и смотреть уникальность по айпишнику. статистически для большинства объявлений соотношение всех показов к уникальным должно стремиться к определённому числу, чем больше показов – тем ближе. резкие расхождения соотношения видимого с ожидаемым могут быть признаком накрутки. это не поможет если накрутка делается по распределённой схеме (типа как DDoS) но тут невозможно отличить такую накрутку от, например, хабраэффекта. так что идеального решения нет. с этим придётся смириться.

Не в сети

#3 02.02.2017 08:37:33

Re: Помогите построить структуру бд для статистики

constb пишет:

Думаю завести таблицу views с такой структурой

хаха)) я как-то видел баннерку с похожей структурой. несколько инсертов и апдейтов на каждый показ генерили настолько мощную нагрузку, что эта дрянь сжирала половину ресурсов не самого слабого сервака.

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

решение довольно простое – использовать хранилище в памяти для промежуточного или постоянного хранения этих данных – редис, мемкэш, внутрипроцессные хранилища пхп (xcache, apcu, и др.) – в таком порядке по предпочтению. редис можно использовать для постоянного хранения, к тому же он поддерживает структуры, с помощью которых управлять этими данными можно намного проще, даже если редис используется для временного хранения. на мемкэше при помощи гугла и крепкого слова тоже можно хранить разные интересные структуры данных, но он теряет всё своё состояние при рестарте – так что он только как временное хранилище подходит. хранение данных внутри процесса пхп вообще не очень надёжно – например если пхп работает в составе апача, такой кэш будет сбрасываться при ротации логов, на apache reload.

в случае с той баннеркой, я вынес счётчики в отдельные записи в мемкэше, инсерты вместо применения в базу сохранял в связанном списке на основе мемкэша тоже, и – по расписанию просто накатывал все эти изменения пакетно раз в пять минут. вместо views=views+1 на каждый показ получался views=views+150 сразу на все показы за 5 минут, инсерты объединялись в один толстый инсерт, вставляющий 150 записей. результат – нагрузка даже в час пик остаётся едва заметной.

Ограничить накрутку

... – практически нереально. можно считать уникальные показы отдельно и смотреть уникальность по айпишнику. статистически для большинства объявлений соотношение всех показов к уникальным должно стремиться к определённому числу, чем больше показов – тем ближе. резкие расхождения соотношения видимого с ожидаемым могут быть признаком накрутки. это не поможет если накрутка делается по распределённой схеме (типа как DDoS) но тут невозможно отличить такую накрутку от, например, хабраэффекта. так что идеального решения нет. с этим придётся смириться.

Я тоже от этого способа отказался,и тупо добавил поле "views" в таблицу с обьявлениями. И потом при каждом просмотре, инкрементирую на 1 данное поле.
Пользуясь случаем, хочу задать еще 1 вопрос.
Сейчас у меня это реализованно так:

// model
public static function setViewed($slug)
{
    static::where('slug', $slug)->increment('viewes', 1):
}

Все прекрасно работает,но кроме поля "views" laravel еще и поле "updated_at" обновляет. Можно ли как то сделать что б "updated_at" не обновлялась?

Не в сети

#4 02.02.2017 10:54:54

Re: Помогите построить структуру бд для статистики

Все прекрасно работает,но кроме поля "views" laravel еще и поле "updated_at" обновляет. Можно ли как то сделать что б "updated_at" не обновлялась?

инкремент не должен менять updated_at. это значит таблица неправильно была создана, не через миграции, и на updated_at добавлен триггер ON UPDATE ... CURRENT_TIMESTAMP. Mysql сам обновляет это поле при любых изменениях.

И потом при каждом просмотре, инкрементирую на 1 данное поле

ну то есть самым неэффективным способом, как раз как я и описывал. ну при небольшом трафике в принципе пофиг, будет нормально работать

Не в сети

#5 03.02.2017 11:48:30

Re: Помогите построить структуру бд для статистики

constb пишет:

Все прекрасно работает,но кроме поля "views" laravel еще и поле "updated_at" обновляет. Можно ли как то сделать что б "updated_at" не обновлялась?

инкремент не должен менять updated_at. это значит таблица неправильно была создана, не через миграции, и на updated_at добавлен триггер ON UPDATE ... CURRENT_TIMESTAMP. Mysql сам обновляет это поле при любых изменениях.

И потом при каждом просмотре, инкрементирую на 1 данное поле

ну то есть самым неэффективным способом, как раз как я и описывал. ну при небольшом трафике в принципе пофиг, будет нормально работать

Это заложено в недрах фреймворка , что при любом обновлении таблици, обновляется поле updated_at. Путем гугления узнал,что такая проблема у многих. Нашел решение. При сохренение модели, в метод save передавать timestemp => false. Но это решение мне не подходит. Вынес проблему в общий вопрос.

Не в сети

#6 03.02.2017 13:26:53

Re: Помогите построить структуру бд для статистики

Это заложено в недрах фреймворка

– только на моделях!

SomeModel::whereSlug($slug)->increment('views');
– этот код вызывает update через построитель, при этом логика модели не затрагивается! если такой запрос вызывает изменение updated_at, значит в таблице поле создано неправильно – вручную, с добавлением ON UPDATE ... CURRENT_TIMESTAMP! такое поле будет обновляться даже при save(['timestamps' => false])!

Не в сети

#7 18.04.2017 00:04:49

Re: Помогите построить структуру бд для статистики

На Ларе есть доска объявлений?
мне тоже нужна smile
покажите плз - где она?

Не в сети

#8 18.04.2017 05:39:23

Re: Помогите построить структуру бд для статистики

На Ларе есть доска объявлений?

например https://www.bedigit.com/item/laraclassi … d-ads-cms/

Не в сети

#9 18.04.2017 22:02:16

TrueKanonir
Откуда: Ташкент
Сообщений: 221

Re: Помогите построить структуру бд для статистики

cleargoal пишет:

На Ларе есть доска объявлений?
мне тоже нужна smile
покажите плз - где она?

Помоему тс ее сам писал с нуля)

Не в сети

#10 18.04.2017 22:21:15

Re: Помогите построить структуру бд для статистики

constb пишет:

На Ларе есть доска объявлений?

например https://www.bedigit.com/item/laraclassi … d-ads-cms/

Спасибо!

Я уже видел ее в бесплатке, наверно "унесенная несуном". Попробовал на демо, есть глюки sad
А жаль.

Не в сети

Подвал раздела