web-dev-qa-db-ja.com

このデータベースをリファクタリングする必要がありますか?どうすればできますか?

まず、いくつかのコンテキスト。

私は10年以上の開発とドキュメントなしでプロジェクトで働いています。私のタスクは、各テーブルのすべての列を含む辞書を含む、データベース(SQLServerデータベース)の包括的なドキュメントを作成することです。

分析の結果、データベースに古い列が見つかり、以下のような多くの問題が見つかりました。

  • 意味的な意味のない名前(「値」列など)。
  • すべての行が「NULL」に設定された列(おそらくもう使用されません)。
  • 一部のテストまたは特定のタスクのためにずっと前に作成された列(たとえば、「test_3」および「client3_sync」列)。

要するに、データベースは混乱しているので、それを修正する方法を考えています。私はこれを発見しました リンク データベースのリファクタリングについて、これについて2つの質問があります:

  1. このデータベースをリファクタリングする必要がありますか?この廃止された未使用の列をそのまま残すことの問題は何ですか?結局、それらは使用されていません。
  2. リファクタリングの場合、どうすればよいですか? this は標準的なアプローチですか?不要な列を削除しないのはなぜですか?
4
James

リファクタリングの鍵は、インターフェースを壊さないことです。データベースには、データを失わないという2つ目の懸念もあります。 SQLサーバーデータベースが主にテーブルである場合、実際のテーブルを別のスキーマ(おそらくdboよりも説明的なもの)に割り当て、古いschema.TableNameでビューを作成できます。

これで、古いシステムから新しいシステムへのアプリケーションに加えられた変更をバッファリングする方法ができました。

例:未使用のフィールドの削除。データを変更するアプリの部分から始めます。このフィールドに変更コードがない場合は、テーブル(すべてnullのフィールド)からフィールドを削除できますが、ビューでは次のようになります。

Select Null as OldFieldName from NewSchema.OldTableName;

私はこの見方を考慮して、自己文書化コードになることから始めます。列名の文書化を開始する場合は、それらに意味のある名前を付けるプロセスを開始してみませんか?

例:列の名前を変更テーブル内の列の名前を変更することはそれほど難しくありませんが、ビューで古い名前をエイリアス名として維持します。

Select NewColumnName as OldColumnName from NewSchema.OldTableName;

テーブルで同じことができなかった理由はありません。

これで、アプリケーションを段階的に変更して、古いテーブル名と列(ビュー)から新しいテーブルと新しい列(削除しない限り)に移行できるようになりました。その後、古いテーブルの外観を誰かが見たい場合は、ソース管理履歴のコードを使用してビューを削除できます。

列を別のテーブルに移動することはビューで処理できますが、SQLサーバーでは、ビューが一度に複数のテーブルのデータを変更しようとした場合、ビューは更新可能とは見なされません。これを回避する1つの方法は、古い列を保持することですが、テーブルにトリガーを設定して、この列のデータを他のテーブルの新しい列に自動的にコピーします。すべてのアプリコードが新しい列を使用するように変更されたら、古い列とトリガーを削除できます。

データベースにはスキーマだけではなく、データの変更も考慮する必要があることに注意してください。

データベースの使用方法を損なうことなくデータベースの責任を取ることは難しい仕事です。この方法では、物事に適切な名前を付け、開発チームと戦略を調整して不要になったものを取り除くことで、データベースをより詳細に制御して理解できるようになると思います。

2
JeffO

あなたの仕事は文書化しています。だからそれに固執する。

データベースのマイレージを考えると、データベースのいくつかの側面について、あなたが見る-反対する-確率は非常に大きいです。

したがって、そのタスクを実行しているときに、タスクの最後に、ドキュメント-実際の状態-および考慮事項-どのように改善できるかを考えてください。

私見彼らはそれを改善するための戦略をたどるために物事が現在どのようになっているのかを知ることを試みています。

7
linuxunil

承認とデータベースの使用目的の理解なしにデータベースを変更したくないのは確かです。列の順序と数をハードコーディングするコード実装を見てきました。列を削除すると、col [4]が異なる、またはcol [9]がないため、全体が爆発するのと同じくらい多くなります。 (そして、アクセス前にインデックスをチェックしません)。

私はこのような迷惑メールをよく見ました:

// DB: ID - FIRST_NAME- TEST_FLAG - LAST_NAME

cols = get_cols(result);

firstName = cols[1];
lastName = cols[3];

未使用のTEST_FLAG列を削除して、kaboom!さらに悪いことに、最後の列が使用されておらず、真ん中の列を突然変更すると、パブリックデータフィールドにプライベート情報が割り当てられるなど、誤って割り当てられます。 DBスキーマを次のように切り替えます。

