後で実行するためにSQLステートメントをテーブルに保存するのは悪い考えですか?


21

後で実行するためにSQLステートメントをMySQLテーブルに保存するのは悪い考えですか?SQLステートメントの実行準備が整います。つまり、スワップするパラメーターなどはありませんDELETE FROM users WHERE id=1

私は怠けていると思いますが、SQLステートメントを定期的に実行するかなりの数のcronジョブを必要とするプロジェクトに取り組んでいるので、このアイデアを考えました。


これらのSQLステートメントを1回実行する場合、または同じ一連のステートメントを繰り返し実行する場合は明確にする必要があります。
GrandmasterB 14

10
この質問全体は、基本的なアプローチが間違っている状況の1つのように思えます。しかし、問題空間についてほとんど知らないので、正確に何を伝えるのは難しいです。
エリックロバートソン14

回答:


46

それがあなたが求めているものなら、それは安全です。データのセキュリティと同様にセキュリティに注意している限り。

ただし、車輪を再発明しないでください。ストアドプロシージャはテーブルに格納されたSQLの一部です。そして、彼らは、パラメータ化をサポートします。

また、cronの代わりにMySql Event Schedulerを使用することにより、セキュリティをよりシンプルにし、障害ポイントの数を減らし、ネットワーク通信を減らすことができます。

他のデータベースには、これらと同等の理由があります。この機能が最初に必要なわけではありません。


1
スケジューラの使用に関する+1。スケジューラのアクセスをプロシージャのみに制限する方が、テーブルアクセスよりも優れています。
ジェフ

しかし、UIからこれらのクエリを動的に作成する必要がある場合はどうでしょうか。たとえば、管理ユーザーが複雑なクエリに基づいてWebコンテンツのアクセスルールを動的に設定できるようにする場合。データベースに新しいprocをUIに作成させたくないでしょう。状況によっては、ストアドクエリの方がプロシージャよりも優れていると思います。
DiscipleMichael

32

後で実行するためにデータベースにSQLステートメントを保存する場合は、テーブルに置くよりも優れたオプションがあります。この特定の目的のために提供されている組み込み機能を使用します。ストアドプロシージャに入れます。


2
では、cronジョブは、実行するストアドプロシージャのリストをどこに保存しますか?
ジェフ14

1
これは有用である可能性がstackoverflow.com/questions/6560639/...それはcronのを使用していないのに
MetaFight

私が何を考えていたのか分からない。procのリストはすべて単一のprocから実行できるため、cronジョブは1つだけ実行する必要があります。
ジェフ14

11

いいえ、私はそれは良い考えではないと言うでしょう。

つまり、すべての「実際の」クエリ/更新には、データベースで2回のヒットが必要です。1回は「実際の」クエリ/更新を取得し、もう1回は実行する必要があります。

これは小規模なシステムでは大きな問題ではないかもしれませんが、システムが取得するユーザー/トランザクションが多いほど、規模は小さくなります。

これは、コードにSQLを埋め込む代わりの方法を探しているからだと思いますか?

Mason Wheelerが示唆したように、SQLをストアドプロシージャにカプセル化することは、このアイデアよりもはるかに優れた1つの方法です。


+1、これが@Mason Wheelerのソリューションが正しい理由である主な理由です-彼はそれを強調するのを逃しました。私見では、ここで最も重要なパフォーマンスの問題ではありませんが、DBからSQLステートメントを抽出し、実行のために返送することで事態を複雑にする必要はありません。
ドックブラウン14

SQL文のリストを同じデータベース/サーバーなどに保存する必要があるのはなぜですか?
ジェフ

1
OPは、データベースで2つのヒットを提案するものです。彼はそれをしてはいけないと言います。次に、同じデータベース/サーバーである必要がある理由を尋ねます。誰が言ったの?次に、DBで2ヒットを得る方法を他に尋ねます。これが何をしているのかではなく、実際の質問を述べてみませんか?
ozz 14

1
それは別のデータベースである@JeffOあっても、それはまだ不要な減速で1つのクエリ、どうあるべきかについて2つのデータベースクエリだ
Izkata

1
@Ozz:回答のパフォーマンスの側面を重視しすぎています-ほとんどの実際のシナリオでは、パフォーマンスはほとんど無視できます。ただし、2つのアクション(最初のアクションが「実際の」クエリ/更新を取得し、2番目のアクションを実行する)が必要なため、必要以上に複雑になります。
ドックブラウン14

4

申し訳ありませんが、それは良い考えではありません。

問題のテーブルが変更される場合を考えます。あなたの言うのid列が名前に変更されますNEW_ID

