web-dev-qa-db-ja.com

MySQLトリガーまたはトランザクションを使用していますか?

MySQLトリガーまたはWebサイトでのトランザクションの使用について、あなたの意見を伺いたいと思います。

実際、履歴paymentテーブルに-UserId | OperationId | Comment | Credits | Sign (debit or credit)があります。したがって、各支払い操作がこのテーブルに挿入されます。

ただし、ユーザーがアクションを実行するたびに、ユーザーの合計クレジット額を計算するのに時間がかかります。したがって、各ユーザーの合計クレジット額をユーザーprofileテーブルに保持することをお勧めします。

ここに問題があります。 profileテーブルの合計クレジット額がpayment履歴テーブルの操作と常に同期していることをどのように確認できますか?

私は2つの方法を使用すると思いました:

  • MySQLトリガーまたは
  • ソースコードでコーディングされたトランザクション

どちらがより信頼できますか?大規模なデータベース(100.000ユーザー以上)がある場合はどうなりますか?

これを行うための提案はありますか?

BD MySQLエンジンはInnoDBです。

8
Ek Kosmos

間違いなく、私はトリガーを除外し、厳密にトランザクションを維持します。

トリガーは本来、ストアドプロシージャです。アクションはロールバックが事実上困難です 。基礎となるすべてのテーブルがInnoDBである場合でも、比例した量の共有行ロックが発生し、排他的行ロックによる煩わしい断続性が生じます。トリガーがINSERTおよびUPDATEを含むテーブルを操作して、トリガーの各呼び出し内で強力なMVCCを実行するために停滞している場合は、このような状況になります。

これを 適切なデータ検証プロトコルがMySQLのストアドプロシージャ言語に実装されていない という事実と組み合わせます。 ストアドプロシージャ言語がトランザクション環境を処理できるのであれば、ビジネスインテリジェンスはデータベースに含まれていても問題ありません 。 MySQL DBAとして、正直に言って、そのようなことはMySQLには当てはまりません。 Oracle(PL/SQL)、PostgreSQL(PL/pgSQL)、およびSQL Server(T-SQL)には、MySQLを介してこのエッジがあります。

トランザクションに関しては、MySQLはその主要なACID準拠のストレージエンジン(MySQL 5.5のDeafultストレージエンジン)としてInnoDBを持っています。優れたクラッシュリカバリがあり、ACIDコンプライアンスプロトコルに従います。

毎回トリガーよりもトランスアクチオンを選択します

8
RolandoMySQLDBA

Rolandoの評価に同意します。ビジネスロジックはアプリケーションに常駐し、トランザクションでデータベースを変更する必要があります。

もちろん、10万人のユーザーへのスケーリングは、アプリケーションとそれが生成するデータベーストラフィックに依存します。 MySQLでトランザクションの書き込み負荷が高い場合、許容できるアプリケーションの応答を維持するために、データセットのシャーディングや複製の負担にすぐに直面する可能性があります。

ただし、MySQLのシャーディングに代わるものがあります。それらの1つはClustrix(私の雇用主)であり、これは並列スケーラブルな高性能シングルインスタンスSQLデータベースシステムです。クラスター化されたデータベースシステムであり、単一のMySQLサーバーとして表示されます。このスレッドで説明されているデータベースをシームレスにClustrixの単一インスタンスで100,000人のユーザーにスケーリングする場合、シャーディングや追加のアプリケーションロジックは必要ありません。

3
blbryant

ローランドからの良い答え。

さらに、トリガーはロジックに使用しないでください。相互に関連するトリガーが後でいくつかあるため、混乱が生じやすくなります。ストアドプロシージャまたはクライアントサイドプロシージャ内の適切な一連の命令は、データベース内の一連の隠されたロジックよりも明確にビジネスロジックを通過できます。また、トリガー元のテーブルに関してトリガーにも制限があります。そのため、ロジックを2つの異なる場所に分割することがあります。

さらに、これらの計算がビジネスロジックサーバーでどの時点で発生するかを最適化する方法が見つかるかもしれませんが、トリガーは毎回トリガーされます。トリガーをオフにしてテーブルを更新し、トリガーを再度有効にすることがわかります。これは、トリガーロジックをthatコードに含める必要があることも意味します。

さらに、コードのビジネスロジック部分にすべてのロジックを含める必要はありません。ストアドプロシージャを使用して、テーブルの整合性を強化することもできます。これにより、トランザクションが開始され、複数の更新が行われ、何かが失敗した場合に適切にロールバックすることができます。このようにして、たとえば、データベースを見ている人は、注文を挿入するためのロジックを見ることができます。これは今日の世界ではそれほど重要ではありません。Webサービスがdbへの単一のアクセスインターフェイスになる可能性があるためです。しかし、複数の実行可能ファイルがDBにアクセスできる場合、これは巨大になる可能性があります。

さらに、とにかくトランザクションを使用するつもりです-トリガーなしでトリガーを実行するつもりはありません...したがって、トランザクションの開始方法を知っておくとよいでしょう。いくつかのことを行います。トランザクションを終了します。コードにこのパターンが見られる場合、それを使用するもう1つのコードは、認知負荷が軽くなります。トリガーがあることを覚えている場合は、トリガーによって影響を受けるトランザクションについて、特にトリガーを持っている他のテーブルがプルされている場合は、別の方法で考える必要があります。

基本的に、定期的にスケジュールされたcronジョブ(またはデータベースエージェントジョブ)と適切なストアドプロシージャの間で、必要なものの99%を達成できます。 1%;プロジェクトを再考します。

1
Gerard ONeill