web-dev-qa-db-ja.com

MySQLで計算を行うvs PHP

環境:

  • 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. NOW()を使用して24期間を計算する-過去24時間に作成されたすべてのユーザーを選択するSQLの1日
  2. すべてのユーザーの大文字の姓と名を返しますか?
  3. 文字列を連結しますか?
  4. (考え、人々?)

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

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

各システムの長所を活かしてプレイします。

ロジックの集約、結合、フィルタリングは、明らかにデータ層に属します。ほとんどのDBエンジンは、それを行うために10年以上の最適化が行われているだけでなく、DBとWebサーバー間でシフトされるデータを最小限に抑えています。

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

基本的に、各システムは、その目的に合わせて使用​​します。

保守性の観点から、どこで何が起こるかが明確である限り、これらをロジックのタイプに分けることは大きな問題を引き起こさず、確かに利益を逃すには十分ではありません。私の意見では、コードの明快さと保守性は、すべてのロジックを1か所に置くことよりも一貫性を重視しています。


再:特定の例...

  1. これもあなたが参照しているものではないことを知っていますが、日付はほとんど特別な場合です。システムによって生成されたすべての日付がWebサーバー上で作成されることを確認する必要がありますORデータベース。そうしないと、dbサーバーとwebサーバーが異なる設定になっている場合、タイムゾーン(これが起こるのを見ました)たとえば、挿入時に適用されるデフォルトのgetDate()を持つcreatedDate列があると想像してくださいDBによって。レコードを挿入する場合、生成された日付を使用してPHPで(例:date("Y-m-d", time() - 3600)、最後の1時間に作成されたレコードを選択すると、何が得られないかどのレイヤーでこれを行うべきかについては、例のように、列のデフォルトを使用できるようにするためにDBを優先します。

  2. ほとんどのアプリでは、PHPでこれを行います。名と姓を組み合わせるのは、あいさつ文、タイトル、ミドルネームのイニシャルが必要になる場合があるまで、簡単に聞こえます。さらに、ほぼ確実に、ユーザーの名、姓、および敬称+名+姓の組み合わせが必要な状況になります。それらをDB側に連結すると、移動するデータが増えることになりますが、実際には非常に小さなものです。

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

いくつかの経験則:

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

ここで直面するいくつかのコアトレードオフがあり、バランスは実際にアプリケーションに依存します。

いくつかのことは、間違いなく毎回常にSQLで行われるべきです。多くのタスクでいくつかの例外(日付のようなもの)を除外すると、SQLは非常に不格好になり、邪魔にならない場所にロジックを残すことができます。特定の列への参照をコードベースで検索する場合(たとえば)、ビューまたはストアドプロシージャに含まれているものを見逃しやすいis.

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

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

短い答え:それは状況によります。 :)

41
Molomby

車輪の再発明は好きではありません。また、必要なタスクに最適なツールを使用したいので、次のようにします。

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

結論として、私はあなたの同僚が提示されたケースで正しいと言うでしょう

8

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

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

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

7
Harley

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

保守性は親しみによって損なわれる傾向があります。 PHPに精通していない場合、保守性のための最初の選択肢ではないでしょうか?

6
OMG Ponies

SQLでデータをフェッチするのにかかる時間は時間がかかりますが、一度行われた計算は同じになります。データがフェッチされた後、どちらの方法でもそれほど時間はかかりませんが、SQLでスマートに実行すると、大きなデータセットに対してより良い結果が得られます。

MYSQLからデータを取得し、取得したデータに対してPHPで計算を行う場合は、必要な結果を取得して、PHP 、より多くの時間が増加するため。

基本的なポイント:

  1. MYSQLの日付フォーマットは強力で、ほとんどのフォーマットはMysqlで使用できます。非常に具体的な日付形式がある場合は、PHPで実行できます。

  2. 文字列操作は単にSQLを吸い込むだけで、PHPで機能させる方がよいでしょう。必要な大きな文字列操作がない場合は、Mysql SELECTで行うことができます。

  3. 選択する場合、レコード数を減らすものはすべて、PHPではなくSQLで実行する必要があります

  4. データの順序付けは常にMysqlで行う必要があります

  5. DBエンジンはこのために特別に設計されているため、Mysqlでは常に集約を行う必要があります。

  6. サブクエリと結合は常にDB側である必要があります。たくさんのPHPコードを減らします。一度に2つ以上のテーブルからデータを取得する必要がある場合、SQLはPHPよりもはるかに優れています。

  7. レコードをカウントしたい、SQLは素晴らしいです。

3
Somnath Muluk