他のテーブルの行数をカウントするために、データベース全体に多くのいわゆるサマリー列があります。たとえば、ユーザーによるコメント数のカウント(ユーザーテーブルの列)。現在、私はこの列を追加のクエリで更新します。
UPDATE user_table SET comments = comments + 1 WHERE user_id='x'
次に、2番目のクエリを実行する代わりに、データベースにTriggers
を導入します。各列に2つのTriggers
:1つのDELETEと1つのINSERT。次に、30〜40にしますTriggers
!!!
ベンチマークは、Triggers
を使用すると、2番目のクエリを実行するよりも約50%高速であることを示しています。どうやら、mysqlの最新機能を使用するのが妥当です。しかし、私がこの質問をするのは、コーディングが曖昧になるため、多くのプログラマーがTriggers
に強く反対しているためです。さらに、Triggers
をたくさん追加すると、Information_Schema
乱雑。
私は正しい軌道に乗っていますか?
トリガーに関する主な問題は次のとおりです。
a)デバッグが難しい
b)トリガーカスケードはデータベースに致命的な影響を与える可能性があります。たとえば、あるテーブルに更新後トリガーがあり、別のテーブルを更新する場合、更新後トリガーもあると、多くの問題が発生します。
いくつかの質問:
a)アプリケーション内で「計算された」要約が使用される頻度はどれくらいですか?
b)「計算された」要約を更新する必要がある頻度はどれくらいですか?
c)必要な主要な「計算」で定期的に更新される「レポート」テーブルを作成することを検討しますか?
あなたが持っているようなサマリーフィールドにはいくつかのオプションがあります。
値を維持するための2回目の更新のオプションは含まれていません。これは、場合によっては見逃されがちで、データが永続的に不正確になる可能性があるためです。これに対する解決策は、不正確な部分を検出して修正するためのバッチ監査/更新です。これは、トリガーを使用するときの初期値設定に必要であり、トリガーがいつでも無効になる場合に備えて、保持しておく必要があります。
すでに述べたように、非正規化された値にトリガーを設定することは望ましくありません。これらは私がトリガーを使用する場合です:
多くの人がトリガーの使用に反対している理由は、2番目のクエリの必要性によってもたらされる制御の欠如と実際に関係しています。
情報を記録するために必要な2番目のクエリは、ストレージエンジン固有の側面を制御する機能がないMySQL環境の影響を受けます。
たとえば、 記録されたテーブルのストレージエンジンに根本的な原因が単純に煮詰められたMySQLイベントのトラブルシューティングを支援しようとしたことがあります 。その問題に関する経験的分析から、トリガー内からInnoDBテーブルに監査証跡情報を記録することを誓約しました。
Triggersの良い点、悪い点、醜い点について以前に投稿しました。
多くのトリガーが必要な場合は、 BLACKHOLEストレージエンジン とMySQLの組み合わせを使用することを強くお勧めしますレプリケーション。
例
ユーザーのコメントを記録するデータベースがあるとします。ユーザーのユーザーIDとコメント列を含むaudit_userというテーブルがあります。
_CREATE DATABASE auditinfo;
USE auditinfo
CREATE TABLE audit_user
(
userid INT NOT NULL,
comments INT NOT NULL DEFAULT 1,
PRIMARY KEY (userid)
) ENGINE=BLACKHOLE;
_
次に、このクエリを実行するトリガーを設定します
_INSERT INTO auditinfo.audit_user (userid) VALUES (myuserid)
ON DUPLICATE KEY UPDATE comments = comments + 1;
_
すばらしいですが、テーブルに何も格納されていないのに、audit_userテーブルがBLACKHOLEストレージエンジンを使用するのはなぜですか?ここでMySQLレプリケーションが機能します。
すべての自動証跡データをキャッチすることを唯一の目的とするスレーブをセットアップします。 _replicate-do-db=auditinfo
_オプションを使用してスレーブをマスターから複製します。次のように、スレーブにauditinfoデータベースとaudit_userテーブルを作成します。
_CREATE DATABASE auditinfo;
USE auditinfo
CREATE TABLE audit_user
(
userid INT NOT NULL,
comments INT NOT NULL DEFAULT 1,
PRIMARY KEY (userid)
) ENGINE=MyISAM;
_
マスターのバイナリログには、コマンドINSERT INTO auditinfo.audit_user (userid) VALUES (myuserid) ON DUPLICATE KEY UPDATE comments = comments + 1;
が記録されています。そのINSERTはスレーブのリレーログに送信されます。レプリケーションにより、INSERtクエリが実行されます。
したがって、問題は残ります。これを設定する利点は何ですか?
厳密に監査情報を記録することになると、マスターはそれを遅くするための重い書き込みI/Oを持ちません。監査を実行するために必要なSQLを記録するだけです。そのSQLは、実際の記録のために別のマシン(スレーブ)に送信されます。当然、この方法で監査を設定すると、マスターはより多くのトリガーを処理できます。 BLACHOLE/MySQLレプリケーションのこの組み合わせを使用しない場合、INSERTを実行するすべてのクエリは速度が低下し、数百のそのようなクエリが表示されるため、DBのパフォーマンスが著しく低下します。