我希望实现一种“活动日志”表,其中用户执行的操作存储在sqlite表中,然后呈现给用户,以便他们可以看到他们已完成的最新活动。但是,当然,我觉得没有必要保留每一段历史记录,所以我想知道是否有办法配置表,一旦达到最大设置限制就开始修剪旧行。
例如,如果限制为100,并且表中当前有多少行,则插入另一个操作时,将自动删除最旧的行,以便始终最多包含100行。有没有办法配置sqlite表来执行此操作?或者我必须经营一个cron工作?
澄清编辑:在任何特定时刻,我想显示表格的最后100个(例如)操作/事件(行)。
答案 0 :(得分:19)
另一种解决方案是预先创建100行而不是INSERT
使用UPDATE
来更新最旧的行。
假设该表具有datetime
字段,则查询
UPDATE ...
WHERE datetime = (SELECT min(datetime) FROM logtable)
可以胜任。
修改:显示最后100个条目
SELECT * FROM logtable
ORDER BY datetime DESC
LIMIT 100
更新:这是一种使用连接操作创建130个“虚拟”行的方法:
CREATE TABLE logtable (time TIMESTAMP, msg TEXT);
INSERT INTO logtable DEFAULT VALUES;
INSERT INTO logtable DEFAULT VALUES;
-- insert 2^7 = 128 rows
INSERT INTO logtable SELECT NULL, NULL FROM logtable, logtable, logtable,
logtable, logtable, logtable, logtable;
UPDATE logtable SET time = DATETIME('now');
答案 1 :(得分:4)
您可以创建一个在INSERT上触发的trigger,但是更好的方法是解决此问题,可能只是让一个定期运行的计划作业(例如每周一次)并从表中删除记录。 / p>
答案 2 :(得分:3)
有几种方法可以约束一个表到100行。 (为简洁起见,下面的代码中有5行。)在SQLite版本3.7.9中进行了测试。
所有这些代码都依赖于SQLite处理数据类型声明的方式的一种怪癖。 (无论如何,这对我来说似乎很古怪。)SQLite允许你将像3.14159和'wibble'这样的废话插入一个裸整数列。但它允许您仅将整数插入到声明为integer primary key
或integer primary key autoincrement
的列中。
FOREIGN KEY约束
对具有有效ID号的表使用外键约束,以保证ID号在您想要的范围内。外键约束甚至可以在自动增量列上工作。
pragma foreign_keys=on;
create table row_numbers (n integer primary key);
insert into row_numbers values (1);
insert into row_numbers values (2);
insert into row_numbers values (3);
insert into row_numbers values (4);
insert into row_numbers values (5);
create table test_row_numbers (
row_id integer primary key autoincrement,
other_columns varchar(35) not null,
foreign key (row_id) references row_numbers (n)
);
insert into test_row_numbers (other_columns) values ('s');
insert into test_row_numbers (other_columns) values ('s');
insert into test_row_numbers (other_columns) values ('s');
insert into test_row_numbers (other_columns) values ('s');
insert into test_row_numbers (other_columns) values ('s');
第六次插入失败并显示“错误:外键约束失败”。
我不认为使用自动增量是完全安全的。在其他平台上,回滚会在序列中留下空隙。如果您不使用自动增量,则可以通过从“row_numbers”中选择ID号来安全地插入行。
insert into test_row_numbers values
(
(select min(n)
from row_numbers
where n not in
(select row_id from test_row_numbers)),
's'
);
CHECK()约束
下面的主键约束保证id号将是整数。 CHECK()约束保证整数将在正确的范围内。您的应用程序可能仍然需要处理由回滚导致的差距。
create table test_row_numbers (
row_id integer primary key autoincrement,
other_columns varchar(35) not null,
check (row_id between 1 and 5)
);