我想创建一个不超过n行数据的SQL表。插入新行时,我希望删除最旧的行以为新行添加空间。
在SQLite中是否有一种典型的处理方法?
应该使用一些外部(第三方)代码进行管理吗?
答案 0 :(得分:12)
扩展Alex' answer,并假设您在名为t
的表serial
上有一个递增的,不重复的串行列,可用于确定行的相对年龄:
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;
当行数少于10行时,这将不会执行任何操作,当DELETE
将您推送到11行时,INSERT
将是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;
列。 / p>
id
我们理所当然地认为我们不能使用ts
来确定相对年龄,因此我们删除按时间戳排序的前10行之后的所有内容。 (SQLite对共享相同{{1}}的行强制执行任意顺序。)
答案 1 :(得分:4)
似乎SQLite对触发器的支持就足够了:http://www.sqlite.org/lang_createtrigger.html
答案 2 :(得分:1)
有关sql:http://www.xaprb.com/blog/2007/01/11/how-to-implement-a-queue-in-sql
中固定队列的文章应该能够使用相同的技术来实现“滚动行”
答案 3 :(得分:0)
这就像你将如何做到这一点。这假设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;