2009-12-29 12 views
10

me gustaría crear una tabla de SQL que no tiene más de n filas de datos. Cuando se inserta una nueva fila, me gustaría eliminar la fila más antigua para dejar espacio para la nueva.filas del balanceo de la tabla de SQL

¿Hay una manera típica de manejar esto dentro de SQLite?

debe manejar con un poco de código fuera (de terceros)?

Respuesta

11

Ampliando Alex' answer, y suponiendo que tiene una incrementación, que no se repite la columna de serie en la tabla t llamado serial que puede ser utilizado para determinar la edad relativa de las filas:

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; 

Esto va a hacer nada cuando tiene menos de diez filas, y se DELETE la serie más bajo cuando un INSERT que empujaría a once filas.

ACTUALIZACIÓN

Aquí es un caso un poco más complicado, donde sus registros de la tabla "edad" de la fila en una columna que puede contener duplicados , como por ejemplo una columna TIMESTAMP seguimiento de los tiempos de inserción.

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; 

Aquí damos por sentado que no podemos utilizar id para determinar la edad relativa, por lo que eliminar todo lo que después de las primeras 10 filas ordenadas por fecha y hora. (SQLite impone un orden arbitrario en las filas que comparten el mismo ts).

+0

No sería esto siempre eliminar la primera fila? – aronchick

+0

@aronchick, no - la subconsulta escalar evaluará a NULL si no hay registro en la posición 11 (DESPUÉS de nuestro INSERT de posiblemente la fila 11), y entonces la cláusula 'WHERE' se convierte' WHERE serial <= NULL', que no coincidirá con nada. – pilcrow

+0

¿Qué ocurre si el _id se incrementa automáticamente? ¿No se pudo lograr este código con _id en lugar de TIMESTAMP o serial? Especialmente cuando un TIMESTAMP no siempre es parte del esquema de la tabla ... –

0

Esto sería algo así como la forma en que lo haría. Esto supone que es my_id_column de incremento automático y es la columna de la ordenación de la tabla.

-- 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; 
Cuestiones relacionadas