Я хотел бы составить таблицу SQL, которая имеет не больше, чем n строки данных. Когда новая строка вставляется, я хотел бы самую старую строку, удаленную для создания пространства для нового.
Существует ли типичный способ обработать это в SQLite?
Должен управлять им с некоторым внешним (сторонним) кодом?
Расширяя ответ Alex, и предполагая, что в таблице 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;
Это ничего не даст, если у вас меньше десяти строк, и будет DELETE
самым низким порядковым номером, когда INSERT
подтолкнет вас к одиннадцати строкам.
UPDATE
Вот немного более сложный случай, когда в вашей таблице записывается "возраст" строки в столбце, который может содержать дубликаты, как, например, столбец 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;
Здесь мы считаем само собой разумеющимся, что мы не можем использовать id
для определения относительного возраста, поэтому мы удаляем все после первых 10 строк, упорядоченных по меткам времени. (SQLite накладывает произвольный порядок на разделяемые строки ts
).
Кажется, поддержки триггеров в SQLite вполне достаточно: http://www.sqlite.org/lang_createtrigger.html
статья о фиксированных очередях в квадратных метрах: http://www.xaprb.com/blog/2007/01/11/how-to-implement-a-queue-in-sql
должны иметь возможность использовать ту же самую технику для реализации "прокатных рядов"
. Это было бы что-то вроде того, как вы бы это сделали. Это предполагает, что 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;