変更自体だけでなく、古いヴィンテージのデータベース用に記述されたバージョンのコードがあり、実行できなくなる可能性があります。確かに、コード表をチェックインすることを知っているかもしれませんが、他の誰かにとってはすぐにはわかりません。

私が説明したような変更については、通常、スタンドアロンSQLファイル、ストアドプロシージャ、トリガー、クライアントコード(VB、C#、C ++など)のインラインSQLを調べますが、最後に見てみたいと思いますデータベーステーブルにあります。多分私は今!:)


2

SQLをテーブルに保存する正当な理由があります。職場で作業するソフトウェアには、ドキュメントを生成するシステムが含まれており、ドキュメントにはデータベース内のデータを使用したかなり複雑な計算を含める必要があります。ドキュメントは頻繁に更新され、多くの場合、必要なデータと実行する必要のある計算の点で大きく異なります。基本的に、SQLはこれらの計算を実行するためのスクリプト言語として使用されており、そのSQLはこれらのドキュメントの他の情報も格納するテーブルに格納されています。これらのドキュメントを管理している人々はプログラマやDBAではありませんが、データベーススキーマに精通しており、SQLに精通しています。そのSQLコードをストアドプロシージャの形式で維持することは、彼らにとって大きなオーバーヘッドになります。

あなたが説明したことについて-「... SQLステートメントを定期的に実行する非常に多くのcronジョブを必要とするプロジェクト」-他の答えは、DBMSに対してストアプロシージャまたは同等のものを使用したことを示唆するのにおそらく正しいでしょう。再使用。

SQLをテーブルに格納するのがストアドプロシージャに格納するのが賢明かどうかを判断するための適切な基準は、そのSQLを誰が管理するかを決定することです。ユーザーがそのSQLを維持する場合、つまり、必要なときにいつでもそれを記述して変更する場合、そのSQLをテーブルに格納することは完全に適切であり、実際に最適です。開発者がそのSQLを維持する場合、(希望する場合は自動化された)ビルドおよびデプロイメント手順によって更新できる形式で保存する必要があります。たとえば、データベース自体のストアドプロシージャのようなオブジェクトとして保存します。


1
答えてくれてありがとう。結局、MySQLイベントを使用して、実行するクエリをスケジュールしました。かなり少数の人々が「基本的なアプローチは間違っている」と思っていました:)特定のユーザーアクションから15分後にいくつかのSQLステートメントを実行するだけでよい場合。
修正されたRustom 14

2
@AmgadSuliman –特にSEサイトでは、誰に対しても慈善活動を行うことが重要です。強い意見を持つのは良いことですが、私たちが楽しんでいるパターンに対して過剰に一致させるの簡単すぎます。しかし、これらのサイトで他人に慈善をすることの一部は、十分なコンテキストを提供することです。多すぎると実際の質問がわかりにくくなる可能性がありますが、一般的にはその後の編集でかなり簡単に修正できます。
ケニーエビット14

1

簡単な方法は、クエリを保持するために.iniまたは他の構成フレーバーファイルを使用することです。この方法で、1か所でクエリを保持し、データベースにアクセスせずに何回でも変更できます。また、ある時点でパラメータを使用したり、クエリに条件を追加したりする必要がある場合があります(コード内の特定のケースに合わせて、より複雑なものを追加します)。

もちろん、データベースレベル(テーブル内、またはストアドプロシージャとして)で保持することもできますが、私と同じくらい怠けている場合は、-)パフォーマンス、.iniファイル、およびPHP それを読むためのparse_iniメソッドが大好きです(別のプログラミング言語を使用する場合は、同様のアプローチを自分で考えます)!通常、アプリケーションのブートローダーでこのファイルを読み取り、静的オブジェクト(キャッシュ層が最上位にある可能性があります)に保存して、非常に多くの個別のクエリについて話している場合に速度を上げます。


1

たとえば、営業時間外に実行する一連の操作をキューに入れている場合など、SQLステートメントが1回だけ必要な場合は、はい、それらをテーブルに入れると問題なく機能します。

指定した間隔で同じSQLステートメントを実行する必要がある場合は、他の人が言及したストアドプロシージャルートの方が適している可能性があります。

とは言うものの、あなたが尋ねているのはかなり珍しいことであり、他の問題の兆候かもしれません。たとえば、データベースからユーザーを削除するのを待っている場合、実際のSQLステートメントを記録するよりも、アプリケーションコードを介して操作を実行するスケジュールされたスクリプトを呼び出す方が適切な場合があります。これにより、SQLとコードが同期しなくなることはありません。

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