57

環境:

  • PHP/MySQL アプリケーションがあります。
  • 計算の一部は SQL で直接実行されます。例: 過去 24 時間に作成されたすべてのユーザーは、SQL クエリ ( NOW() – 1 日) を介して返されます。

仲間の開発者と私の間で議論が行われており、私は次のようにすべきだと意見を持っています:

A. すべての計算 / コード / ロジックを PHP に保持し、MySQL を情報の「ダム」リポジトリとして扱う

彼の意見:

B. どちらが簡単か、またはどちらが速いかに応じて、組み合わせを行います。http://www.onextrapixel.com/2010/06/23/mysql-has-functions-part-5-php-vs-mysql-performance/

私は保守性の観点から見ています。彼は速度に注目しています (記事で指摘されているように、一部の操作は MySQL の方が高速です)。


@bob-the-destroyer @tekretic @OMG Ponies @mu は短すぎる @Tudor Constantin @tandu @Harley

効率的な WHERE 句は SQL レベルに属することに (そしてまったく明白に) 同意します。ただし、次のような例はどうでしょうか。

  1. SQL で NOW() - 1 日を使用して 24 期間を計算し、過去 24 時間に作成されたすべてのユーザーを選択しますか?
  2. すべてのユーザーの姓と名を大文字で返す
  3. 文字列を連結しますか?
  4. (考え、皆さん?)

SQL ドメインに属する明確な例:

  1. 特定の WHERE 選択
  2. ネストされた SQL ステートメント
  3. 注文・並び替え
  4. DISTINCT アイテムの選択
  5. 行/アイテムのカウント
4

6 に答える 6

49

それぞれのシステムの強みを生かしたいと思います。

集計、結合、およびフィルタリングのロジックは、明らかにデータ レイヤーに属します。これは、ほとんどの DB エンジンが 10 年以上の最適化を行っているためだけでなく、DB と Web サーバーの間で移動するデータを最小限に抑えることができるため、より高速です。

一方、私が使用したほとんどの DB プラットフォームは、個々の値を操作するための機能が非常に貧弱です。日付の書式設定や文字列の操作などは、SQL ではうまくいかないので、PHP でその作業を行う方が適切です。

基本的に、各システムは、その目的に合わせて使用​​してください。

保守性に関しては、何がどこで発生するかの区分が明確である限り、これらをロジックのタイプに分離しても大きな問題は発生せず、メリットを損なうほどではないはずです。私の意見では、コードの明快さと保守性は、すべてのロジックを 1 か所にまとめることよりも一貫性が重要です。


