web-dev-qa-db-ja.com

SQLの変更をより効果的に確認するにはどうすればよいですか?

私の経験から、SQLコードの変更はほとんど常に増分ではない傾向があります。誰かが新しいストアドプロシージャを作成するか、最適化のために埋め込みSQLクエリ全体を変更するか、まったく新しいテーブルを作成します。これらのコードレビューリクエストのいずれかを受け取ったとき、SQLクエリ全体を理解する以外に方法を見つけることができませんでした。多くの場合、これらは非常に長いネストされたクエリであり、他のプロシージャを呼び出すことがあります。これらの変更を理解して検証することは、非常に大きな作業になります。次に、3つのオプションが残されます。

  1. 慎重に検討せずに承認します。
  2. 行ごとにかなりの時間を費やし、データモデルを理解し、何らかのテストシステムでクエリを実行して、何が生成されるかを確認します。
  3. その人に変更について説明してもらいます。

1や3をやりたくありません。しかし、クエリ全体が何をしているのか、新しいバージョンが同等で高速に動作するかどうかを理解するのに何時間も費やしたくありません。

このプロセスを容易にする技術、ツール、または方法論はありますか?他の人は、あまり苦労せずにそのようなレビューをどのように実行しますか?

通常のコード変更との根本的な違いの1つは、SQLの変更が(少なくとも概念的には)全体的な書き換えになり、問題がより頻繁に発生するようです。私にとって、ほとんどすべてのSQLレビューで毎日行っています。

どんな推薦でも大歓迎です。

更新:

レビューを却下したり、作成者に変更をより明確に書き直したり、コメントやテストを追加したりできます。しかし、私が探しているのは、レビュアーとして実際にレビューを実際に行う方法です。これまでのほとんどの答えは、コードの変更を改善して、より簡単に確認できるようにすることです。それは明らかです。一方、ここでの実際的な問題は、著者の行動を変更したり組織を再構成したりせずに、レビューを著者に戻さずに対処する必要があることです。

また、一般的なコードレビューの推奨事項ではなく、SQL固有の推奨事項を期待しています。コードベースがどれほど悪かったり、コードの記述方法がどれほど悪かったりしても、レビュアーを助けるツールがあることを期待しています。

個人的には、20年近く開発者として大小さまざまな企業で働いていました。私はオープンソースプロジェクトを維持しており、コンピューターサイエンスの博士号を取得しています。 「他の人を変えるとあなたの世界が良くなる」タイプの実用的でない答え以上のものを教えてくれる助けをいただければ幸いです。

11
CEGRD

あなたはこれが好きではないかもしれませんが、:

これは、追加のテクノロジーやツールによって簡単に解決できる問題ではありません。

「長いネストされたクエリ、場合によっては他のプロシージャを呼び出す」を含み、簡単に理解できないSQLには、少なくとも適切なインデントとコメントが必要です。そうでなければ、それは維持不可能な混乱になります。したがって、クエリを1行ずつ理解するのが本当に難しい場合は、変更を拒否し、読みやすくするように作成者に依頼してください。

また、レビュー中にコードを説明するように作者に依頼することは、最悪の事態ではなく、まったく逆です。両方で一緒にコードを調べ、不足しているコメントを一緒に追加できます。

もちろん、これに対する技術的な解決策は、SQLクエリをまったく記述せずに、ほとんどのクエリを自動的に生成するORMのようなものに切り替えることです。しかし、残念ながら、これは実際のシステムの多くにとって現実的な解決策ではありません。システムの大部分を地面から書き直すことを意味する可能性があるためです(そして多くの場合、ORMは独自のクラスの新しい問題を導入します。解決する)。

11
Doc Brown

SQLクエリは複雑で壊れやすいコードなので、自分で確認するのは非常に困難です。私たちはコードベースのかなりの部分をSQLテンプレートとして記述しているので(詳しく説明しませんが、正当な理由により)、コードを作成するための継続的な努力にもかかわらず、レビュープロセスがどのように困難になる可能性があるか(ただし、特に価値がある)を完全に理解しています。品質。

私たちがすでに持っていて少し助けているのは、SQLクエリのコード標準を持つことです。つまり、正規化されたインデントレベル、テーブルの命名規則などです。

しかし、私たちの場合、プロセスを大幅に簡略化したのは、レビュー対象のコードとともに、コードベースにすべての変更済み/新規SQLクエリの単体テストを導入することです。これにより、クエリの実行内容がすばやくわかり、すべてのケースで正しいことを確認できます。テストスイートでこの保証が得られない場合は、コードを拒否する必要があります。

