警告: この悲惨な話には、コードの臭い、設計上の決定の誤り、および技術的負債の例が含まれています。
SOLID の原則に精通している場合は、TDD を実践し、作業の単体テストを行ってください。誰かの不幸を笑い飛ばしたり、自分の後継者のためにそのような途方もないがらくたの山を決して残したりしないことを知って、自分自身の素晴らしさにうめき声を上げたりしたくない場合を除きます。
それで、あなたが快適に座っているなら、私は始めます。
私が継承し、過去 7 か月間サポートとバグ修正を行ってきたこのアプリでは、6 か月半前に去った開発者によって、私はボールアップの DOOZY を残されました。はい、始めて2週間。
ともかく。このアプリにはclients
、employees
とvisits
テーブルがあります。
と呼ばれる (または同様のもの) というテーブルもありますAppNewRef
... それを待つ... 他の各テーブルに使用する次のレコード ID が含まれています。したがって、次のようなデータが含まれる場合があります:-
TypeID Description NextRef
1 Employees 804
2 Clients 1708
3 Visits 56783
アプリケーションが の新しい行を作成するとき、テーブルをEmployees
調べてAppNewRef
値を取得し、その値を ID に使用して、NextRef
列を更新します。Clients
、および使用Visits
する他のすべてのテーブルについても同じことNextID
がここに格納されます。
はい、わかってIDENTITY
います。このデータベースには列の自動番号付けはありません。いずれも「Accessアプリだった頃」という言い訳で。これらの ID は (VB6) コードで long として保持されます。したがって、最大 21 億 4,700 万レコードが可能です。OK、それはかなりうまくいっているようです。(データベースではなく、アプリが更新し、ロック/更新などを処理しているという事実は別として)
そのため、ユーザーは非常に満足して 、 などを作成Employees
しClients
ていますVisits
。Visits ID
は、一度に数十個ずつ着実に増加しています。その後、問題が発生します。サーバーが正常に動作しなくなり、アプリが応答しなくなるため、訪問のバッチを作成しているときにクライアントがデータベースの破損を引き起こしています。そのため、彼らは辛抱強く待つのではなく、タスク マネージャーを使用してアプリを強制終了します。確かに、アプリはロックされているようです。
今年の初めにロールバックすると、開発者のティム (本名。ここでは有罪を保護するものではありません) は、UI が「レスポンシブ」のままになるように、段階的にバッチ更新を行うようにコードを変更し始めました。それからエイプリルがやって来て、彼は通知を処理しており(今のシーンを想像できますよね?)、彼は更新を完了するためにビーブリングしています。
4 月末と 5 月初めに、一部のクライアントを更新します。今後数か月にわたって、それらの多くを更新します。
ティム (本名、覚えておいてください) と私 (ティムが去る 2 週間前に開始した)、および 1 週間後に開始した他の新しい開発者には見えませんが、訪問テーブルの ID は大きく飛躍し始めます。巨大とは、一度に 10000、20000、30000 を意味します。場合によっては数十万。
これは、使用される ID の急速な増加を示すグラフです。
11 月にロールします。顧客がテクニカル サポートに電話し、エラーが発生したと報告しました。エラー メッセージを見て、コードをデバッグできるようにデータベースを要求します。長い間、値が大きすぎることがわかりました。いくつかのクエリを実行し、情報を取得して Excel にドロップし、グラフ化します。
このアプリはその ID を他の DLL や OCX に渡し、それらのインターフェイスを壊すことは、私がやっている傷の全世界のように思えます。今は出会いたくない。
私が調査している潜在的なアイデアの 1 つは、ID を変更して、ID をより低いレベルに下げることができるようにすることです。基本的にギャップを埋めます。ROW_NUMBER
機能の使用
私が考えているのは、これらの訪問IDへの外部キー参照を持つ各テーブルに新しい列を追加することです(適切な外部キーの心ではなく、これらの制約はこのデータベースには存在しません)。この新しい列には、訪問 ID の古い (現在の) 値を格納できます (混乱させるために、一部のテーブルでは と呼ばれEventID
、一部のテーブルでは と呼ばれていVisitID
ます)。
次に、その を参照する他の各テーブルについてVisitID
、新しい値に更新します。
アイデア?提案?T-SQL のスニペットは、感謝して受け取ったすべての人を支援します。