9

典型的な SaaS アプリケーションで、特定のユーザーの auto_incrementing 整数をどのように生成しますか?

たとえば、特定のユーザーのすべての請求書の請求書番号は、auto_incrementing で、1 から始まる必要があります。Rails id フィールドは、すべてのユーザー間で共有されるため、この場合は使用できません。

頭のてっぺんから、ユーザーが持っているすべての請求書を数えてから 1 を足すことができますが、もっと良い解決策を知っている人はいますか?

4

6 に答える 6

4

リレーションデータベースの典型的な解決策は、次のようなテーブルです

user_invoice_numbers (user_id int primary key clustered, last_id int)

およびストアド プロシージャまたは次のような SQL クエリ

update user_invoice_numbers set last_id = last_id + 1 where user_id = @user_id
select last_id from user_invoice_numbers where user_id = @user_id

ユーザーに対しては機能しますが (各ユーザーが同時に実行するトランザクションがいくつかある場合)、企業に対しては機能しません (たとえば、companys_invoice_numbers が必要な場合)。同じ会社内の異なるユーザーからのトランザクションが互いにブロックされ、パフォーマンスのボトルネックが発生する可能性があるためです。この表で。

チェックする必要がある最も重要な機能要件は、システムで請求書の番号付​​けにギャップが許容されているかどうかです。標準のauto_incrementを使用する場合、ギャップを許可します。これは、私が知っているほとんどのデータベースでは、トランザクションをロールバックするときに、増分された数がロールバックされないためです。これを念頭に置いて、次のガイドラインのいずれかを使用してパフォーマンスを向上させることができます

1)実行時間の長いトランザクションから新しい番号を取得するために使用する手順を除外します。請求書への挿入手順が、複雑なサーバー側ロジックを伴う長時間実行トランザクションであるとします。この場合、最初に新しい id を取得してから、別のトランザクションで新しい請求書を挿入します。最後のトランザクションがロールバックされる場合、自動番号は減少しません。ただし、user_invoice_numbers は長時間ロックされないため、多数の同時ユーザーが同時に請求書を挿入できます。

2)従来のトランザクション データベースを使用して、各ユーザーの最後の ID を持つデータを保存しないでください。キーと値の単純なリストを維持する必要がある場合、それを実行できる小さいながらも高速なデータベース エンジンが多数あります。キー/バリュー データベースのリスト。おそらくmemcachedが最も人気があります。過去に、単純なキー/値ストレージが Windows レジストリまたはファイル システムを使用して実装されているプロジェクトを見てきました。各ファイル名がキーで、各ファイル内に最後の ID があるディレクトリがありました。そして、この大まかな解決策は、ロックが非常に迅速に発行および解放され、トランザクション スコープに関与しなかったため、SQL テーブルを使用するよりも優れていました。

私の提案する最適化があなたのプロジェクトにとって複雑すぎると思われる場合は、実際にパフォーマンスの問題が発生するまで、今は忘れてください。ほとんどのプロジェクトでは、追加のテーブルを使用した単純な方法でかなり高速に動作します。

于 2009-07-09T16:29:24.610 に答える
2

ユーザーの最新の請求書番号を追跡する「ユーザー」テーブルに関連付けられた別のテーブルを導入できます。ただし、この値を読み取るとデータベースクエリが発生するため、提案したように、ユーザーの請求書の数を取得して追加することもできます。いずれにせよ、それはデータベース ヒットです。

于 2009-07-09T15:49:36.670 に答える
2

請求書番号がユーザー/顧客ごとに独立している場合、ユーザーに関連付けられた永続ストア (DB レコードなど) に「lastInvoice」フィールドを持つことは避けられないようです。ただし、これにより、「最新」の番号に対する競合が発生する可能性があります。

ユーザーに請求書 1、2、3、および 5 を送信し、請求書 4 を送信しないことは本当に問題なのでしょうか? 要件を少し緩和できれば。

要件が実際に「すべての請求書番号が一意でなければならない」という場合は、通常の ID 生成トリックをすべて見ることができ、これらは非常に効率的です。

数字が連続していることを確認すると、複雑さが増しますが、それはビジネス上のメリットにつながりますか?

于 2009-07-09T15:53:33.997 に答える
1

あなたのニーズを解決するはずのgemをアップロードしました(数年遅れるよりはましです!):)

https://github.com/alisyed/sequenceid/

于 2011-05-31T08:19:42.760 に答える
0

これが最善の解決策かどうかはわかりませんが、最後の請求書 ID をユーザーに保存し、それを使用して、そのユーザーの新しい請求書を作成するときに次の ID を決定できます。しかし、この単純な解決策は整合性に問題がある可能性があるため、注意が必要です。

于 2009-07-09T15:47:45.223 に答える
0

インクリメンタル形式で請求書 ID を生成しますか? これはセキュリティ ホールを開けませんか (ユーザーが請求書番号の生成を推測できる場合、要求でそれを変更でき、情報漏えいにつながる可能性があります)。理想的には、数字をランダムに生成します (そして、使用された数字を追​​跡します)。これにより、衝突も防止されます (番号が範囲にわたってランダムに割り当てられるため、衝突の可能性が減少します)。

于 2009-11-09T07:03:18.513 に答える