DB: ID - FIRST_NAME- TEST_FLAG - LAST_NAME - USERNAME - PASSWORD

...そしてええと、ユーザー名などの一般にアクセス可能なリストがある場合、今ではcolsが1に切り替えられているため、すべてのユーザーのパスワードが公開されています。

悪いコード、はい。実際のコード?悲しいことに、そうです。不正な推測を行ったため、システム全体をクラッシュさせることは望ましくありません。

別の、それほどひどくない例は、オブジェクトリレーショナルコードであり、TEST_FLAGはオブジェクトにマップできますが、使用されていなくても、コードはそれが存在することを予期しており、ミスマッチ。

ここで、このシステムを文書化し、改善のためのメモを作成し、次に、改善されたシステムに移行するリファクタリングフェーズについて説明しても何も問題はありません。ただし、この種のナンセンスはデータベースを使用するシステムのどこにでも存在する可能性があるため、システムを広範囲にテストする必要があります。ほとんどの自動化された/インテリジェントなIDEも、データベーススキーマを認識する方法でセットアップされていないため、この種のエラーをキャッチできません。

これらはすべて、より優れた、より復元力のあるコードで対処できますが、多くの開発者は、データベーススキーマにわずかな変更を加えても壊れないコードを作成することを学んだことがありません。

7
BrianH

1)リファクタリングする必要がありますか?

これは職場の文化に大きく依存します。一部の組織は、開発者が発見した問題の所有権を取り、解決策を見つける責任を負うことを期待しています。他の人は、あなたがしなければならない仕事(データベースを文書化する)だけをし、絶対にそれ以上はしないと期待します。いずれにしても、データベースのリファクタリングはやや危険な操作であるため、影響を受ける可能性のあるチームに少なくとも情報を提供し、賛同を得ることをお勧めします。

他の回答を読むことは、2番目の種類の組織が最も一般的であるようです。私の経験は、新興企業であり、多くの場合、小規模な組織は最初のタイプですが、大企業は2番目のタイプです。これは、あなたが現在どのような組織に属しているかを発見する良い機会だと思います。そのため、そのような問題が発生した場合に実行することが予想されるアクションを上司またはチームに尋ねてください-修正を開始し、誰かに報告してください。または単に無視して、割り当てられたタスクに焦点を当てます。これらの文化的要因を理解することは、あなたの仕事を進める上で非常に役立ちます。

もちろん、この電話をかけることができる技術的な上司がいない場合は、自分で電話をかけ、それによってどのような組織が必要かを決める必要があります。

2)どのように進めますか?

レポート、スケジュールされたSQLスクリプト、およびデータベースによって影響を受ける可能性のあるその他のものを含む、データベースを使用するすべてのアプリケーションの概要を確立します。

これらのアプリケーションがデータベースにアクセスする方法を特定します。 ORMレイヤーを通じて?直接SQLクエリを通じて?ストアドプロシージャとビューを通じて?動的SQL? select * from流行?

あなたのアプローチは、これらの質問の答えに大きく依存します。

ORMを介してDBにアクセスする単一のアプリケーションがある場合、それは簡単です。コードが何らかの方法で古い列に依存しているかどうかをコード分析で識別でき、そうでない場合は削除します。データベースと一緒にマッピングを更新する必要があるだけなので、名前の変更もかなり簡単です。

複数のアプリケーションまたはSQLを動的に生成するアプリケーションがある場合、さらに複雑になります。データベースの外観を表すビューのセット(古い列の削除、列の名前の変更など)を作成し、アプリケーションを徐々に移行してこれらのビューを使用することをお勧めします。その後、すべてのアプリケーションが移行されたら、基になるテーブルを変更してビューをミラーリングできます。使用するデータベースシステムのタイプは、そのようなビューに更新または挿入できる範囲に影響します。

もっと詳細に説明することはできますが、特定のセットアップについて詳しく知らなければ、非常に広範囲に及ぶでしょう。たぶん、上記の質問に対する回答で質問を修正すると、より役立つ回答が得られるでしょう。

4
JacquesB

データベースを変更する権限があると仮定すると、十分な予算があり、それ自体のリファクタリングだけでなく、変更後の信頼できる(!)テストのために、データベースをリファクタリングする必要があります。また、変更後に何かが機能しなくなることがわかった場合の運用システムのダウンタイムのリスクを見積もり、会社がこれに余裕があることを確認してください。

これらの点により、10年前のdbのリファクタリングが予想よりもはるかに高価になることがよくあります。データベース列の削除は簡単です。この変更がおそらく何も壊さないという確信を得ることも簡単です。あなたが本当にを壊していないことを確認するのは難しいです!

4
Doc Brown