2013-08-07 2 views
2

В моей таблице есть поле TIME.Правильный способ удаления «старых» строк в MySQL

Я хочу сохранить только 5 новых строк.

Могу ли я удалить старые строки без использования SELECT?

Я думаю, что логика должна быть что-то вроде этого:

DELETE FROM tbl WHERE row_num > 5 ORDER BY TIME 

Как я могу реализовать это в MySQL whitout с помощью SELECT, чтобы получить список TIME значений?

+0

Ваш вопрос непонятен. сначала сделайте это правильно. – ripa

+2

Добавьте 'LIMIT 5, 999999' к этому запросу. А также иметь 'ORDER BY TIME DESC', вместо' ASC' (по умолчанию). [См. Похожий вопрос с тем же нечетким ответом.] (Http://stackoverflow.com/questions/255517/mysql-offset-infinite-rows) –

+0

Поскольку написано все колпачки, это слово 'TIME', ссылающееся на фактическое столбец вашей таблицы - или это какой-то заполнитель? –

ответ

3

Без надлежащего предложения ORDER BY, SQL result set следует считать неупорядоченным.

Вы должны предоставить столбец для явного хранения порядковых номеров строк. Это может быть отметка времени или столбец auto_increment вашей таблицы.

Обратите внимание, что у вас может быть одновременный доступ к вашему столу. Какое должно быть ожидаемое поведение, если кто-то еще вставляет, когда вы удаляете? Насколько я могу судить, это может привести к ситуации, когда вы сохраняете только «5 последних строк» ​​+ «те, которые были добавлены в другую транзакцию».


Если ваш иметь time колонку для этой цели на вашем столе и а PRIMARY KEY (или какой-либо другой UNIQUE NOT NULL столбца) можно было бы написать:

DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k 
    ON (tbl.pk) = (k.pk) 
    WHERE k.`time` IS NULL; 

Если у вас есть составной первичный ключ (a,b) Вы могли бы написать :

DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k 
    ON (tbl.a,tbl.b) = (k.a,k.b) 
    WHERE k.tm IS NULL; 
+0

У него уже есть поле времени. Я согласен, что есть потенциальное состояние гонки. – Paul

+0

@Paul Я не совсем уверен в этом, как это написано все кепки, как зарезервированное ключевое слово ... –

+0

Предполагая, что время или TIME - это метка времени в каждой строке, я больше обеспокоен тем, что документы для MySQL DELETE имеют голый номер после LIMIT (например, LIMIT 3), а не окно (например, LIMIT 10,15). Таким образом, LIMIT 5 10000000000 может быть недействительным. http://dev.mysql.com/doc/refman/5.7/en/delete.html – Paul

0
DELETE FROM TBL 
    WHERE ROW_NUM = (SELECT ROW_NUM FROM TBL LIMIT 6, 99999) 
    ORDER BY TIME DESC; 

Это приведет к удалению записей из 6, 7, 8, 9, 10, ....., 200005

Поскольку LIMIT диапазон начинается здесь от 6 до 9999 записей, означает 200005

+0

Вы уверены, что ROW_NUM для удаления и выбора будет представлять одну строку? –

0

Если вы хотите, чтобы исключить верхние 5 строк, использовать что-то вроде:

DELETE FROM table WHERE primary_key IN 
(SELECT primary_key FROM table LIMIT 1 OFFSET 5,1000000) 

100000 может быть очень большой нет

+0

следует изменить '*' на 'primary_key'? –

0

Может быть, это будет альтернатива:

DELETE FROM tbl 
WHERE primary_key NOT IN (SELECT primary_key 
          FROM tbl 
          ORDER BY time 
          DESC LIMIT 5) 
Смежные вопросы