現在、私はSQLクエリを読んで、規則に従っていることとパフォーマンスが適切であることを確認しています。コード修正と堅牢性は、ほとんどの場合、最新のテストスイートでより適切にカバーされます。

3
Arthur Havlicek

あなたの質問を読んだときの私の考えは

  1. コードレビューでチェックする対象を定義していますか?
  2. 増分変更と非増分変更の違いを認識するのはなぜですか?
  3. omg sprocsにビジネスロジックを配置するのをやめる

私にとってコードレビューは、定義されたもののリストをチェックし、テストはありますか、CIパイプラインは正しく構成されていますか、スタイルガイドはフォローされていますか、作業は実際に要求されたことなどを行います。誰でもどのコードでも実行できます。

したがって、SQLの変更にテストが含まれている場合、テストはパスし、テストは十分なEdgeケースをカバーし、コードはチケットが要求したことを実行します...コードレビューはパスしました!

変更の影響を理解するという意味では、呼び出すsprocを変更しますが、コードを見ても理解できない大きな変更であるsprocコードは変更しないでください。

しかし、小さなコードの変更ですべてが壊れる可能性がある場合、欠落しているブラケットまたはnullチェック、整数のオーバーフローなど、またはビジネスロジックの変更は、コード的には正しいように見えますが、1つの方法が必要です。

これがテストの理由です。したがって、コードをたどって、それが正しいかどうかを確認する必要はありません。テストを実行すると、テストは合格または不合格であり、テストはコードが想定することを説明します。 sprocは注文を更新し、selectは世界中のオフィスを返します。コードがそこにあるため、コードが試行していることを理解する必要はありませんAssert.AreEqual(results, listOfOfficesinTheWorld)

私の推測では、sprocsにロジックが多すぎて、ソースコントロールにもない可能性があり、パフォーマンステストを含むテストがないと思います。

データレイヤーからロジックを移動し始め、SQLをシンプルに保ち、データを追加および削除し、多数のユニットテストを含むコードに操作ロジックを含めることをお勧めします。

変更に応じて更新:

私の答えはまだ当てはまると思います。あなたは:

このプロセスを容易にするツールまたは方法論(ポイント2)

ポイント2を自動化することは、テストを書くことと同じです。

データモデルを理解し、

変更前と変更後のデータモデルを比較します。テストがある場合、そのテストへのコミットはインクリメンタル、またはグラウンドアップの変更を表示します

いくつかのテストシステムでクエリを実行して、生成されるものを確認します。

SQLを実行し、結果を予想と比較します。自動化すると、テストがすぐそこにあり、期待される結果の変更を示すコミットが増分またはグループ化の変更を示します。テストの命名とコメントは変更を説明しますEnsureCustomerIsAlwaysRight()SharesCanBeSoldInUnder100ms() etc

あなたのためにテストを書くためのツールを期待することは少し多くを求めています。コードがパターンに従う場合、いくつかの基本的なものをテンプレート化できる可能性があります。しかし、あなたのプロセスの期待される結果はあなたのアプリケーションに特注されるでしょう。常にハードビットを手動で入力する必要があります。

これらのテストが存在しないという理由でレビューに失敗するか、現在の手動テストプロセスの一部として、自分でテストを記述します。そうすれば、少なくとも次回は仕事が楽になります。

これが実用的な答えです。これは大変な作業であり、時間がかかりますが、実装と理解は簡単で、段階的に実装することができ、懸念の分離に向かわなければならず、この一般的な問題を解決する通常の解決策です。

2
Ewan

正直に言うと私はこの種のシステムのファンではありません。あなたがすでに述べたいくつかの理由のために、それらを維持することは非常に困難です。あなたのレビュープロセスは問題ではありません。あなたのアーキテクチャが問題です。

私が見ているように、あなたの選択は2つあります:

  1. 定期的にアーキテクチャレビューを開始して、全員がテーブルとクエリに慣れるようにし、すべてがどのように機能するかを説明する適切なドキュメントとトレーニングを提供する、または

  2. 単純な(CRUD)クエリをフロントエンドまたはミドルウェアアプリケーションにシフトし、ストアドプロシージャを廃止して、主にバッチおよびサーバー操作のために予約します。

1
Robert Harvey