2010-01-10 8 views
24

사용자가 수행하는 작업이 sqlite 테이블에 저장되고 사용자에게 제공되는 일종의 '활동 로그'테이블을 구현하려고합니다. 그러면 사용자가 최신 활동을 볼 수 있습니다 해냈다. 그러나 자연스럽게 모든 단일 비트를 유지할 필요가 없다고 생각합니다. 따라서 최대 설정 한도에 도달하면 이전 행을 제거하기 위해 테이블을 구성하는 방법이 있는지 궁금합니다.sqlite 테이블의 최대 행 수를

예를 들어 한도가 100이고 현재 테이블에있는 행 수가 몇 개인 경우 다른 동작을 삽입하면 가장 오래된 행이 자동으로 제거되므로 항상 최대 100 행이됩니다. 이 작업을 수행하기 위해 sqlite 테이블을 구성하는 방법이 있습니까? 아니면 크론 작업을해야합니까?

해명 편집 : 어떤 주어진 순간, 나는 테이블의 마지막 (100) 행동 (예를 들어)/이벤트 (행)을 표시하고 싶습니다.

답변

18

다른 해결책은 100 행을 미리 작성하고 INSERT 대신 UPDATE을 사용하여 가장 오래된 행을 업데이트하는 것입니다.
하면 테이블이 datetime 필드, 일을 할 수있는 쿼리

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

을 가지고 있다고 가정.

편집 : 디스플레이 지난 100 개 항목

SELECT * FROM logtable 
ORDER BY datetime DESC 
LIMIT 100 

업데이트 : 거기

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

뭔가 빠져있는 것 같아요.하지만 항상 마지막 행만 업데이트할까요? 내 원래 게시물에서 언급하는 것을 잊어 버린 것 같지만, 지난 5 가지 작업/이벤트를 예를 들어 마지막 세월이 아니라 몇 세까지 보여주고 싶습니다. 그래도 고마워. –

+2

@Blaenk : 업데이트가 날짜/시간 필드를 설정하는 각각의 행에 대해 현재 시간으로 설정한다고 가정하면 시간 순서대로 행을 순환해야합니다. –

+0

Oohhh, 그리고 또한 datetime 필드를 업데이트하면 가장 최신 행이됩니다. 내가 참조. 흠, 이것은 흥미 롭습니다. 일정량의 더미 행을 미리 만드는 간단한 방법이 있습니까? –

2

INSERT에서 발생하는 trigger을 만들 수 있지만 더 좋은 방법은 주기적으로 실행되는 예약 된 작업 (일주일에 한 번)을 실행하고 테이블에서 레코드를 삭제하는 것일 수 있습니다.

+0

오케이 내가 생각한 것 (cron)이지만, 이런 종류의 상황에 대한 메커니즘이 내장되어 있지 않은지 확인하고 싶었습니다. –

+1

트리거에 익숙하다면이 상황에서 사용할 수있는 예제를 제공하기에 충분합니까? 즉, 복잡하지 않다면, 걱정하지 마십시오. –

3

: 여기 조인 작업을 사용하여 (130) "더미"행을 생성하는 방법입니다 두 가지 방법으로 테이블을 100 행으로 제한합니다. (간략히하기 위해 아래 코드에서 5 행.) SQLite 버전 3.7.9에서 테스트되었습니다.

이 코드는 SQLite가 데이터 형식 선언을 처리하는 방식에 일종의 버킷을 사용합니다. SQLite를 사용하면 3.14159와 같은 말도 안되는 것을 삽입 할 수 있으며, 정수형 열에 'wibble'을 삽입 할 수 있습니다. 그러나 이것은 integer primary key 또는 integer primary key autoincrement으로 선언 된 열에 정수만 삽입 할 수있게합니다.

FOREIGN KEY 제약

이 ID 번호가 원하는 범위에 있음을 보장하기 위해 유효한 ID 번호의 테이블에 외래 키 제약 조건을 사용합니다. 외래 키 제약 조건은 자동 증가 열에서도 작동합니다.

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"에서 ID 번호를 선택하여 안전하게 행을 삽입 할 수 있습니다.

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() 제약 조건 기본 키 제약 조건 아래의 ID 번호는 정수있을 것입니다 보장

. 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) 
); 
관련 문제