28

ユーザーが行ったアクションがsqliteテーブルに保存され、ユーザーが行った最新のアクティビティを確認できるように表示される、一種の「アクティビティログ」テーブルを実装しようとしています。ただし、当然のことながら、すべての履歴を保持する必要があるとは思わないので、設定された最大制限に達したときに古い行の整理を開始するようにテーブルを構成する方法があるかどうか疑問に思っています。

たとえば、制限が 100 で、テーブルに現在ある行の数である場合、別のアクションが挿入されると、最も古い行が自動的に削除されるため、常に最大 100 行になります。これを行うためにsqliteテーブルを構成する方法はありますか? または、cron ジョブを実行する必要がありますか?

明確化編集:いつでも、テーブルの最後の100(たとえば)アクション/イベント(行)を表示したいと思います。

4

3 に答える 3

21

もう 1 つの解決策は、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'); 
于 2010-01-10T02:38:20.327 に答える
4

INSERT で起動するトリガーを作成することもできますが、これにアプローチするより良い方法は、定期的に (週に 1 回など) 実行され、テーブルからレコードを削除するスケジュールされたジョブを単純に持つことです。

于 2010-01-10T01:47:58.957 に答える
3

テーブルを 100 行に制限するには、いくつかの方法があります。(簡潔にするために、以下のコードでは 5 行です。) SQLite バージョン 3.7.9 でテスト済み。

このすべてのコードは、SQLite がデータ型宣言を処理する方法の一種の癖に依存しています。(とにかく、私には奇妙に思えます。) SQLite では、3.14159 や「ウィブル」などのナンセンスをそのままの整数列に挿入できます。integer primary keyただし、 orと宣言された列に挿入できるのは整数のみです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');

6 回目の挿入は「エラー: 外部キー制約に失敗しました」で失敗します。

自動インクリメントの使用が完全に安全だとは思いません。他のプラットフォームでは、ロールバックによってシーケンスにギャップが残ります。自動インクリメントを使用しない場合は、「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)
);
于 2012-08-28T20:14:37.753 に答える