14

データ モデルを反映しなくなった従来のデータベース スキーマにとらわれていることは、すべての開発者にとって悪夢です。しかし、保守性のためにコードをリファクタリングするという話が飛び交っていますが、古いデータベース スキーマをリファクタリングするという話はあまり聞いたことがありません。

古いスキーマに依存するすべてのコードを壊すことなく、より良いスキーマに移行する方法に関するヒントは何ですか? 私は自分の要点を説明するために特定の問題を提案しますが、役立つことが証明されている他のテクニックについても気軽にアドバイスしてください。それらも役立つ可能性があります。


私の例:

私の会社は製品を受け取り、発送します。現在、製品の受領書と製品の出荷には、いくつかの非常に異なるデータが関連付けられているため、元のデータベース設計者は、受領書と出荷用に別のテーブルを作成しました。

このシステムを使って 1 年が経ちましたが、現在のスキーマはあまり意味がないことに気づきました。結局のところ、受け取りも発送も基本的には取引であり、それぞれ商品の金額を変更する必要があり、基本的には +/- 記号だけが異なります。実際、一定期間にわたって製品が変更された合計量を見つける必要があることがよくありますが、この設計では非常に扱いにくい問題です。

明らかに適切な設計は、ID が ReceiptInfo または ShipmentInfo テーブルのいずれかの外部キーである単一の Transactions テーブルを持つことです。残念なことに、間違ったスキーマが既に数年間運用されており、数百のストアド プロシージャと、そこから書き出された数千行のコードが含まれています。では、スキーマを正しく機能するように移行するにはどうすればよいでしょうか?

4

8 に答える 8

5

データベースのリファクタリングのカタログ全体を次に示します。

http://databaserefactoring.com/

于 2008-09-19T18:42:46.153 に答える
3

これを回避するのは非常に困難です。データベースをリファクタリングした後のいくつかの簡単なオプションは次のとおりです。

  • 元のスキーマに一致するビューを作成しますが、新しいスキーマからプルします。ビューの更新を処理できるように、ここでトリガーが必要になる場合があります。
  • 新しいスキーマを作成し、両側にトリガーを配置して、反対側を維持します。
  • 于 2008-09-19T18:43:19.177 に答える
    3

    この本 (データベースのリファクタリング)は、インベントリ データベースでほぼ同じ問題に対処しなければならなかったときを含め、レガシー データベース スキーマを扱うときに私にとって天からの贈り物でした。

    また、データベース スキーマへの変更を追跡するシステム (ソース コントロール リポジトリに格納されている一連の変更スクリプトなど) を用意しておくと、コードとデータベースの依存関係を把握するのに非常に役立ちます。

    于 2008-09-19T18:44:37.910 に答える
    1

    ここでは、ストアド プロシージャとビューが役に立ちます。システムがそれらを使用しない場合でも、それらを使用するように変更してから、その下のデータベースをリファクタリングします。

    その後、領収書と出荷がビューになります。

    注意してください、領収書と出荷は、私が扱ったほとんどのシステムで実際には2つの非常に異なる獣です. 領収書はサプライヤーにリンクされ、出荷は顧客 (または顧客/出荷先の場所) にリンクされます。在庫レベルでは、それらはしばしば同じように表されます。

    于 2008-09-19T18:44:08.270 に答える
    0

    場合によっては、より優れた構造を持つ新しいテーブルを作成してから、古いテーブルの名前を使用してビューを作成できますが、新しいテーブルのデータに基づいています。そうすれば、より良い構造に移行し始める間、コードが壊れることはありません。ただし、非リレーショナル テーブルから複数のレコードを持つリレーショナル構造に移動する場合もありますが、コードは 1 つしか想定していません。これは、サブクエリを使用する開発者がいる場合に特に当てはまります。

    次に、それぞれが変更されると、ビューから実際のテーブルに移動します。最終的には、ビューを削除できます。これにより、少なくとも、物事を動かしながら段階的に作業を続けることができますが、より良い設計を使用するために物事を修正し始めることができます.

    于 2008-09-19T18:47:52.520 に答える
    0

    すべてのデータ アクセスはストアド プロシージャに限定されていますか? そうでない場合、タスクはほぼ不可能になる可能性があります。その場合は、データ移行スクリプトが古いスキーマから新しいスキーマにうまく移行することを確認し、ストアド プロシージャが入力と出力を尊重することを確認する必要があります。

    うまくいけば、それらのどれにも「select *」クエリはありません。その場合は、'sp_help tablename' を使用して列の完全なリストを取得し、それをコピーして、各 * を完全な列リストに置き換えます。これは、クライアント コードを壊さないようにするためです。

    徐々に変更を加え、多くの統合テストを行うことをお勧めします。いくつかのバグを導入せずに大幅な改造を行うことは困難です。

    于 2008-09-19T18:40:43.803 に答える
    0

    最初に、テーブル スキーマを作成します。Enterprise Architect を使用して、レガシー データベースに対して既にそれを行いました。DB を選択すると、すべてのテーブル/フィールドが作成されます。次に、すべてをカテゴリに分割する必要があります。すべての商品の受け取りと発送をまとめて例に挙げます。クライアントのものは別のカテゴリに分類されます。すべてが明確になると、新しいテーブル、新しいリリース、および新しいフィールドを作成して、フィールドをリファクタリングできるようになります。もちろん、すべてがストアド プロシージャなしでアクセスされる場合、これには多くの変更が必要になります。

    于 2008-09-19T18:41:26.000 に答える
    0

    トランザクション テーブルの ID が ReceiptInfo または ShipmentInfo のいずれかへの外部キーであることは明らかではないと思います。逆に考えてみてください。オブジェクト指向モデルでは、トランザクション テーブルが必要であり、ReceiptInfo または ShipmentInfo にはトランザクション テーブルへの外部キーが必要です。運が良ければ、ReceiptInfo または ShipmentInfo で新しいレコードが作成されるコード内のポイントは 1 つか 2 つだけです。そこで、Transaction テーブルにエントリを追加するコードを追加し、その後、Transaction への外部キーを使用して ReceiptInfo または ShipmentInfo にエントリを作成する必要があります。

    于 2008-09-19T18:44:51.217 に答える