LOG-файл - очистка по кол-ву в зависимости от даты?

Royal Flash

-=MaestrO=-
LOG-файл - очистка по кол-ву в зависимости от даты?

Есть таблица с полями:
dataerr (datetime) - время записи
error (char) - наименование ошибки
info (text) - информация о пользователе

Нужно, чтобы в таблице было не более 100, самых последних по времени, записей. Если записей более 100, все самые старые записи удаляются, чтобы оcталось 100 самых новых.
Вот такой вариант у меня:

$sql = 'SELECT * FROM table ORDER BY dataerr DESC LIMIT 100, 1';
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$sql = 'DELETE FROM table WHERE dataerr <= "'.$row['dataerr'].'"';
$result = mysql_query($sql);
Очевидный минус - может оставить менее 100 записей, если есть несколько записей в БД с одним и тем же временем: $row['dataerr'].

Кcожалению, оператор DELETE поддерживает Limit, тлько с одним параметром, иначе можно былобы вместо первого SELECT использовать DELETE (DELETE FROM table ORDER BY dataerr DESC LIMIT 100, 10000).

Возможно ли, может быть, как-либо объеденить данные запросы (SELECT и DELETE) в один?
 

Royal Flash

-=MaestrO=-
svetasmirnova
Из мана:
Можно просто повторять команду DELETE до тех пор, пока количество удаленных строк меньше, чем величина LIMIT.
Ты это имееш ввиду? Хотя я не совсем понял, что это значит... Циклом что-ли ее повторять??
 

svetasmirnova

маленький монстрик
Если применяется выражение ORDER BY (доступно с версии MySQL 4.0), то строки будут удалены в указанном порядке. В действительности это выражение полезно только в сочетании с LIMIT. Например:

DELETE FROM somelog
WHERE user = 'jcole'
ORDER BY timestamp
LIMIT 1
У меня такой медл. нет, что точную ссылку не дам. Это глава 6, якорь delete
 

Royal Flash

-=MaestrO=-
svetasmirnova
В этом случае получится так:
PHP:
$sql = 'SELECT * FROM table ORDER BY dataerr DESC LIMIT 100, 1000';
$result = mysql_query($sql);
$n = mysql_num_rows($result);
$sql = 'DELETE FROM table WHERE 1 < 0 ORDER BY dataerr LIMIT '.$n;
$result = mysql_query($sql);
Впринципе, немного лучше, чем я предложил вначале... Спасибо и на этом :)

-~{}~ 22.12.05 01:47:

white phoenix
Вариант - только ведь неохота добавлять лишнее поле, которе, по сути, необходимо только для корректного удаления устаревшей информации... Я думал об этой реализации, только хотелось бы обойтись без auto_increment. Вариант svetasmirnova на мой взгляд лучше.
 

white phoenix

Новичок
Royal Flash
Такой вариант imho лучше того что ты предложил:
PHP:
$sql = 'SELECT COUNT(*) FROM `table`';
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$n = $row[0]-100;
$sql = 'DELETE FROM `table` ORDER BY `dataerr` ASC LIMIT '.$n; 
$result = mysql_query($sql);
Он мне пришел в голову сразу же, но я считаю лучше с `id`, т.к. это быстрее.
 

svetasmirnova

маленький монстрик
вот так ещё можно, с использованием переменных в MySQL:
PHP:
mysql_query('select @temp := count(*) from `table``'); 
$sql = 'DELETE FROM table ORDER BY dataerr ASC LIMIT @temp';
$result = mysql_query($sql);
 

white phoenix

Новичок
svetasmirnova
вот так ещё можно, с использованием переменных в MySQL:
mysql_query('select @temp := count(*) from `table``');
$sql = 'DELETE FROM table WHERE 1 < 0 ORDER BY dataerr LIMIT '.$n;
$result = mysql_query($sql);
Как я понимаю, $n барабашка принесет.
 

Royal Flash

-=MaestrO=-
<b>white phoenix</b>
Он мне пришел в голову сразу же, но я считаю лучше с `id`, т.к. это быстрее.
Почему быстрее? Ктомуже вариант с превышением более чем в 1 запись возможен очень в редких случаях, в подавляющем большинстве прийдется удалять 1, самую старую запись.
 

white phoenix

Новичок
svetasmirnova
Нет, "вот что значит не читать ман", имхо, уместнее :)
Royal Flash
Потому, что в том варианте не нужно сортировку делать.
 

svetasmirnova

маленький монстрик
white phoenix
1. В каком варианте не надо сортировку делать?
2. Чистка таблицы не частая процедура, её можно делать после вызова ignore_user_abort
3. А тебе не пофиг откуда информацию брать? Из мана или из личного опыта?
 

white phoenix

Новичок
svetasmirnova
1. В том где есть поле `id` (auto_increment).
2. Причем тут частота чисток таблицы и функция ignore_user_abort(TRUE), которая позволяет продолжить работу скрипта после отключения клиента? Или найден способ принудительного отключения клиента еще до завершения работы скрипт? Очень сомнительно.
3. Абсолютно всё равно из мана или из опыта, лишь бы данные достоверные были. Но, imho, ты "взяла" и ни из того, и ни из другого :D
 

svetasmirnova

маленький монстрик
white phoenix
Ну-ка расскажи как без сортировки удалить все записи, кроме ста последних? Одним запросом.

-~{}~ 22.12.05 15:44:

N.B.: чисто абстрактно я против способа с id ничего не имею
 

white phoenix

Новичок
svetasmirnova
> чисто абстрактно я против способа с id ничего не имею
От чего именно абстрагируешься?
Не абстракно имеешь? Если да, то что?
> Ну-ка расскажи как без сортировки удалить все записи,
> кроме ста последних? Одним запросом.
Если есть поле `id` (auto_increment), то про сортировку сразу забываем. Способ c двумя запросами:
PHP:
$sql = 'SELECT MAX(`id`) FROM `table`'; 
$result = mysql_query($sql); 
$row = mysql_fetch_row($result); 
$n = $row[0]-100; 
$sql = 'DELETE FROM `table` WHERE `id` < '.$n;  
$result = mysql_query($sql);
При желании можно записать как один запрос.
 

svetasmirnova

маленький монстрик
Так запиши как один запрос. И что ты имеешь против сортировки?
>Не абстракно имеешь? Если да, то что?
избыточность данных
 

white phoenix

Новичок
svetasmirnova
> Так запиши как один запрос
[sql]
SELECT @max := MAX( `id` )
FROM `table`;
DELETE
FROM `table`
WHERE `id` < @max-100;
[/sql]
Если подумать, то возможно получится еще проще.
> И что ты имеешь против сортировки?
Медленее так будет. Но, способов решения предложеной задачи много, можно долго спорить насчет того какой лучше, но стоит ли? Ведь разница в производительности копеечная.
 

svetasmirnova

маленький монстрик
Это 2 запроса.
>Но, способов решения предложеной задачи много, можно долго спорить насчет того какой лучше, но стоит ли? Ведь разница в производительности копеечная.
Наконец-то :)
 
Сверху