2013-08-26 2 views
1

У меня очень высокий сайт трафика с большим количеством фотографий на нем, и я пытаюсь отслеживать, какую фотографию просматривал каждый пользователь.Отслеживание пользователей и фотографий, которые они просмотрели

Моим первым инстинктом будет таблица SQL с двумя столбцами: user_id & photo_id. Но это не повлияло бы на мой уровень трафика, и таблица быстро стала бы неуправляемой.
Любые рекомендации для решения anoher, SQL или NoSQL (mongodb, couch, redis, ...)

Мой код в основном PHP, если это имеет значение.

Спасибо!

Редактировать Существует 10 миллионов миллионов дней.

Edit мне не нужно знать общее время пользователь просматривает конкретную фотографию, были просто ли его рассматривать вообще этим пользователем

+0

Вы можете добавить идентификаторы фотографий в сеанс и обновить БД навалом, поэтому вместо обновления каждой фотографии, которую они видят, вы можете обновить WHERE id IN (5, 10, 15, любые идентификаторы). Отрицательная сторона этого заключается в том, что если пользователь просматривает n-1 изображения и затем выходит из системы, чтобы не возвращаться, вы потеряли запись n-1 изображений. – JimL

+0

Спасибо, Джим, ты говоришь, что ты делаешь объемную вставку? (не совсем обновление?). Это очень помогло бы, но таблица все равно быстро поправилась. Через неделю или около того это будет неуправляемо. – OneSolitaryNoob

+0

Ах, я догадываюсь, что сегодня я вошел в систему слишком рано. Вам придется делать несколько запросов на вставку, но если вы используете подготовленные заявления, вам пригодится запрос 2-15 (или какой бы номер вы ни выбрали), когда вы их выполняете. Насколько велики вы ожидаете получить таблицу? SQL может обрабатывать миллионы строк. Кроме того, вы можете изучить разбивку таблицы/осколки. – JimL

ответ

1

Лучше всего, чтобы создать коллекцию с {_id: Сформирован автомагически, pictureID, viewerID}

с находкой (pictureID, viewerID) .limit (1) и индекс по pictureID и viewerID сделает проверку супер ультра быстрый уровень 99. очень важно установить индекс. Я использую find(). Limit (1), потому что он быстрее, чем findOne, по крайней мере, из текущих тестов.

Почему у пользователя нет одной записи с массивом просматриваемых изображений? потому что поиск по массиву медленнее, чем поиск целого документа в коллекции. 10 миллионов изображений? без проблем. здесь сияет монгодб. он предназначен для масштабирования для крупных баз данных, таких как ваши. Пока ваши документы меньше 16 мб, и с 3 свойствами, это: у вас мало что нужно беспокоиться.

Когда вы удаляете изображение, просто db.viewed.remove ({pictureID: pictureID}), и он удалит все связанные изображения.

db.viewed.remove ({viewerID: viewerID}), когда вы удаляете пользователя! Не делайте этого, когда пользователь удаляет изображение или учетную запись. Делайте это во время технического обслуживания или говорите, один раз в час. Создайте коллекцию с pendingRemovingImages и pendingRemovingUsers, где вы храните вещи, которые хотите удалить. проверьте $ в, чтобы выполнить массовое удаление изображениями и/или пользователями.

Я нахожу ваш вопрос самым захватывающим, и я твердо убежден, что вы должны идти в мою сторону.

+0

@OneSolitaryNoob Примите вопрос, если он удовлетворяет, пожалуйста. – Discipol

+0

Discipol, это может сработать, но я все же немного опасаюсь размера. Я смотрю 10 миллионов в день (много пользователей и много фотографий). Будет ли это способно удерживать до 1000 дней * 10 миллионов просмотров в день? – OneSolitaryNoob

+0

Теоретически, да. Вы могли видеть, что пространство hdd входит в сотни концертов. Ваш сайт Google или что-то еще? : P – Discipol

1

Вы можете попросить Redis. Redis очень хорошо поддерживает PHP, с Redis, вы можете сохранить историю просмотров определенной фотографии в хэш-карте.

$map = 'views|' . $photo_id; 
// this line is called whenever a user view a photo 
$redis->hset($map, $uid, time()); 
// this line is called to test whether a user viewed a photo 
$redis->hget($map, $uid); 

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

Также вы можете попробовать SSDB (https://github.com/ideawu/ssdb), который имеет аналогичные API для Redis, также хорошо поддерживает PHP (http://www.ideawu.com/ssdb/docs/php/), но хранить большинство данных на диске, память используется только для кеширования. Это означает, что пропускная способность SSDB составляет 100 раз от Redis - вплоть до ТБ.

+0

redis сам по себе будет слишком быстро заполняться, я не слышал о ssdb, который выглядит интересным. я загляну в него – OneSolitaryNoob