私のシステムでは、各userに独自のidシーケンスを持たせたい彼の記事。
そこで、users
とそれらのarticles
の間の対応を表すテーブルを持つデータベースを作成しました。このようなテーブルの概要は次のとおりです。
+ ------ + ---------- + --------- + | id |記事| user_id | + ------ + ---------- + --------- + | 1 |メモ| 1 | + ------ + ---------- + --------- + | 2 |メモ| 1 | + ------ + ---------- + --------- + | 3 |メモ| 2 | + ------ + ---------- + --------- + | 4 |メモ| 2 | + ------ + ---------- + --------- + | 5 |メモ| 3 | + ------ + ---------- + --------- +
しかし、次の方法でこのテーブルにids
を生成したいと思います。
+ ------ + ---------- + --------- + | id |記事| user_id | + ------ + ---------- + --------- + | 1 |メモ| 1 | + ------ + ---------- + --------- + | 2 |メモ| 1 | + ------ + ---------- + --------- + | 1 |メモ| 2 | + ------ + ---------- + --------- + | 2 |メモ| 2 | + ------ + ---------- + --------- + | 3 |メモ| 2 | + ------ + ---------- + --------- + | 1 |メモ| 3 | + ------ + ---------- + --------- +
したがって、関連するuser
テーブルに新しいuser
が作成されると、彼の記事のid
シーケンスは1から始まります。
この問題を解決するために一般的に受け入れられているアプローチはありますか?
これは何度も尋ねられました。長いものと短いもの:やってはいけない試してみてください。同時実行性、行の削除によって生じるギャップなど、あらゆる種類の問題に遭遇します。id
を単純な serial
列にして、VIEW
user_id
。
CREATE VIEW v_user_article AS
SELECT *, row_number() OVER (PARTITION BY user_id ORDER BY id) AS per_user_id
FROM user_article;
「いくつかのメモ」を含む列article
は、設定にとってほとんど意味がありません。そして、最後にソートされない新しい記事ごとに番号が変わるため、それによる順序付けはさらに意味がありません。安定したソート順と安定した番号(削除を除く!)を取得するには、serial
列を使用してソート順を決定します。
詳細:
これは、ウィンドウ関数を使用する必要があるようです。何かのようなもの:
SELECT user_id, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY article)
FROM [table]
追加のメモとして、順序付けが静的であり、ウィンドウ関数のORDER BY
句に基づいて同じ順序になるようにする必要があります。
あなたはビューrow_number()ソリューションで行ったことは良い
ハードコーディングに行き詰まった場合
私はこれがMSSQLで機能することを知っていますが、postgresqlでテストしていません
insert into table (article, user_id, id)
select @article, @user_id, isnull(max(id), 0)+1 as [id]
from table where user_id = @user_id