2010-01-10 33 views
24

Estoy buscando implementar una especie de tabla de 'registro de actividad' donde las acciones que realiza un usuario se almacenan en una tabla sqlite y luego se presentan al usuario para que puedan ver la actividad más reciente haber hecho. Sin embargo, naturalmente, no creo que sea necesario mantener cada bit de la historia, por lo que me pregunto si hay una forma de configurar la tabla para comenzar a podar filas antiguas una vez que se alcanza el límite máximo establecido.Limite un número máximo de filas de sqlite

Por ejemplo, si el límite es 100 y esa es la cantidad de filas que hay actualmente en la tabla, cuando se inserta otra acción, la fila más antigua se elimina automáticamente para que siempre haya un máximo de 100 filas. ¿Hay alguna forma de configurar la tabla sqlite para hacer esto? ¿O tendría que ejecutar un trabajo cron?

Aclaración Editar: En cualquier momento dado, me gustaría mostrar las últimas 100 (por ejemplo) acciones/eventos (filas) de la tabla.

Respuesta

18

Otra solución es precreate 100 rows y en lugar de INSERT usa UPDATE para actualizar la fila más antigua.
Suponiendo que la tabla tiene un campo datetime, la consulta

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

puede hacer el trabajo.

Editar: pantalla los últimos 100 entradas

SELECT * FROM logtable 
ORDER BY datetime DESC 
LIMIT 100 

actualización: aquí es una manera de crear 130 filas "ficticios" mediante el uso de unirse a la operación:

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

Supongo que me falta algo, pero ¿no siempre actualizaría la última fila? Supongo que olvidé mencionar en mi publicación original, pero me gustaría mostrar, por ejemplo, las últimas 5 acciones/eventos independientemente de su antigüedad, no solo de la última. Gracias sin embargo. –

+2

@Blaenk: suponiendo que su actualización establece el campo de fecha y hora en la hora actual para cada fila que toca, esto debería pasar por las filas en orden cronológico. –

+0

Oohhh, y luego también actualiza el campo datetime del curso, que luego lo convertiría en la fila más nueva, ¿verdad? Ya veo. Hmm, esto es interesante. ¿Existe una forma simple de predecir una cierta cantidad de filas 'ficticias'? –

2

Puede crear un trigger que se active en INSERTAR, pero una forma mejor de abordar esto podría ser simplemente tener un trabajo programado que se ejecute periódicamente (por ejemplo, una vez a la semana) y elimine registros de la tabla.

+0

oh bien eso es lo que pensé (cron), pero quería asegurarme de que no hubiera un mecanismo incorporado para este tipo de situación. –

+1

Si está familiarizado con los factores desencadenantes, ¿tendría la amabilidad de proporcionar un ejemplo que sería útil en esta situación? Es decir, si no son demasiado complicados, si lo son, no te preocupes por eso. –

3

Hay Hay un par de maneras de restringir una tabla a 100 filas. (Por razones de brevedad, 5 filas en el código a continuación). Probado en SQLite versión 3.7.9.

Todo este código se basa en un tipo de peculiaridad en la forma en que SQLite maneja las declaraciones de tipos de datos. (De todos modos, me parece peculiar). SQLite te permite insertar disparates como 3.14159 y 'wibble' en una columna entera desnuda. Pero le permite insertar solo enteros en una columna declarada integer primary key o integer primary key autoincrement.

restricción FOREIGN KEY

Utilice una restricción de clave externa a una tabla de números de identificación válidos para garantizar que los números de identificación están en el rango que desea. Las restricciones de clave externa funcionan incluso en columnas autoincrementing.

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 sexta inserción falla con "Error: restricción de clave externa fallida".

No piensa El uso de un autoincrement es completamente seguro. En otras plataformas, una reversión dejaría un espacio en la secuencia. Si no usa una autoincrementación, puede insertar filas de forma segura seleccionando el número de identificación de "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() limitación

La restricción de clave principal a continuación garantiza los números de identificación serán enteros. La restricción CHECK() garantiza que los enteros estarán en el rango correcto. Es posible que tu aplicación tenga que ocuparse de las lagunas causadas por las reversiones.

create table test_row_numbers (
    row_id integer primary key autoincrement, 
    other_columns varchar(35) not null, 
    check (row_id between 1 and 5) 
); 
Cuestiones relacionadas