web-dev-qa-db-ja.com

同じ外部キー値を共有する行のセットごとに一意のシーケンスを作成します

私のシステムでは、各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から始まります。

この問題を解決するために一般的に受け入れられているアプローチはありますか?

3
RedSulfur

これは何度も尋ねられました。長いものと短いもの:やってはいけない試してみてください。同時実行性、行の削除によって生じるギャップなど、あらゆる種類の問題に遭遇します。idを単純な serial 列にして、VIEWuser_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列を使用してソート順を決定します。

詳細:

6

これは、ウィンドウ関数を使用する必要があるようです。何かのようなもの:

SELECT user_id, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY article)
FROM [table]

追加のメモとして、順序付けが静的であり、ウィンドウ関数のORDER BY句に基づいて同じ順序になるようにする必要があります。

2
codedawg82

あなたはビュー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
0
paparazzo