Проверка на дубли

KillDead

Хранитель порядка
Регистрация
11 Авг 2006
Сообщения
894
Реакции
579
Здравствуйте. Возникла небольшая задача, вроде бы тривиальная:
Есть дорвей, требования к скрипту должны быть не особо большими. Mysql использовать нельзя. Дор получает и парсит новости, затем всё кеширует. Но проблема такая- нужно проверять, есть ли новость с заголовком "ХХХ1" уже на сайте или нет. Особо не думая сделал файл base.db в которой храню md5 всех новостей. Проверка представляет собой чтение всей базы в ключи массива и потом проверка, есть ли такой ключ.
Код:
$fp = fopen(  '/video_id.db', 'r');
$_idbase = array();
while ($idInBase = fgets($_idbasefp)) {
    $_idbase[trim($idInBase)] = 1;
}
fclose($_idbasefp);
foreach($news as $title=>$__){
if(isset(  $_idbase[$title])){
continue;
}

}
В принципе, всё устраивало, скорость нормальная, но при увеличении объёмов увеличилось количество памяти на массив, по рассчётам, скрипт будет есть аж 500 метров при максимальном наполнении.
Хочу спросить- как лучше организовать такую проверку. Может ктото решал? Есть пара идей, но пока они под обдумыванием.
 
Дор получает и парсит новости, затем всё кеширует. Но проблема такая- нужно проверять, есть ли новость с заголовком "ХХХ1" уже на сайте или нет. Особо не думая сделал файл base.db в которой храню md5 всех новостей.
Юзал длительное время движки без БД, некоторые сайты и сейчас на них стоят.
При использовании текстовых баз с индексом в 1 файле тормоза на разных хостингах начинаются, когда в базе примерно от 500 индексов.
Решение обычно в разбитии новостей на блоки (например на категории или помесячно) до 300 новостей.
Тогда нагрузка даже при большой посещаемости редко превышает 10Мб.
Например: Новости, Новости август 2015, Новости сентябрь 2015, Архивы за 2014 и т.д.
 
Решение обычно в разбитии новостей на блоки (например на категории или помесячно) до 300 новостей.
А как проверять на дубли? Читать все эти файлы?
Пока что два варинта без использования сторонних либ
1. Делаем md5 и создаём файл /a/b/c/abc.... Получится такой индексный кеш на файловой системе. Недостаток- хардам может быть не особо хорошо.
2. Делаем разбивку индексного файла по 3-м (или 2-м) певым буквам кеша. То есть aa.db ab.db . Посчитал, если 1кк значений то в каждом будет ~4к для 2-х букв и ~200 для 3-х букв. Скорость тоже не страдает особо. Есдинственное, что для проверки придётся считывать обязательно один файл полностью.
 
Пока что два варинта без использования сторонних либ
1. Делаем md5 и создаём файл /a/b/c/abc.... Получится такой индексный кеш на файловой системе. Недостаток- хардам может быть не особо хорошо.
2. Делаем разбивку индексного файла по 3-м (или 2-м) певым буквам кеша. То есть aa.db ab.db . Посчитал, если 1кк значений то в каждом будет ~4к для 2-х букв и ~200 для 3-х букв. Скорость тоже не страдает особо. Есдинственное, что для проверки придётся считывать обязательно один файл полностью.
Примерно при кешировании так и делал по первому варианту, только сохранял всё в одной папке.
Что конечно не айс — при большом количестве файлов в папке кеша системе может стать плохо.
Вот класс для кеширования в мд5 Для просмотра ссылки Войди или Зарегистрируйся
Собственно при заходе на сайт вызывается класс кеша и текущая страница перед выдачей в браузер сохраняется тупо на диск.
А адрес страницы шифруется в мд5 и с этим именем сохраняется в папку кеша.
При повторном заходе на эту страницу вычисляется — истек ли срок обновления кеша.
Если срок истек, кеш пишется заново, если нет — движок не грузится вообще, а выдается страница с кеша.
Вот вариант использования
PHP:
//Включаем кеш для незарегистрированных или если можно включать или если выводимый модуль не в списке исключений из кеша
if (is_guest() && !empty($system->config['cache']) && !in_array($mod,explode("\n",str_replace("\r", '', $system->config['disable_cache'])))){
$cache = new CACHE;
$cache -> start_cache();
$cache -> time_file_cache = $system->config['cache'];//
if (!$cache -> is_fresh())    {
rcms_start();
$cache -> save_cache();
}
$cache -> clear_cache();
if ($cache -> show_cache()) echo $cache -> CONTENT;
} else {
rcms_start();
}
Второй Ваш вариант — это собственно Гит так работает (разбивает на папки). Это ещё лучше.
 
Чем sqlite плох?
 
:-] У вас же не один хостинг(сервер)? Храните хеши на другом, ненагруженном , с MySQL, а с дорвея отправляйте туда XML с новыми хешами, там принимающий скрипт делает проверку, вносит в базу новые, и отправляет назад XML с повторяющимися:crazy:
 
Вот класс для кеширования в мд5 Для просмотра ссылки Войди или Зарегистрируйся
Почитай Для просмотра ссылки Войди или Зарегистрируйся надо лок файла делать и при чтении и при записи, иначи приколы при одновременном доступе к файлу от нескольких процессов...


1. Делаем md5 и создаём файл /a/b/c/abc.... Получится такой индексный кеш на файловой системе. Недостаток- хардам может быть не особо хорошо.
Мне такая реализация кеша понравилась Для просмотра ссылки Войди или Зарегистрируйся
Разбивка по 2 символа на папку. При уровне в 2 директории по 2 символа будет нормально.
Но такой кеш потом очень-очень сложно вычищать (даже при том что есть метод для чистки) и переносить между серверами практически анрил, если не VPS.

Лучший вариант на мой вкус:
- читаешь обалденную стать про то как работают индексы Для просмотра ссылки Войди или Зарегистрируйся
- осознаешь, что так на файлах такое замутить будет непросто
- и делаешь на базе какой-нибудь БД с возможностью индексов
 
Назад
Сверху