リレーショナルデータベースと反復開発


19

アジャイル手法、ドメイン駆動設計、オブジェクト指向分析および設計など、ソフトウェア開発への多くのアプローチでは、開発への1つの反復アプローチを採用することをお勧めします。

そのため、プロジェクトでの作業を初めて開始したときにドメインモデルを正しく実行することは想定されていません。代わりに、時間が経つにつれてモデルをリファクタリングします。なぜなら、時間とともに問題の領域をより深く理解できるからです。

それとは別に、完璧なモデルを事前に取得しようとしても、私はすでに非常に難しいと確信していますが、要件は変わる可能性があります。ソフトウェアがそのようにした後にしている生産に配備され、エンドユーザーは、一定の要件を完全に理解していなかったことに気づくかもしれない、あるいは悪化し、いくつかの要件が欠落していました。

ここでのポイントは、ソフトウェアの展開後にモデルの変更が必要になる場合があるということです。これが発生した場合、問題が発生します。本番データベースには重要なユーザーデータがあり、古いモデルの形式に既に適合しています

コードが適切に設計されておらず、システムが大きい場合、コードの更新は困難な作業になる可能性があります。しかし、それは時間とともに実行できます。Gitのようなツールを使用すると、本番対応バージョンを損傷することなくそれを実行できます。

一方、モデルが変更された場合、クラスのプロパティが消失した場合など、データベースも変更される必要があります。しかし、問題があります。そこには、失われないデータが既にあり、古いモデル用にフォーマットされています。

ここのリレーショナルデータベースは、エンドユーザーの要求に応じて反復的な開発を行ったり、ソフトウェアを更新したりすることを妨げる障壁になっているようです。

私がすでに使用したアプローチの1つは、古いデータベーステーブルを新しいテーブルにマップする特別なクラスをコーディングすることでした。したがって、これらのクラスは古い形式のデータを選択し、新しいモデルで使用される形式に変換して、新しいテーブルに保存します。

このアプローチは最良の方法ではないようです。ここでの私の質問は次のとおりです。リレーショナルデータベースで反復開発を調整するためのよく知られた推奨アプローチはありますか。


6
ちなみに、これは特にリレーショナルデータベースとは関係ないと思います。私が取り組んでいるプロジェクトにも同様の問題がありますが、非常に非リレーショナルなオブジェクトを表すJSON文字列のスキーマに問題があります。おそらくすべての形式の永続性に等しく影響します。
Ixrec

1
データを失わない方法でデータベーススキーマを変更します。en.wikipedia.org/wiki/Schema_migrationです。
-RemcoGerlich

1
このトピックは以前どこかで広範に議論されていたと思いますが、プログラマーで見つけることはできません。しかし、ここで参照martinfowler.com/articles/evodb.htmlまたはここstackoverflow.com/questions/334059/...
ドク・ブラウン

1
「それとは別に、完璧なモデルを事前に取得しようとしても、私はすでに非常に難しいと確信していますが、要件は変わる可能性があります。」(完璧に近い)モデルを前もって取得しようとしてもいけないことを付け加えたいと思います。それはあなたの選択肢を開いたままにするのではなく、あなたの考え方を1つのタイプのソリューションに結びつけるかもしれません。
ベント

回答:


15

特別なクラスである必要はありませんが、はい、以前の形式のデータベースを現在の形式に変換するものが必要です。

ここで重要なのは、これらのスクリプトを作成およびテストするためのプロセスを開発し、手動でテストデータベースと運用データベースに触れるのではなく、常に移行スクリプトによって訓練する必要があるということです。

データベースを変更する必要があるたびに、SQLまたはORMレイヤーを使用して、それを行うスクリプトを作成し、新しいスキーマを必要とする変更とともにバージョン管理にコミットします。次に、シーケンスでまだ適用されていないすべての移行スクリプトを適用してデータベースをアップグレードする制御スクリプトがあります。

また、スクリプトを適用し、動作しない場合は以前のバージョンにロールバックすることにより、共有開発、テスト、およびQA環境のみを変更するようにします。したがって、本番環境でそれらを解放するときに、意図したとおりに動作することを合理的に確信できます。

新規インストールは、すべてのスクリプトを適用するだけで簡単に実行されます。しばらくすると、数百台になり、非常に効率が悪いと思うかもしれませんが、最適化を試みるというtrapに陥らないでください。インストールは1回限りの作業であり、信頼性を維持することは迅速になります。

@Docブラウンはすでにリンクされ進化データベースの設計:Martin Fowler氏をして/programming/334059/agile-development-and-database-changes、と私は追加したいアレックスPapadimoulis:右を完了データベースの変更、短いですいくつかの例があります。

