我想創建一個不超過n行數據的SQL表。當插入一個新行時,我想刪除最舊的行以騰出空間給新的行。SQL表中的滾動行
有沒有一種在SQLite中處理這個問題的典型方法?
應該用一些外部(第三方)代碼來管理它嗎?
我想創建一個不超過n行數據的SQL表。當插入一個新行時,我想刪除最舊的行以騰出空間給新的行。SQL表中的滾動行
有沒有一種在SQLite中處理這個問題的典型方法?
應該用一些外部(第三方)代碼來管理它嗎?
似乎的SQLite的觸發器的支持可以足夠了:http://www.sqlite.org/lang_createtrigger.html
擴展在Alex' answer,假設你有一個遞增的,不重複的命名serial
表t
可以用來確定行的相對年代序列列:
CREATE TRIGGER ten_rows_only AFTER INSERT ON t
BEGIN
DELETE FROM t WHERE serial <= (SELECT serial FROM t ORDER BY serial DESC LIMIT 10, 1);
END;
,當你有少於十行,並將DELETE
最低的串行時INSERT
會推你到十一行。這會什麼都不做。
UPDATE
這裏有一個稍微複雜一點的情況下,你的表記錄中可能包含重複,例如一個TIMESTAMP
列跟蹤插入時間一列列的「年齡」。
sqlite> .schema t
CREATE TABLE t (id VARCHAR(1) NOT NULL PRIMARY KEY, ts TIMESTAMP NOT NULL);
CREATE TRIGGER ten_rows_only AFTER INSERT ON t
BEGIN
DELETE FROM t WHERE id IN (SELECT id FROM t ORDER BY ts DESC LIMIT 10, -1);
END;
在這裏,我們理所當然地認爲,我們不能用id
確定相對年齡,所以我們通過時間戳訂購了第10行後刪除所有內容。 (SQLite在共享同一個ts
的行上施加任意順序)。
這將是如何你會這樣做。這假定my_id_column
是自動遞增的,並且是該表的排序列。
-- handle rolls forward
-- deletes the oldest row
create trigger rollfwd after insert on my_table when (select count() from my_table) > max_table_size
begin
delete from my_table where my_id_column = (select min(my_id_column) from my_table);
end;
-- handle rolls back
-- inserts an empty row at the position before oldest entry
-- assumes all columns option or defaulted
create trigger rollbk after delete on my_table when (select count() from my_table) < max_table_size
begin
insert into my_table (my_id_column) values ((select min(my_id_column) from my_table) - 1);
end;
文章在SQL固定隊列:http://www.xaprb.com/blog/2007/01/11/how-to-implement-a-queue-in-sql
應該能夠使用相同的技術來實現「滾動行」
不會總是這樣刪除第一行? – aronchick
@aronchick,no - 如果在第11個位置(可能是第11行的INSERT之後)沒有記錄,則標量子查詢將評估爲NULL,因此WHERE子句變爲WHERE serial <= NULL,這不會匹配任何東西。 – pilcrow
如果_id是自動遞增的,該怎麼辦?無法用_id代替TIMESTAMP或串行來完成此代碼?特別是當TIMESTAMP並不總是表模式的一部分時... –