限制sqlite表的最大行数

时间:2010-01-10 01:13:23

标签: database database-design sqlite database-table

我希望实现一种“活动日志”表,其中用户执行的操作存储在sqlite表中,然后呈现给用户,以便他们可以看到他们已完成的最新活动。但是,当然,我觉得没有必要保留每一段历史记录,所以我想知道是否有办法配置表,一旦达到最大设置限制就开始修剪旧行。

例如,如果限制为100,并且表中当前有多少行,则插入另一个操作时,将自动删除最旧的行,以便始终最多包含100行。有没有办法配置sqlite表来执行此操作?或者我必须经营一个cron工作?

澄清编辑:在任何特定时刻,我想显示表格的最后100个(例如)操作/事件(行)。

3 个答案:

答案 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 keyinteger 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)
);