Ограничить максимальное количество строк в таблице sqlite - PullRequest
28 голосов
/ 10 января 2010

Я ищу реализацию своего рода таблицы «Журнала активности», в которой действия пользователя сохраняются в таблице sqlite, а затем представляются пользователю, чтобы они могли видеть последние действия, которые они выполнили. Однако, естественно, я не считаю необходимым хранить каждый бит истории, поэтому мне интересно, есть ли способ настроить таблицу так, чтобы она начинала обрезку более старых строк после достижения максимального установленного предела.

Например, если ограничение равно 100, и это то количество строк, которое в данный момент находится в таблице, при вставке другого действия самая старая строка автоматически удаляется, так что всегда есть максимум 100 строк. Есть ли способ настроить таблицу sqlite для этого? Или мне придется запустить задание cron?

Разъяснение. Правка : В любой момент я хотел бы отобразить последние 100 (например) действий / событий (строк) таблицы.

Ответы [ 3 ]

20 голосов
/ 10 января 2010

Другое решение - предварительно создать 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'); 
4 голосов
/ 10 января 2010

Вы можете создать триггер , который срабатывает на INSERT, но лучшим способом решения этой проблемы может быть просто запланированное задание, которое выполняется периодически (скажем, раз в неделю) и удаляет записи из таблицы.

3 голосов
/ 29 августа 2012

Есть несколько способов ограничить таблицу до 100 строк. (Для краткости 5 строк в коде ниже.) Протестировано в SQLite версии 3.7.9.

Весь этот код основан на своеобразном способе, которым SQLite обрабатывает объявления типов данных. (Во всяком случае, мне это кажется странным.) SQLite позволяет вставлять глупости, такие как 3.14159 и wibble, в пустой столбец целых чисел. Но он позволяет вставлять только целые числа в столбец, объявленный integer primary key или integer primary key autoincrement.

Ограничение FOREIGN KEY

Используйте ограничение внешнего ключа для таблицы действительных номеров идентификаторов, чтобы гарантировать, что номера идентификаторов находятся в требуемом диапазоне. Ограничения внешнего ключа работают даже для автоинкрементных столбцов.

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".

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 () ограничение

Приведенное ниже ограничение первичного ключа гарантирует, что номера идентификаторов будут целыми числами. Ограничение 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)
);
...