新しい機能を処理するためのデータベースのリファクタリングまたはアップグレード


9

データベーススキーマの質問に対するいくつかの回答は、現在の要件の一部ではない機能のデータベースを正規化するための追加のテーブルを提案しました(UserDepartmentテーブルは、従業員/ユーザーとそれらが異なる部門との多対多の関係を可能にします属します。)

正規化に反対ではありません。データベースの設計に関しては、誰かが将来的に望んでいると確信している機能を含めるように強く求められているようです。テーブル/フィールドをデータベースに追加して機能に対応することは、過度に設計する傾向があるので難しいですか?必要に応じて、他のアプリと同じようにリファクタリングまたはアップグレードされませんか?やり直しは決して楽しいものではありませんが、データをあるテーブルから新しいテーブルに移動することはできます。この考え方がどこで終わるのかわからない。

編集:これには多くの嫌悪感があります。データベースの大幅な変更を必要とする機能を追加しないプロジェクトや、新しいテーブルの代わりにDepartmentID2フィールドを追加するなどの非正規化されたアプローチがいくつあるのでしょうか?従業員が複数の部署を必要とすることは、よくあるドメインの問題です。多対多の関係で散らかされている多くのデータベーススキーマに気づかなかっただけです。


1
+1これをお問い合わせいただきありがとうございます。元の質問に対する回答を読むことで多くのことを学びましたが、これも洞察に満ちたスレッドです。
ジム、

回答:


3

データベースのリファクタリングについて書かれた本全体があります。コードのリファクタリングと同様に、データベースのリファクタリングには標準的な方法があります。唯一の違いは、コードのリファクタリングを行う場合、オブジェクト/コードの状態を考慮する必要がないことです。データベースではデータを考慮する必要があります。データを失うことはユーザー(または実際には誰にとっても) )。

データベースのリファクタリングについて詳しくは、こちらをご覧ください


このサイトがそもそも質問の
きっかけとなりました

14

コードのリファクタリングは簡単です。コードを変更して回帰テストを実行するだけです。

データベースのリファクタリングは困難です。(場合によっては膨大な量の)データを移動し、データが削除されていないことを確認し、新しいスキーマで制約が維持されていることを確認する必要があります。また、データの監査要件がある場合は、データの構成が異なる理由を説明し、リフレクター前のデータとリファクタリング後のデータを照合できる必要があります。また、古いバックアップが新しいスキーマと一致しないため、さらに別のリスクがあります。

怖いもの。


データベーステストに違いはありません。すべての変更には監査が必要であり、バックアップに影響します。この必要性を認識する前に、どのくらいのデータを蓄積しますか?データを変換した場合、この機能はさらに明白になります。
JeffO、2011

8
@Mathew Flynnの+1。この必要性を認識する前に、どのくらいのデータを蓄積しますか?数百万行。もう1つの問題は、多くの場合、データベースを使用しているのはアプリだけではないということです。データベースには多くのアプリが含まれている可能性があり、それらが存在することさえ知らない場合があります(例:ワイルドな「BI」アプリ)。データベーススキーマの変更恐ろしいです。
アンジェロ

2
時には数十億行
HLGEM 2011

1
何十億もの行を処理している場合、それらを移動する方法をよりよく理解している
JeffO

3

オーバーエンジニアリングに多くの時間を費やすことと、将来のかなりの時間を節約するのに十分な機能を追加するために少しの時間を費やすこととの間には微妙な境界があります。


1
孤立した1つまたは2つのインスタンスに対してこの議論をすることができますが、「時間」の「合計」がいつ多くなりすぎるのですか?
JeffO 2011

私自身の経験から、プロジェクトの大部分は実際にそうです。しかし、私はそれが経験とともにもたらされ、非常に主観的であることも推測します:)誰かがあなたに正確なレシピを提供できるとしたら私は驚かれるでしょう(したがって「細かい線」)。
0x4B1D 2011

@ジェフO:それは「ビット」になることはありません。システムは当初想定されていた時間枠とあなたの雇用の両方を長持ちさせる可能性があるため、硬化に開発時間を10%または20%投資する必要があります。
rwong 2011

3

理論としては、2つのテーブル間の多対多の関係をサポートするリンクテーブルを含めると、データに実際には多対1の関係しか存在しなくても、SQLは誰でも多対多がサポートされており、すべてが「うまくいく」だけです。

実際には、これが本当であることは通常はわかりませんが、SQLは多対多をサポートするために必要なものに近いと思います。

しかし、具体的に質問に行く、実際に、1対多から多対多への関係の変換にかなりの苦痛があります。その理由は、SQLはオブジェクトと同じ種類のカプセル化の目的で設計されておらず、ほとんどのクエリは、ビジネスレイヤーのオブジェクトを可視化するのに慣れているよりも多くのテーブルをデータベースレイヤーで使用するためです。

したがって、多対多の関係への変更は、元の2つのテーブルを含むすべてのクエリに影響を与え、多くの場合、ビジネスレイヤーで発生するよりもはるかに広いカスケード効果をもたらします。したがって、人々はこれが起こらないようにかなりの時間をかけます。

