Limite le nombre maximal de lignes d'une Table sqlite

Je cherche à implémenter une sorte de table' journal d'activité ' où les actions d'un utilisateur sont stockées dans une table sqlite, puis présentées à l'utilisateur afin qu'il puisse voir la dernière activité qu'il a effectuée. Cependant, naturellement, Je ne pense pas qu'il soit nécessaire de garder chaque bit d'histoire, donc je me demande s'il existe un moyen de configurer la table pour commencer à élaguer les anciennes lignes une fois qu'une limite maximale est atteinte.

Par exemple, si la limite est de 100, et c'est le nombre de lignes sont actuellement dans la table, lorsqu'une autre action est insérée, la ligne la plus ancienne est automatiquement supprimée de sorte qu'il y a toujours un maximum de 100 lignes. Est-il un moyen de configurer la table sqlite pour ce faire? Ou devrais-je exécuter un travail cron?

Clarification Edit : à tout moment, je voudrais afficher les 100 derniers (par exemple) actions/événements (lignes) de la table.

26
demandé sur ROMANIA_engineer 2010-01-10 04:13:23

3 réponses

Une autre solution consiste à précréer 100 lignes et au lieu de INSERT Utiliser UPDATE pour mettre à jour la ligne la plus ancienne.
En supposant que la table a un champ datetime, la requête

UPDATE ...
WHERE datetime = (SELECT min(datetime) FROM logtable)

Peut faire le travail.

Edit: affiche les 100 derniers entrées

SELECT * FROM logtable
ORDER BY datetime DESC
LIMIT 100

Update : Voici un moyen de créer 130 lignes "fictives" en utilisant l'opération join:

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'); 
18
répondu Nick Dandoulakis 2010-01-12 07:35:46

Vous pouvez créer un trigger qui se déclenche sur INSERT, mais une meilleure façon d'aborder cela, pourrait être simplement d'avoir un travail planifié qui s'exécute périodiquement (disons une fois par semaine) et supprime les enregistrements de la table.

3
répondu Mitch Wheat 2010-01-10 01:53:30

Il existe plusieurs façons decontraindre une table à 100 lignes. (Pour plus de concision, 5 lignes dans le code ci-dessous.) Testé dans la version SQLite 3.7.9.

Tout ce code repose sur une sorte de bizarrerie dans la façon dont SQLite gère les déclarations de type de données. (Cela me semble bizarre, de toute façon.) SQLite vous permet d'insérer un non-sens comme 3.14159 et 'wibble' dans une colonne entière nue. Mais il permet d'insérer uniquement des entiers dans une colonne déclarée integer primary key ou integer primary key autoincrement.

CLÉ ÉTRANGÈRE la contrainte

Utilisez une contrainte de clé étrangère sur une table de numéros d'identification valides pour garantir que les numéros d'identification sont dans la plage souhaitée. Les contraintes de clé étrangère fonctionnent même sur les colonnes auto-incrémentées.

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');

La sixième insertion échoue avec "erreur: la contrainte de clé étrangère a échoué".

Je ne pense pas Que utiliser un auto-incrément est entièrement sûr. Sur d'autres plates-formes, une restauration laisserait un vide dans la séquence. Si vous n'utilisez pas un autoincrement, vous pouvez insérer des lignes en sélectionnant le numéro d'identification dans "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'
);

COCHEZ() la contrainte

La contrainte de clé primaire ci-dessous garantit que les numéros d'id seront des entiers. La contrainte CHECK() garantit que les entiers seront dans la bonne plage. Votre application peut toujours avoir à faire face à des lacunes causées par des rollbacks.

create table test_row_numbers (
  row_id integer primary key autoincrement,
  other_columns varchar(35) not null,
  check (row_id between 1 and 5)
);
3
répondu Mike Sherrill 'Cat Recall' 2012-08-28 20:14:37