限制SQLite中的行数

4
我有一个情况,我只想在表格中限制50行。如果用户在此之后插入新行,则应删除第一行(最先插入的行),并插入新行,以保持计数不变。我知道我可以有一个rowid字段,在插入新记录时,我可以检查是否已经有了50行,因此删除最小的rowid,然后插入新的rowid。但是,我想知道是否有更好的解决方案,这样我就不必执行3个数据库操作(1.查询行数,2.删除最小值,3.插入)。

你可以考虑在插入后使用触发器来删除所有满足 rowid <= (max(rowid) - 50) 条件的行。 - ThatOneDude
@ssnobody 当rowid不连续时,这将会出现问题。 - CL.
你如何在没有数据库操作的情况下查询行数或删除一些旧行?这些操作从定义上来说都是对数据库的操作。 - CL.
@CL,是的,但如果rowid是AUTOINCREMENT,并且删除仅通过触发器执行,我相信我们可以保证连续性。不过,我很乐意听取其他想法。 - ThatOneDude
这似乎是一个不错的答案:https://dev59.com/bXbZa4cB1Zd3GeqPHZfc - IgorGanapolsky
1个回答

1

我知道一种可行的方法,但有点丑陋。它依赖于精心构建的约束条件和数据库种子数据。为了简洁起见,我只使用了五行而不是50行。

create table test (
  row_num integer primary key
    check ((round(row_num) = row_num) and (row_num between 1 and 5)),
  other_columns char(1) not null default 'x',
  row_timestamp timestamp 
    not null unique 
    default current_timestamp
);

表达式 round(row_num = row_num) 确保在 row_num 列中只有整数。否则,SQLite 可能会让你在其中插入 1.54 或 'wibble'。 other_columns 列仅是您实际数据的占位符。
insert into test (row_num, row_timestamp) values
(1, '2015-01-01 08:00:01'),
(2, '2015-01-01 08:00:02'),
(3, '2015-01-01 08:00:03'),
(4, '2015-01-01 08:00:04'),
(5, '2015-01-01 08:00:05');

实际的时间戳值并没有真正意义。至少目前还没有。像这样种子数据库意味着,从现在起,您只需要执行更新语句。如果表一开始是空的,那么您将不得不处理插入和更新的不同逻辑。例如,您将不得不计算行数以确定是插入还是更新。
create trigger update_timestamp
after update on test 
for each row
begin
  update test 
  set row_timestamp = strftime('%Y-%m-%d %H:%M:%f', 'now')
  where row_num = OLD.row_num;
end;

"update_timestamp"触发器使SQLite维护带有秒的小数戳(%f)。这可能取决于底层操作系统是否支持小数精度。
create trigger no_deletes
after delete on test
for each row
begin
  -- There might be a more elegant way to prevent deletes.
  -- This way just inserts exactly what a delete statement deletes.
  insert into test (row_num, other_columns, row_timestamp) 
  values (OLD.row_num, OLD.other_columns, OLD.row_timestamp);
end;

现在您可以更新数据。您可以更新自己的数据,这里只是占位符other_columns,SQLite会处理其余部分。
update test 
set other_columns = 'b' 
where row_timestamp = (select min(row_timestamp) from test);
select * from test order by row_timestamp desc;
行号       其他列         行时间戳
----------  -------------  -----------------------
1           b              2015-03-08 12:43:21.926
5           x              2015-01-01 08:00:05    
4           x              2015-01-01 08:00:04    
3           x              2015-01-01 08:00:03    
2           x              2015-01-01 08:00:02   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接