そのようなプロセスを実装するツールの適切な例として、Alembicをお勧めします。Python SQLAlchemyフレームワークに基づいていますが、独自の移行サポートがない場合は、他の言語やフレームワークで使用できます。スキーマの移行に関するウィキペディアのページには、このようなツールがリストされています


1
@Tiboでは、同じ一連のスクリプトを実行して、スキーマをゼロから構築します。それが問題の管理方法です。ことを考えると、標準としてあなたから得ることができる任意の現在のスキーマに、その同じことを自信を持っている-まだ存在していないものを含め-データベースのインスタンス。あなたの例のように2つの方法を持つ必要はありません。(少なくとも一貫したベースラインが与えられていない-最初のステップはベースラインを確立することであり、そのベースラインに到達すると問題は解決します。)
マーフ

1
アレックスの記事に賛成。短くはないかもしれませんが、より実践志向で面白い読み物になります。
マーフィー

1
私たちはアジャイルショップであり、100%の稼働率のサービスを実行しています。これらは両方ともDBに適用されます。実稼働スキーマは平均して1日に1回移行しますが、Janが言ったことはすべて2番目に控えます。私たちが行う非常に貴重なもう1つのことは、移行テストと呼ばれるものです。これは、ビルドおよびデプロイプロセスの一部として実行されます。本番環境からスキーマスナップショットを取得し、マスターから保留中の移行を適用し、そのスキーマに対して現在デプロイされている本番コードから単体テストを実行します。目標は、移行を適用しても実行中のシステムが破損しないことを確認することです。
ゴードンリグレー

1

奇妙なことに、これは現在の開発チームが直面しているまさに問題です。質問にはいくつかのサブ質問が含まれているため、個別に対処します。

何よりもまず、リレーショナルデータベースはデータモデルを過度に制約し、変更を非常に難しくしていますか?

最も確かに、しかし必ずしも引用された理由のためではない。残念ながら、リレーショナルデータベース管理システムの汎用性も、その衰退につながります。RDBMSは元々、大きなデータセットを受け入れて比較的小さなサイズに縮小する比較的単純なデータストレージプラットフォームを提供するために開発されました。これは、データモデルの複雑さと、必要な計算能力を犠牲にして行われました。データベースの複雑さが増すにつれて、データベース管理者が一貫性のあるスケーラブルな方法で複雑さに対処できるように、ストアドプロシージャ、ビュー、関数、およびトリガーが登場しました。

残念ながら、リレーショナルデータベースモデルはオブジェクト指向ではなく、データモデルのように実際のエンティティに自然にマッピングされません。そのため、オブジェクトリレーショナルマッパーなどの仲介者ツールが必要になります。残念ながら、これらのツールは明らかに今日の開発の世界での位置を占めていますが、その使用は、データモデルの実際の世界への不整合である根本的な原因ではなく、リレーショナルデータの複雑さの問題の症状を対象としています。

それは質問の2番目の部分につながります。これは実際にはより多くの仮定でしたが、質問と見なされるべきです。最初にドメインモデルを正しく実行することになっていますか?

はい、ある程度。質問が指摘したように、設計プロセスを開始するときに問題を完全に理解することはほとんど不可能です。ただし、ドメインの理解が深まるにつれて微調整される可能性があるものとは対照的に、完全に不正確なデータモデルの違いは、現実世界に一貫してマッピングされるモデルです。 これは、現実世界のエンティティに関する問題の理解と一致する初期データモデルを作成するためにあらゆる努力をする必要があることを意味します。 間違ったエンティティで正規化を開始すると、データモデルが2つの点で間違ってしまい、回復が困難になります。

多くの点で、「No SQL」データベースソリューションへの移行は、データモデルの一貫性の問題の結果です。オブジェクト指向のNo SQLアプローチを使用すると、コード内のオブジェクトと現実世界のオブジェクトとの間のマッピングについてより深く考えることができます。データベース。これにより、全体的な設計が改善されます。

それが最後の質問につながります:リレーショナルデータモデルはアジャイルアプローチと矛盾していますか?

いいえ、しかしより多くのスキルが必要です。 No-SQLの世界では、フィールドを追加したり、プロパティを配列に変換したりするのは簡単ですが、リレーショナルの世界でこれらのことを行うのは決して簡単ではありません。少なくとも、リレーショナルデータモデルとそれらが表す実世界のエンティティの両方を理解できる人が必要です。この人は、実世界のモデルの理解が変化したときにリレーショナルモデルの更新を促進する個人です。この問題を解決する特効薬はありません。


