2012-04-14 4 views
2

У меня есть база данных sqlite (на android), где я хочу хранить последние N записей некоторых данных.сохранить последние n записей в таблице

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

Есть ли особенно умный/хороший способ сделать это? Обратите внимание, что я всегда проверяю инвариант (nr rows < = THRESHOLD) после каждой вставки, поэтому нам не нужно иметь дело ни с чем, кроме как с удалением самой старой записи.

Что я собираюсь сделать, это в основном:

  1. вставки данных
  2. если количество (*) таблицы < = ПОРОГ: Гото 4
  3. DELETE FROM таблицы WHERE даты == (SELECT дата из таблицы порядок по дате ASC LIMIT 1);
  4. СДЕЛАНО

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

+0

Не нарушает ли это правило подзапроса одного значения? 3.DELETE FROM table WHERE date == (SELECT date from table order by date ASC); –

+0

@ Крис Там должно быть хотя бы 1 предел 1 да. Но его следует рассматривать как псевдокод - я все еще думаю о том, как его лучше всего реализовать - я просто подумал, что какой-то код упростит его понимание. – Voo

ответ

1

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

Количество строк может храниться в отдельной таблице учета, чтобы избежать на каждой вставке COUNT.

Вот полный пример:

create table bookkeepings (bk_name text primary key, bk_value integer not null); 

insert or replace into bookkeepings values ('Max Results', 50); 
insert or replace into bookkeepings values ('Qty Results', 0); 

create table results 
    (r_timestamp text primary key default (datetime(current_timestamp)), 
    result text); 

create trigger results_limit_trigger before insert on results" 
    for each row" 
    when (select bk_value from bookkeepings where bk_name = 'Qty Results') 
    >= (select bk_value from bookkeepings where bk_name = 'Max Results') 
    begin 
    delete from results 
     where r_timestamp = (select r_timestamp from results order by r_timestamp limit 1); 
    end; 

create trigger results_count_insert_trigger after insert on results 
    for each row 
    begin 
    update bookkeepings set bk_value = bk_value + 1 where bk_name = 'Qty Results'; 
    end; 

create trigger results_count_delete_trigger after delete on results 
    for each row 
    begin 
    update bookkeepings set bk_value = bk_value - 1 where bk_name = 'Qty Results'; 
    end; 
2
DELETE FROM table WHERE date = (SELECT MAX(date) from table LIMIT 1); 
+0

Ah MAX - хорошая идея, да - яснее в намерениях и, скорее всего, быстрее. Но общая структура не может быть улучшена? Необходимость сделать 4 запроса для этого кажется довольно крутой. – Voo

+1

Зачем ВСТАВИТЬ И УДАЛИТЬ? Возможно, UPDATE в MIN (datetime) для перезаписывания самой старой записи с новыми данными и текущим временем datetime? – Sam

+0

@Sam Интересная идея. Никогда даже не думал об обновлении полной записи. Вероятно, не эффективнее, чем insert/delete (поскольку нам все равно придется переупорядочить таблицу), но я тоже попробую. – Voo

1

Как насчет этого?

-- keep the last N records by expiration date 
declare @expDate datetime 

set @expDate = (select top 100 max(dt) from table order by dt asc); 
delete from table where dt > @expDate