【问题标题】:Limiting number of rows in SQLite限制 SQLite 中的行数
【发布时间】:2014-09-26 00:37:05
【问题描述】:

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

【问题讨论】:

  • 您可能会考虑在插入后使用触发器来删除所有带有rowid <= (max(rowid) - 50)的行
  • @ssnobody 这会在rowids 不连续时爆炸。
  • 如何在没有数据库操作的情况下查询行数,或者删除一些旧行?根据定义,这些操作是对数据库的操作。
  • @CL,是的,但如果 rowid 是 AUTOINCREMENT,并且删除仅通过触发器执行,我相信我们可以保证连续。不过,我愿意听取其他想法。
  • 这似乎是一个很好的答案:stackoverflow.com/questions/18677649/…

标签: android sqlite android-sqlite


【解决方案1】:

我知道一种可行的方法,但它有点难看。它依赖于精心构建的约束和对数据库的播种。为简洁起见,我只使用了 5 行而不是 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;
row_num other_columns row_timestamp ---------- ------------- ----------- 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 2017-07-22
    相关资源
    最近更新 更多