関係代数を指定するためにSQLよりも優れた言語があった場合、これは必要ありません。クエリ内のすべてのテーブルへの可視性を必要としないオブジェクトごとにSQLクエリを1つずつ構築できる場合、これは起こりません。LINQ(to SQLまたはEntities)のようなものはこれを解決しようとしますが、これは非常に複雑なソリューションであり、最適化は困難です(そして、LINQが言及され、集団のうめき声が毎回上がるDBAユーザーグループに行ったことがあります)。ファーストクラスのリレーショナル代数関数で普遍的にサポートされるデータベース言語を夢見ています...

それまでの間は、1対多から多対多にリファクタリングできますが、多くの作業が必要になる場合があります。


すべての関係を多対多に変えるつもりはありませんか?
JeffO、2011年

@Jeff O-よくわかりません。疑問がある場合は、元の質問に対するさまざまな回答で言及されている落とし穴を回避するために、多対多のモデルを作成します。ほとんどすべての関係を実際に多対多にしたデータベースを維持した後、私はそれをもう少し警戒しました。関係が1対多(実際には、それらはすべてでした)。したがって、彼らは両方の世界で最悪の事態にあった。自分のデザインでそれが起こったことは一度もありませんが、注意書きとしてそこにあります。
psr、2011年

3

私は通常、この方法でPHBに説明します。コードは壁と屋根であり、データベースは基盤です。

壁の移動と屋根の変更ができます。基礎を変えるには、壁や屋根を掘り起こして再構築する必要があります。

経験の浅い開発者(および大学の教授)が「過剰なエンジニアリング」と言っているのは、経験豊富な開発者が「将来の証明」と呼んでいるものです。仕様に記載されている内容にかかわらず、ALM中に何が変更されるか、またはパフォーマンスの問題が発生する場所がわかっているため、テーブル構造を正しく開始する必要があります。

更新スクリプトを顧客のサーバーにロールアウトすることは簡単なプロジェクトではなく、顧客の各DBAは、すべてをトリプルチェックしたいと思っています。結局のところ、いくつかの余分な列とテーブルはそれほど悪くありません。


1

一般的なルールは、関係が1対1であるかどうかです、将来的には多対多になり、多対多になる可能性あります。

従業員/部門は典型的な例です。ほとんどの小規模企業では、これはほとんどの場合、事実上、1対多の関係です。ただし、ほとんどの場合、それが多対多になる状況があります-エンジニアの1人が管理職に昇格しますが、エンジニアリング中に開発した製品をサポートする責任があります。または、営業担当者の1人が製品開発、しかし、彼は重要な顧客との密接な関係を持っているので、彼はまだその顧客のセールスマンをリードしています。

1対多を多対多として実装すれば、それ以上のコストはかかりませんが、多対多をサポートするようにデータベースとアプリケーションをリファクタリングすることは、費用がかかり、困難を伴います。


私は、クライアントがニーズを予期しない成熟したドメイン(HRなど)がたくさんあることに同意しますが、あなたはそれが必ず起こることを知っています。
JeffO、2011年

0

ソフトウェアの設計(およびおそらく他の多くのもの)を見るには2つの方法があります-戦術的ビューまたは戦略的ビュー。それぞれに独自の利点と欠点があります。

OOソフトウェアの変更が依然として苦痛であるとしても、コーディング部分が難しいだけでなく、苦情環境での本番への変更を促進するプロセス(現在の技術の状態を考えると)は、想定される大規模システムでは非現実的です24時間年中無休。

可能な場合は、共有ソフトウェアアーティファクトを戦略的に設計する」という私の原則に従います。これは、ある意味でYAGNIの原則に反するように思えるかもしれませんが、これは私の意見です。このアプローチにより、複雑さとリソースのコストを削減することができます。

あなたのケースでは、新しいジャンクションテーブルを追加するために必要なアクティビティには、設計、設計承認、スキーマの変更、3つのテーブルのCRUDのいくつかのメソッドの書き換え(一部の読み取りを除く)、インデックスの構築、GUIの作成が含まれます。新しいテーブルのCRUD。ユーザーが新しいテーブルの作成、更新などでPKを選択できるようにします。ああ、ところで、単体テスト、ユーザー受け入れテスト、システムテスト、および製品プロモーションを忘れないでください。

これでは不十分な場合、本当の悪夢は情報の損失に起因します。最初にジャンクションテーブルがなく、従業員と部門間の関連付け/分離が発生した日付をキャプチャすることにした場合、ジャンクションテーブルに日付を自動的に入力することはできません。それらを手動で入力する必要があります(データがある場合)。

したがって、これを最初から予測することをお勧めします。


すべては最初から予見する方が良いです。
JeffO、2011年

0

マシューが上で述べたように、データの管理も考慮に入れる必要があるため、ソフトウェアと比較してデータベースのリファクタリング/変更はしばしばより複雑になります。たとえば、データベースユニットテストの適切なスイートがあることを確認したり、「DB API」を使用してクライアントアプリケーションをベーススキーマから分離したりするのに役立つテクニックがあります-sprocs / viewsなど。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.