2

SQLite docsによると、自動インクリメント列を取得する唯一の方法は主キーです。

複合主キーが必要ですが、自動インクリメントも必要です。SQLite でこれらの両方を達成する方法はありますか?

PostgreSQL で記述したテーブルの関連部分:

CREATE TABLE tstage (
    id                   SERIAL NOT NULL,
    node                 INT REFERENCES nodes(id) NOT NULL,
    PRIMARY KEY (id,node),
    -- ... other columns
);

この要件の理由は、すべてのノードが最終的にデータを単一の集中型ノードにダンプするためです。単一列の PK では衝突が発生します。

4

3 に答える 3

2

ドキュメントは正しいです。ただし、トリガーで自動インクリメントロジックを再実装することは可能です。

CREATE TABLE tstage (
    id    INT,  -- allow NULL to be handled by the trigger
    node  INT REFERENCES nodes(id) NOT NULL,
    PRIMARY KEY (id, node)
);

CREATE TABLE tstage_sequence (
    seq INTEGER NOT NULL
);
INSERT INTO tstage_sequence VALUES(0);

CREATE TRIGGER tstage_id_autoinc
AFTER INSERT ON tstage
FOR EACH ROW
WHEN NEW.id IS NULL
BEGIN
    UPDATE tstage_sequence
    SET seq = seq + 1;

    UPDATE tstage
    SET id = (SELECT seq
              FROM tstage_sequence)
    WHERE rowid = NEW.rowid;
END;

my_sequence(または、複数のテーブルがある場合は、テーブル名を持つ共通のテーブルを使用します。)

于 2013-01-04T10:41:55.170 に答える
1

どうですか...

仮定

  • PK の一意性のみが必要であり、連続性は必要ありません
  • ソース テーブルに PK がある

1 つの余分な列、ノード番号を含む中央テーブルを作成します...

CREATE TABLE tstage (
    node  INTEGER NOT NULL,
    id    INTEGER NOT NULL,   <<< or whatever the source table PK is
    PRIMARY KEY (node, id)
       :
);

集中ノードにデータをロールアップするときは、ソース ノードの番号を「node」に挿入し、「id」をソース テーブルの PRIMARY KEY 列の値に設定します。

INSERT INTO tstage (nodenumber, sourcetable_id, ...);

nodenumber+sourcetable_id は常に一意であるため、中央テーブルに別の自動インクリメント列を維持する必要はありません。

于 2013-01-05T13:56:21.030 に答える
1

トリガーは機能しますが、複雑です。もっと簡単に言えば、シリアル ID を避けることができます。1 つのアプローチとして、 GUIDを使用できます。残念ながら、デフォルトで SQLite に GUID を生成させる方法が見つからなかったため、アプリケーションで生成する必要があります。GUID 型もありませんが、文字列またはバイナリ blobとして格納できます。

または、適切なキーとして機能する他の列に何かがあるかもしれません。選択したタイムスタンプ形式の解決よりも頻繁に挿入が発生しないことがわかっている場合 ( SQLite にはいくつかの形式があります。セクション 1.2 を参照してください)、おそらく(node, timestamp_column)良い主キーです。

AUTOINCREMENTまたは、SQLite のを使用することもできますが、生成されたシリアルが衝突しないように、テーブルを介して各ノードに開始番号を設定します。sqlite_sequenceSQLite は 64 ビットの数値であるためrowid、ノードごとに一意の 32 ビット数値 (IP アドレスは便利で、おそらく一意の 32 ビット数値) を生成し、それを左に 32 ビットシフトするか、同等に乗算することで、これを行うことができます。したがって、64 ビットrowidは実質的に 2 つの連結された 32 ビット数になりNODE_ID, RECORD_ID、1 つのノードが 40 億を超えるレコードを生成しない限り衝突しないことが保証されます。

于 2013-01-05T01:21:48.600 に答える