Re: 具体例は・・・

  1. これもあなたが言及しているものではないことは知っていますが、日付はほとんど特殊なケースです。システムによって生成されたすべての日付が、Web サーバーまたはデータベースのいずれかに作成されていることを確認したいと考えています。そうしないと、db サーバーと web サーバーが異なるタイムゾーン用に構成されている場合に、いくつかの潜在的なバグが発生します (私はこれが起こるのを見てきました)。たとえば、DB による挿入時に適用されるcreatedDateデフォルトの列があるとします。次に、 PHP で生成された日付を使用してレコードを挿入する場合(たとえば、過去 1 時間に作成されたレコードを選択すると、期待した結果が得られない可能性があります。どのレイヤーでこれを行うべきかについては、DB を優先します例のように、列のデフォルトを使用できます。getDate()date("Y-m-d", time() - 3600)

  2. ほとんどのアプリでは、これを PHP で行います。名と姓を組み合わせるのは簡単に聞こえますが、敬称、肩書き、ミドルネームのイニシャルが必要な場合もあります。さらに、ほぼ間違いなく、ユーザーの名、姓、および敬称 + 名 + 姓の組み合わせが必要な状況に陥ります。それらを DB 側で連結すると、最終的により多くのデータを移動することになりますが、実際にはかなりマイナーです。

  3. 依存します。上記のように、それらを個別に使用したい場合は、パフォーマンスの観点から、それらを個別に引き出し、必要に応じて連結する方がよいでしょう。とは言っても、扱うデータセットが巨大でない限り、おそらく他の要因 (あなたが言及したように保守性など) がより重要な意味を持ちます。

いくつかの経験則:

  • 増分 ID の生成は DB で行われる必要があります。
  • 個人的には、DB によって適用されるデフォルトが気に入っています。
  • 選択するとき、レコードの数を減らすことはすべて DB で行う必要があります。
  • 通常は、DB 側のデータセットのサイズを小さくすることをお勧めします (上記の文字列の例のように)。
  • そして、あなたが言うように; 順序付け、集計、サブクエリ、結合などは常に DB 側で行う必要があります。
  • また、それらについては話しませんでしたが、トリガーは通常、悪い/必要です。

ここで直面するコアなトレードオフがいくつかあり、そのバランスはアプリケーションによって異なります。

いくつかのことは、常に SQL で実行する必要があります。多くのタスクのいくつかの例外 (日付など) を除外すると、SQL は非常に扱いにくく、邪魔にならない場所にロジックが残る可能性があります。コードベースで特定の列への参照を検索する場合 (たとえば) 、ビューやストアド プロシージャに含まれているものを見落としがちです。

パフォーマンスは常に考慮事項ですが、アプリと特定の例によっては、大きなものではない場合があります。保守性に関するあなたの懸念はおそらく非常に有効であり、私が言及したパフォーマンス上の利点のいくつかは非常にわずかであるため、時期尚早の最適化に注意してください。

また、他のシステムが DB に直接アクセスしている場合 (レポートやインポート/エクスポートなど)、DB にロジックを追加することでメリットが得られます。たとえば、別のデータソースから直接ユーザーをインポートしたい場合、SQL で再利用可能なメール検証関数のようなものが実装されます。

簡単な答え: 場合によります。:)

于 2011-06-23T03:57:26.580 に答える
11

車輪の再発明は好きではありません。また、実行する必要があるタスクに最適なツールを使用することも好きです。

  • WHEREそれ以上処理せずにDBから結果セットを直接取得できる場合は、それを行います-あなたの場合、それは単純な句を使用した単純なクエリです。1,000 万人のユーザーがいて、100 人のユーザーが必要なだけで PHP を使用するとどうなるか想像してみてください。ご想像のとおり、Web サーバーがクラッシュする可能性は非常に高いです。
  • 一度に 2 つ以上のテーブルからデータを取得する必要がある場合も、MySQL はPHP よりもはるかに優れています。
  • レコードをカウントする必要がある場合 - DB は得意です
  • FK 制約よりもアプリケーション レベルの処理を好む傾向がある
  • また、私はストアド プロシージャを避ける傾向があり、そのビジネス ロジックをアプリケーション レベルで実装することを好みます (もちろん、巨大なデータ セットについて話している場合を除きます)。

結論として、提示されたケースではあなたの同僚は正しいと思います

于 2011-06-23T03:55:37.013 に答える
8

ロジックの半分をデータベースに配置し、残りの半分を php に配置すると、6 か月後に変更を加えると、何が起こっているのかを理解するのに 2 倍の時間がかかります。

とはいえ、データベース クエリには、php が必要とする正確なデータを提供するのに十分なロジックが必要です。PHP コードで何千もの mysql レコードをループしている場合は、何か間違ったことをしています。ただし、スケールの反対側では、mysql クエリで if / else ステートメントを実行している場合、何か間違ったことをしている可能性もあります (おそらく、クエリを書き直す必要があるだけです)。

私はストアドプロシージャを避けたいと思います。それらは理論的には優れた概念ですが、通常、php で同じ結果を達成することができ、開発時間ははるかに短縮されます。また、すべてのロジックがどこにあるかを知るという追加の利点もあります。

于 2011-06-23T03:57:27.410 に答える
6

結果セットが増えると、MySQL はより適切に拡張されます。率直に言って、データベースを「ダムデータ」リポジトリとして扱うことはリソースの無駄です...

保守性は慣れによって損なわれる傾向があります。PHP に慣れていない場合、保守性を考慮して PHP を最初に選択することはないでしょう。

于 2011-06-23T03:50:33.253 に答える