1
ステートメントをよりドラマチックにするために、RDBMSテーブルに新しいフィールドを作成する問題を大きくしたことを本当に願っています。データベーステーブルは、1つのフィールドを追加する問題を実際に作成するために、非常に特殊である必要があります(または、新しいフィールドタイプは例外的なものである必要があります)。
アレクセイ・ジマレフ16

はい、しかしそれはただ一つのフィールドではありません
...-theMayer

1
もっと頻繁に言うと、それはたった一つのフィールドです。劇的なスキーマの変更はそれほど頻繁ではありません。私は、インピーダンスの不整合のために、OOデザインでRDBMSを使用することを好みません。ただし、新しいタイプ(テーブル)とプロパティ(列)の追加はどちらの世界でも比較的簡単ですが、NoSQLでは実際に少し簡単です。しかし、どちらの場合も複雑な変更は苦痛です。さらに悪いことに、スナップショットを使用するイベントソースシステムでは、そのようなシステムの開発経験がどれほど楽しいかとは逆になります。
アレクセイ・ジマレフ16

リレーショナルデータベースは、データストレージのニーズを解決するための「ユニバーサルハンマー」としてよく使用されます。実際、それらを使用する非常に具体的な理由があります。慎重に考え抜かれたシステムでは、回答で書いた問題を心配する必要はほとんどありません。適切なシステム設計を事前に経験したことのない、より一般的な聴衆を対象にしています。
-theMayer

リレーショナルモデル間に矛盾はありません。通常、他の種類のモデルと同様に、実際の世界にマッピングされます。一部の操作は、ある種類ではより簡単になり、別の種類ではより簡単になります。問題は、ある種類のモデル(オブジェクト指向)を作成し、別の種類のツール(リレーショナル)で実装しようとすることです。それはうまくいきません。しかし、現実の世界はオブジェクト指向ではありません。それだけであり、あなたはそれをモデル化します。また、選択した種類のモデルに適したツールを使用する必要があります。
Jan Hudec

-1

主なポイントは、モデルがすべての認識を超えて変化するほどリファクタリングしないことです。反復的な開発であっても、実際に既存のものの上に構築し、リファクタリングしないでください。

これにより、大きな変更を処理する2つの主なオプションが提供されます。1つ目は、DBレイヤーをAPIとして構築し、ストアドプロシージャを使用して、基になるデータスキーマを変更せずにクライアントに合わせて変更できるようにすることです。

もう1つの方法は、テーブルを少しのデータ移行で置き換えることです。大規模な変更が必要な場合は、新しいスキーマを作成し、一連のスクリプトを実装して古いデータを取得し、新しい形式にマッサージします。これを行うには時間がかかります。そのため、最初の選択肢として、データへのアクセスを変更するより安価な方法(SP経由など)にもっと頼るのです。

だから:1.物事を変える必要がないように、デザインを先に考えてみてください。

  1. ラッパーまたはAPIに依存しているため、変更は制限されているか、隔離されたコンポーネント内に隠すことができます。

  2. 必要に応じて、適切にアップグレードするために時間をかけてください。

これらの手順は、データベースだけでなくすべてに適用されます。


基になるスキームを変更する必要がある場合あります。アプリケーションが顧客テストに入ると、聞いたことのない新しい属性が出現し、数字だと思った属性が文字列であることが判明し、1:1であると予想される関係が結局はそうではないことが判明します。ストアドプロシージャの背後にあるこの種のことをカバーすることはできません(データベース内の他の物と同様に、バージョン管理に住んでいないため、ストアドプロシージャは問題の一部です)。
Jan Hudec

@JanHudecは、いつSPがバージョン管理に含まれないのですか?そのようなことをカバーすることができます。SPAPIを変更して文字列を取得し、それを別のフィールドに書き込み、SPのコードのビットで古い数字と新しい文字列を処理します。最高ではありませんが、すべての顧客サイトに行ってデータを新しい文字列形式に移行するよりも良い場合があります(より良い例がありますが、アイデアは得られます)。変更が大きい場合は、移行する必要がありますが、少なくともDB APIには他の安価なオプションもあります。
gbjbaanb

SPをインストールして新しいフィールドを追加するには、各カスタマーサイトに移動する必要があります。そして、そこにいるときは、データも移行できます。SPは、データベースにアクセスする複数のアプリケーションがある場合に下位互換性のあるインターフェイスを作成できるため、すべてを同時にアップグレードする必要がないという点で便利です。ただし、要件の変更によりスキーマを変更する必要がある場合は、手順を保存しません。
Jan Hudec
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.