コードで作業を行うよりもRDBMSに作業をオフロードする方が適切なのはいつですか?


12

さて、私はそれに対処します:私はデータベースよりも優れたコーダーであり、「ベストプラクティス」についての考えは、SQLクエリとSQLクエリで「単純な」計算を行うというテーマのどこにあるのだろうかと思っています。このMySQLの例のようなコード(私はそれを書いていません、私はそれを維持する必要があります!)-これはユーザー名と、最後のイベントの時点でのユーザーの年齢を返します。

SELECT u.username as user, 
       IF ((DAY(max(e.date)) - DAY(u.DOB)) < 0 ,   
       TRUNCATE(((((YEAR(max(e.date))*12)+MONTH(max(e.date)))
       -((YEAR(u.DOB)*12)+MONTH(u.DOB)))-1)/12, 0),  
       TRUNCATE((((YEAR(max(e.date))*12)+MONTH(max(e.date))) -            
       ((YEAR(u.DOB)*12)+MONTH(u.DOB)))/12, 0)) AS age   
FROM users as u
JOIN events as e ON u.id = e.uid
...

コードで「重い」リフティングを行うことに比べて:

クエリ:

SELECT u.username, u.DOB as dob, e.event_date as edate
FROM users as u
JOIN events as e ON u.id = e.uid

コード:

function ageAsOfDate($birth, $aod)
{    //expects dates in mysql Y-m-d format...
     list($by,$bm,$bd) = explode('-',$birth);
     list($ay,$am,$ad) = explode('-',$aod);

     //Insert Calculations here 
     ...
     return $Dy; //Difference in years
}

echo "Hey! ". $row['user'] ." was ". ageAsOfDate($row['dob'], $row['edate']) . " when we last saw him."; 

このような単純なケースでは、(最初​​のようなクエリに変更を加えなければならないときの恐ろしい恐怖感を除いて)大きな違いはないだろうと確信していますが、それは私がそれを明確にすると思います探しています。

ありがとう!


1
これは良い質問です-私は同じ問題に出くわしました。
マイケルK

ここ際の良い例だありません。それを行うにはcalendar.sql(。はい、はい、それは悪い考えで、いや、それは遅いではない、私の怪物である)
greyfade

あなたがたは、神々をひっくり返す...私はその事のためにMD5を賭ける「CthulhuFhtagn」と出てくる
GeminiDomino

回答:


13

パフォーマンス上の理由から、データベースですべてのセットベースの操作を実行します。したがって、集約関数、ソート関数、結合など。

この年齢の計算は、コードで行います。データベースクエリでこのようなことを行う唯一の理由は、クエリを大幅に遅くするのに十分なデータに達する可能性のある選択しない多くの列が必要な場合です。少数の整数値を選択しても、意味のあるパフォーマンスの違いは生じません。そして、中程度のパフォーマンスの違いが生じたとしても、このロジックをアプリケーションコードに保持することに偏りがあります。


同意する。表示目的の値をいじるコードは、アプリコードに含める必要があります。
-TehShrike

4

各ケースは異なります

ロジックは...

  • 他のクライアントに必要ですか?DRY:データベース内
  • さらなる処理に使用されますか?例:年齢の降順でソート:データベース内
  • 地域の設定が必要ですか?dd / mm / yyyyまたはmm / dd / yyyy:クライアント内
  • よく使われますか?何度も何度も計算する理由:データベースで計算列と永続列を使用する

、この場合、私は、データベースに計算され、永続化列を使用する場合があります

さらに悪いことには、データベースにこれを含めることができます。

"Hey! ". u.username." was ". <datecalc>. " when we last saw him."

3

基本的に、CPU使用率とネットワークトラフィックの2つのことを確認する必要があります。データベースがこれをはるかに改善できるため、膨大な応答を生成し、それらをネットワーク経由で転送してからフロントエンドで要約しないでください。

データ操作に関しては、トレードオフです。データベースが、フロントエンドコードと同等のCPUサイクルを同じことを行っている場合(転送されるデータの量がほぼ等しいことを考えると)、どこでもかまいません。次に、プログラミングの専門知識が最も豊富な場所で実行します。多くの場合、注意深い選択で非常に長い道のりを得ることができ、それは非常に便利かもしれません。


1

あなたは1つに言及しました:専門分野。データベースの構造はそれほど集中していないので、ロジック開発の一部をデータベース中心のチームメンバーにオフロードすることにします。理想的ではないかもしれませんが、時間に困っているなら...

データベースハードウェアには他のサーバーよりもかなり多くのリソースがあり、これを変更することはできません。これはこの特定の状況には当てはまらないかもしれませんが、考慮する必要があるかもしれません。

コード外のロジックを必要とする他のアプリケーションがあります。一部のレポート作成ツールでは、WebサービスまたはAPIを利用できない場合があります。ロジックを複製することも、要件が異なると感じる場合もあります。


「データベースハードウェアには他のサーバーよりもかなり多くのリソースがあり、これを変更することはできません。」-ええ?これらの2つのステートメントはどこから来たのですか?
ピーターボートン

Jeffはスタンドアロンのデータベースサーバーについて話しているのではないかと思います。私は、おそらくLA [MP] Pセットアップで主に作業することを指定すべきでした。
ジェミニドミノ

1
LAMPセットアップは、スタンドアロンデータベースサーバーがない理由ではなく、スタンドアロンデータベースサーバーがより多くのリソースを保証したり、これを変更できないことを保証するものでもありません。
ピーターボートン

ふむ よくわかりません。
ジェミニドミノ

同じサーバー内の@Peter Boughton、DB、およびアプリは、インターフェイス接続に要する時間が桁違いに短く、全体的にIOが大きいため、これら2つを一緒に配置する本当の理由があります。
ジェキュー

0

私は常にDBにできるだけ多くの処理を置くことに失敗します。上記の構文は、IMOの非常にクリーンなソリューションになるDB関数を使用して作成することもできます。

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