MySQL データベース開発仕様 [推奨]

MySQL データベース開発仕様 [推奨]

最近、問題のある新しい SQL が本番データベースに入力される数を最小限に抑えるために、開発仕様を整理しながら、最適化のために SQL をオンラインでキャプチャしています。本日は社内開発の研修もありました。PPTはここではアップしませんが、SQLの運用事例が10件ほどありました。仕様のほとんどは普遍的なため、Qunar と Ganji の仕様も参考にしました。ただし、この記事の執筆過程では、各仕様は作業で参考にした負の例に基づいています。時間が許せば、その一部を取り上げてその原理を分析したり、事例を挙げて説明したりするつもりです。

1. 命名規則

1. データベース名、テーブル名、フィールド名には小文字を使用し、アンダースコアで区切る必要があります。

(1)MySQLにはlower_case_table_names=1という設定パラメータがあり、これはテーブル名が小文字で保存され、大文字と小文字が区別されないことを意味します。 0 の場合、ライブラリ テーブル名は大文字と小文字を区別してそのまま保存されます。2 の場合、ライブラリ テーブル名はそのまま保存されますが、小文字で比較されます。

(2)大文字と小文字が混在すると、abc、Abc、ABCなどの複数の表が共存することがあり、混乱を招きやすい。

(3)フィールド名は大文字と小文字が区別されて表示されますが、実際の使用では大文字と小文字は区別されません。つまり、同じ名前で大文字と小文字が異なる2つのフィールドを作成することはできません。

(4)統一規格のため、ライブラリ名、テーブル名、フィールド名には小文字を使用する。

2. データベース名はdで始まり、テーブル名はtで始まり、フィールド名はf_で始まります。

(1)例えば、テーブルt_crm_relationでは、中央のcrmはビジネスモジュール名を表す。

(2)ビューはview_で始まり、イベントはevent_で始まり、トリガーはtrig_で始まり、ストアドプロシージャはproc_で始まり、関数はfunc_で始まります。

(3)共通インデックスはidx_col1_col2、ユニークインデックスはuk_col1_col2(f_public部分は削除可能)と命名される。例えば、idx_companyid_corpid_contacttime(f_company_id,f_corp_id,f_contact_time)

3. ライブラリ名、テーブル名、フィールド名は 32 文字を超えてはなりません。

ライブラリ名、テーブル名、フィールド名は最大64文字をサポートしますが、統一性、識別の容易さ、転送量の削減のため、32文字以下しか使用できません。

4. 一時データベースとテーブルの名前には、tmp と date の接尾辞を付ける必要があります。

たとえば、t_crm_relation_tmp0425 など。バックアップ テーブルも同様で、形式は _bak20160425 です。

5. 日付と時刻で区切られた表は、_YYYY[MM][DD]の形式に準拠する必要があります。

これは、将来的に t_crm_ec_record_201403 などの個別のテーブルが作成される可能性に備えるためのものですが、t_crm_contact_at201506 はこの仕様に違反しています。
時間特性を持たないものは、直接 t_tbname_001 として名前が付けられます。

2. データベーステーブルの基本仕様

1. Innodbストレージエンジンを使用する

バージョン 5.5 以降、MySQL のデフォルトのストレージ エンジンは InnoDB です。バージョン 5.7 以降、システム テーブルでは MyISAM は廃止されています。

2. 表の文字セットはUTF8を統一的に使用

(1)UTF8文字セットは、中国語の文字を格納するのに3バイト、英語の文字を格納するのに1バイトを占有する。

(2)校正文字セットはデフォルトのutf8_general_ciを使用する。

(3)接続先のクライアントもutf8を使用します。接続を確立するときにcharsetまたはSET NAMES UTF8;を指定します。 (長い間プロジェクトでlatin1を使用していた人にとっては、それを保存する方法はありません)

(4)EMOJなどの絵文字を保存する必要がある場合は、UTF8MB4文字セットの使用を申請できます。

3. すべてのテーブルにコメントを追加する

(1)フィールドにコメントを追加してみる

(2)ステータスタイプは、「0-オフライン、1-オンライン」のように、主な値の意味を指定する必要があります。

4. 1つのテーブル内のフィールド数を制御する

(1)1つのテーブル内のフィールド数の上限は30程度です。フィールド数が多い場合は、テーブルを垂直に分割することを検討してください。まず、ホットデータとコールドデータを分離します。次に、大きなフィールドを分離します。3番目に、条件と戻り値によく一緒に使用される列を分離しないでください。

(2)テーブルフィールドは簡潔かつ正確に制御されるため、IO効率が向上し、より多くの有効なデータがメモリにキャッシュされ、応答速度と同時実行能力が向上し、その後のテーブル変更操作も高速化されます。

5. すべてのテーブルは主キーを明示的に指定する必要がある

(1)主キーは可能な限り自動増分する必要があります。InnoDBテーブルは実際にはインデックス構成テーブルです。シーケンシャルストレージはアクセス効率を向上させ、ディスクスペースを最大限に活用できます。また、最適化のために自己結合を必要とする複雑なクエリにも必要です。

(2)グローバルに一意な主キーが必要な場合は、外部チケットサーバーを使用する(構築中)

(3)主キーまたは一意のインデックスがない場合、更新/削除はすべてのフィールドを通じて操作の行を検索します。これは、各行の完全なテーブルスキャンに相当します。

(4)場合によっては、共同一意主キーを使用できるが、DBAとの協議が必要である。

6. 外部キー参照は強制されない

2 つのテーブルのフィールドに明確な外部キー参照関係がある場合でも、新しいレコードは主キー テーブルに対してチェックされ、パフォーマンスに影響するため、FOREIGN KEY は使用されません。

7. ストアドプロシージャとビューを適切に使用し、トリガーとイベントの使用を禁止する

(1)ストアドプロシージャはビジネスサイドのコードを簡素化でき、従来の企業では複雑なロジックを記述する際に使用できますが、インターネット企業では変更が非常に頻繁に行われます。データベースとテーブルが別々にある場合、ストアドプロシージャをアップグレードするのは非常に面倒です。また、ログを記録しないため、パフォーマンスの問題をデバッグするのに不便です。手順を使用する場合は、実行が失敗した場合に何が起こるかを必ず考慮してください。

(2)ある程度、ビューの使用はコード内のSQLの複雑さを軽減するためにもありますが、ビューの汎用性によりパフォーマンスが犠牲になる場合もあります(たとえば、不要なフィールドを返すなど)。

(3) 同じことがトリガーにも当てはまりますが、トリガーはデータの一貫性を制限するために使用すべきではありません。MySQL は「行ベースのトリガー」のみをサポートしています。つまり、トリガーは常に SQL ステートメント全体ではなくレコードを対象とします。変更されるデータセットが非常に大きい場合、効率は非常に低くなります。作業内容を SQL ステートメントの背後に隠すと、問題が発生した場合に悲惨な結果になるだけでなく、迅速に分析して特定することが難しくなります。さらに、ddl が必要な場合、pt-osc ツールは使用できません。トランザクション実行に入れます。

(4) イベントも怠惰の一種です。スケジュールされたタスクの失敗によって業務に影響が出たのに、MySQL が失敗の警告を出せなかったというケースが何度かありました。専用のジョブ スケジューラ プラットフォームを確立します。

a. 1つのテーブル内のデータ量は5000w以内に制限されます

b. プレーンテキストのパスワードはデータベースに保存できません

3. フィールド仕様

1. char、varchar、text などの文字列型の定義。

(1)固定長の列の場合、頻繁に更新される場合にはcharが適しています。

(2)varcharは可変長の文字列を格納できますが、小さすぎたり大きすぎたりすることはできません。 UTF8は最大21844の中国語文字または65532の英語文字を保存できます。

(3)varbinary(M)はバイナリ文字列を格納します。文字ではなくバイトを格納するため、文字セットの概念はありません。Mの長さは0〜255(バイト)です。パスワードの保存を除き、並べ替えや比較の際に大文字と小文字を区別するタイプにのみ使用されます。

(4) TEXT型は、可変長を格納し、最大制限が2^16である点でVARCHARに似ています。ただし、20バイト以降の内容はデータページ外に格納されます(row_format=dynamic)。使用するには、もう1つのアドレス指定が必要であり、デフォルト値はありません。

一般的に、平均容量が大きく、他のフィールドほど頻繁に操作されない値を格納するために使用されます。

インターネット上の記事の中には、text と blob の使用を避けるべきだと書かれているものもあります。varchar のみを使用すると、行オーバーフローが発生する可能性があることに注意してください。影響は似ていますが、各行が占有するバイト数が多すぎるため、buffer_pool がキャッシュできるデータ行とページの数が減少します。さらに、テキストと BLOB にはインデックスが作成されることはありません。代わりに、Sphinx などのサードパーティの全文検索エンジンが使用されます。実際に (プレフィックス) インデックスが作成されると、パフォーマンスに影響します。すべては具体的なシナリオに依存します。

また、可能であればテキスト/BLOBを別のテーブルに分割します

(5) BLOBはvarbinaryの拡張バージョンです。コンテンツはバイナリ文字列で保存され、文字セットはなく、大文字と小文字が区別されます。よく言われるが使われないシナリオがあります。それは、データベースに画像を保存しないことです。

2. int、tinyint、decimal などの数値型の定義。

(1)enumとbooleanの代わりにtinyintを使用する
ENUM 型で列挙値を変更または追加する必要がある場合、コストのかかるオンライン DDL が必要になります。ENUM 列の値に数値型が含まれている場合、デフォルト値に関する混乱が生じる可能性があります。
Tinyint は 1 バイトを使用し、通常はステータス、タイプ、フラグの列に使用されます。

(2)負でない値を格納する場合はUNSIGNEDを使用することをお勧めします。unsignedを使用しない場合と比較して、使用可能な値の範囲が2倍になります。

(3) intは固定の4バイトの記憶域を使用します。int(11)とint(4)の違いは表示幅のみです。

(4) 正確な浮動小数点数を保存するには、float/double ではなく Decimal を使用します。通貨や金額などの型には、decimal(9,2) などの 10 進数を使用します。デフォルトでは、float の精度は 6 桁までしか有効になりません。

3.タイムスタンプと日時の選択

(1) datetime型とtimestamp型はそれぞれ8バイトの記憶領域を占め、timestamp型は4バイトの記憶領域を占めます。そのため、表現できる時間の範囲が異なります。前者は 1000-01-01 00:00:00 から 9999-12-31 23:59:59 まで、後者は 1970-01-01 08:00:01 から 2038-01-19 11:14:07 までの範囲です。したがって、TIMESTAMP でサポートされる範囲は DATATIME よりも狭くなります。

(2)timestampは行を挿入/更新するときに時間フィールドを自動的に更新できます(f_set_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPなど)が、テーブルにはそのような定義が1つしか設定できません。

(3)タイムスタンプの表示はタイムゾーンに関連しており、常にUTCミリ秒で内部的に保存されます。厳格なモード制限も適用される

(4)タイムスタンプが推奨されますが、日付時刻も許容されます。

(5)where条件の時間列に時間関数を使用しない

4. すべてのフィールドをNOT NULLとして定義することをお勧めします。

(1)インデックスフィールドの場合は、null以外として定義する必要があります。 NULL 値は座標統計に影響し、オプティマイザのインデックスの選択に影響を与える可能性があるためです。

(2)挿入時に値が必ず存在することを保証できない場合は、定義時に「default」または「0」を使用してください。

5. 同じ意味を持つフィールド定義は同じでなければならない

たとえば、異なるテーブルに f_user_id フィールドがある場合、それらのタイプとフィールドの長さは同じになるように設計する必要があります。

4. インデックスの指定

1. インデックスの使用状況を確認するには、まず新しい選択、更新、削除操作を説明する必要があります。

余分な列が表示されないようにしてください。ファイルの並べ替えや一時使用を使用し、行数が 1,000 を超える場合はオンラインにするときに注意してください。
説明する

(1)タイプ:ALL、インデックス、範囲、ref、eq_ref、const、システム、NULL(左から右へ、パフォーマンスは最悪から最高へ)

(2) possible_keys: MySQL がテーブル内のレコードを検索するために使用できるインデックスを示します。クエリに関係するフィールドにインデックスがある場合、そのインデックスはリストされますが、クエリでは使用されない可能性があります。

(3)キー:MySQLが実際に使用するキー(インデックス)を示す
インデックスが選択されなかった場合、キーは NULL になります。 MySQL で possible_keys 列のインデックスを強制的に使用または無視するには、クエリで FORCE INDEX、USE INDEX、または IGNORE INDEX を使用します。

(4)ref:インデックス列の値を見つけるために使用される列または定数を示します。

(5)行数:テーブル統計とインデックス選択に基づいて、必要なレコードを見つけるために必要な行数の推定値。

(6)追加

a.一時テーブルの使用: MySQL が結果セットを保存するために一時テーブルを使用する必要があることを示します。これは、クエリの並べ替えやグループ化でよく使用されます。
b. ファイルソートの使用: MySQL のインデックスを使用して完了できないソート操作は、「ファイルソート」と呼ばれます。

1. インデックス数の制限

(1) インデックスは諸刃の剣です。メンテナンスの負担が増し、IO 圧力が高まり、インデックスが占有するスペースが増加します。

(2)1つのテーブル内のインデックスの数は5以内に抑えるか、テーブルフィールド数の20%を超えないようにする。クエリ要件に応じて、単一テーブル内の複数のフィールドで個別のインデックスを使用する必要がある場合は、DBA による評価が必要です。

2. 冗長なインデックスを避ける

(1.) InnoDB テーブルはインデックス構成テーブルです。主キーはデータと一緒に配置されるクラスター化インデックスです。通常のインデックスは最終的に主キーのアドレスを指すため、主キーを最後の列にすることは冗長です。 f_crm_id を主キーとして使用する場合、結合インデックス (f_user_id、f_crm_id) 上の f_crm_id は完全に冗長になります。

(2) (a,b,c)、(a,b)、後者は冗長なインデックスです。プレフィックスインデックスを使用すると、高速化とメンテナンスの負担軽減を実現できます。

3. 特別な要件がない場合は、自動増分IDを主キーとして使用します。

(1.) 主キーはクラスター化インデックスであり、順番に書き込まれます。結合された一意のインデックスを主キーとして使用すると、ランダムに書き込まれるため、書き込みが少なく読み取りが多いテーブルに適しています。

(2)主キーの更新は許可されない

4. 選択性の高い列にインデックスを構築する

(1)性別やタイプなどのカーディナリティの低い列にはインデックスを作成しないでください。ただし、idx_feedbackid_type (f_feedback_id、f_type) というケースが 1 つあり、f_type=1 が比較に頻繁に使用され、行の 90% をフィルター処理できる場合は、この複合インデックスを作成する価値があります。場合によっては、同じクエリ ステートメントでも条件値が異なるために異なるインデックスが使用され、同じ原則が適用されます。

(2)インデックス選択度の計算方法(カーディナリティ÷データ行数)

選択性 = カーディナリティ / 合計行数 = select count(distinct col1)/count(*) from tbname。1 に近いほど、col1 のインデックスを使用したフィルタリング効果は高くなります。

(3)インデックスでスキャンされた行数が30%を超えると、フルテーブルスキャンに切り替える

5. 左端接頭辞原則

(1) MySQL がジョイントインデックスを使用する場合、左から右に一致します。切断または範囲クエリに遭遇すると、後続のインデックス列は使用できません。たとえば、インデックス idx_c1_c2_c3 (c1,c2,c3) は、3 つのインデックス (c1)、(c1,c2)、(c1,c2,c3) を作成することに相当します。このインデックスは、上記 3 つの条件を含むフィールド比較に使用できます。ただし、たとえば c1=a かつ c3=c の場合、列 c1 のインデックスのみ使用できます。c2=b かつ c3=c のような場合は、このインデックスはまったく使用できません。

(2)範囲クエリ(>、<、between、like)に遭遇した場合もインデックスマッチングは停止されます。例えば、c1=aかつc2>2かつc3=cの場合、列c1とc2の比較のみインデックスを使用でき、配列(c1、c2、c3)のインデックスはすべて使用できます。

(3) where条件内のフィールドの順序はインデックスの順序とは関係ありません。MySQLオプティマイザが自動的に順序を調整します。

6. プレフィックスインデックス

(1) 30文字を超える長さの列にインデックスを作成する場合は、プレフィックスインデックスの使用を検討してください。たとえば、idx_cs_guid2 (f_cs_guid(26))は、最初の26文字をインデックスとして使用することを意味します。これにより、検索効率が向上し、スペースを節約できます。

(2)プレフィックスインデックスにも欠点があります。列に対してORDER BYやGROUP BYを実行するときに使用できず、カバーリングインデックスとして使用できません。

(3)varbinaryやblobなどのバイナリストレージ列にプレフィックスインデックスを作成する場合は、文字セットを考慮する必要があります。括弧内のバイト数は

7. IOを削減するためのカバーインデックスの合理的な使用

INNODB ストレージ エンジンでは、セカンダリ インデックス (非主キー インデックス、補助インデックス、セカンダリ インデックスとも呼ばれる) は行アドレスを直接格納するのではなく、主キー値を格納します。
ユーザーがセカンダリ インデックスに含まれていないデータ列をクエリする必要がある場合、ユーザーは最初にセカンダリ インデックスを通じてプライマリ キー値を見つけ、次にプライマリ キーを通じて他のデータ列をクエリする必要があるため、クエリを 2 回実行する必要があります。カバーリング インデックスは、必要なすべてのデータ列を 1 つのインデックスで取得できるため、テーブル内での 2 次検索が回避され、IO が節約され、効率が向上します。

たとえば、SELECT email, uid FROM user_email WHERE uid=xx です。uid が主キーでない場合は、index(uid, email) としてインデックスを追加してパフォーマンスを向上させることができます。

8. 頻繁に更新される列にインデックスを作成しないようにする

ON UPDATE CURRENT_STAMPが定義された列にインデックスを作成しないと、メンテナンスコストが高くなりすぎます(幸いなことに、MySQLにはインデックスの挿入をマージする挿入バッファがあります)

5. SQL設計

1. すべてのフィールドを読み取るためにSELECT *を直接使用しないでください

すべてのフィールドが必要な場合でも、ネットワーク帯域幅の消費が削減され、カバーインデックスを効果的に使用でき、テーブル構造の変更がプログラムにほとんど影響を与えません。

2. 返される結果が1つだけであることが確実な場合は、limit 1を使用します。

データが正しいことと結果セットの数を決定できることを前提として、limit をより頻繁に使用して、できるだけ早く結果を返します。

3. 暗黙的な型変換には注意する

(1)変換ルール

a. 2 つのパラメータのうち少なくとも 1 つが NULL の場合、比較の結果も NULL になります。例外として、<=> を使用して 2 つの NULL を比較すると、1 が返されます。どちらの場合も、型変換は必要ありません。

b. 両方のパラメータは文字列であり、型変換なしで文字列として比較されます。

c. 両方のパラメータは整数なので、型変換なしで整数として比較されます。

d. 16 進数値を非数字と比較する場合、バイナリ文字列として扱われます。

e. 一方のパラメータがTIMESTAMPまたはDATETIMEで、もう一方のパラメータが定数の場合、定数はタイムスタンプに変換されます。

f. 1 つのパラメータが 10 進数型の場合、他のパラメータが 10 進数または整数であれば、整数は比較のために 10 進数に変換されます。他のパラメータが浮動小数点数の場合、10 進数は比較のために浮動小数点数に変換されます。

g. それ以外の場合、比較の前に両方の引数が浮動小数点数に変換されます。

(2)インデックスが文字列型に基づいて構築され、このフィールドがint型の値と比較される場合、セクションgに準拠する。たとえば、f_phone の型が varchar として定義されているが、where で f_phone in (098890) が使用されている場合、両方のパラメータは浮動小数点型として扱われます。この暗黙的な変換の発生は最悪ではありません。最悪なのは、文字列が float に変換された後、MySQL がインデックスを使用できなくなり、パフォーマンスの問題が発生することです。 f_user_id = '1234567' の場合、節 b の要件を満たし、数値は文字列として直接比較されます。

4. where条件列に関数を使用しない

(1)これにより、lower(email), f_qq % 4などのインデックスが無効になります。右辺の定数で計算できる

(2)返される結果セットがそれほど大きくない場合は、返された列に対して関数を使用してプログラム開発を簡素化することができます。

5. あいまい一致のように使用し、%を先頭に置かない

これにより、インデックスが失敗します。この検索要件がある場合は、sphinx全文検索などの他のソリューションを検討してください。

6. 複雑な SQL の場合は、必ず既存のインデックス設計を参照して、最初に説明してください。

(1)コード処理の複雑さを言い訳にせず、SQLを単純に分割する。

(2)例えば、OR条件f_phone='10000'またはf_mobile='10000'では、両方のフィールドにインデックスがありますが、そのうちの1つしか使用できません。 2 つの SQL ステートメントに分割することも、すべてを結合することもできます。

(3)最初に説明する利点は、インデックスを活用するためにさらにクエリ制限を追加できることです。

7. 結合を使用する場合は、where条件で同じテーブルのインデックスを使用するようにしてください。

(1) たとえば、t1、t2からt1.a、t2.b *を選択し、t1.a=t2.aかつt1.b=123かつt2.c=4とします。フィールドt1.cとt2.cが同じ場合、t1のインデックス(b、c)はbのみを使用します。このとき、where条件のt2.c=4をt1.c=4に変更すると、完全なインデックスが使用できるようになります。

(2)この状況は、フィールド設計が冗長(反正規化)である場合に発生する可能性がある。

(3)内部結合と左結合を正しく選択する

8. サブクエリを減らして結合を増やす

5.6 より前のバージョンでは、サブクエリを最初に計算してから外部クエリを計算する Oracle とは異なり、サブクエリは非常に非効率的です。バージョン5.6の最適化が開始されました

9. union allの使用を検討し、unionの使用頻度を減らし、重複排除に注意する

(1) union allは重複を削除しませんが、ソート操作を必要としないため、unionよりも高速です。重複を削除する必要がない場合は、union allが推奨されます。

(2)UNIONの結果にlimitが使用されている場合、戻り値が多数存在する可能性があるときは、2つのサブSQL文のそれぞれにlimitを追加します。まだ注文がある場合は、DBA にお問い合わせください。

10. INの内容は200語を超えてはなりません。

500 を超える値にはバッチ モードを使用します。そうしないと、1 つの SQL が常に 1 つの CPU しか占有できないため、1 回の実行がデータベースの同時実行性に影響し、マスター スレーブ レプリケーションの遅延が発生する可能性があります。

11. 大きなことにはノーと言う

たとえば、1 つのトランザクションで複数の選択と更新が実行され、それが高頻度トランザクションである場合、トランザクションによって保持されているロックやその他のリソースは、トランザクションがロールバック/コミットされたときにのみ解放できるため、MySQL の同時実行機能に重大な影響を及ぼします。しかし同時に、データ書き込みの一貫性も考慮する必要があります。

12. is nullやis not nullなどの比較は避ける

13.順序付け .. 制限

このタイプのクエリはインデックスによってさらに最適化されますが、フィールドによる順序付けが重要です。たとえば、主キー id と f_time が両方とも昇順になっている場合は、f_time ではなく id による順序付けを検討できます。

14.c1 < c2 による順序

上記との違いは、order byの前に範囲クエリがある点です。これまでの内容からわかるように、(c1, c2)のようなインデックスは必要なく、(c2, c1)インデックスが使用できます。 join メソッドとして書き直すこともできます。

15. ページングの最適化

ページング効率を向上させるには、適切なページング方法を使用することをお勧めします。大きなページの場合は、ジャンプ ページングを使用しないでください。

次のようなページングステートメントがある場合:

table1 から選択し、 ftime で DESC LIMIT 10000,10 で並べ替えます。

MySQL は先読み戦略を使用するため、このページング方法では大量の IO が発生します。

推奨されるページング方法:

table1 から選択 WHERE ftime < last_time ORDER BY ftime DESC LIMIT 10

つまり、前のページングの境界値を渡す

SELECT * FROM table as t1 inner JOIN (SELECT id FROM table ORDER BY time LIMIT 10000,10) as t2 ON t1.id=t2.id

16. 数える

(1) まず、count()、count(1)、count(col1) には違いがあります。count() は結果セット全体のレコード数を示しますが、count(1) は主キーでカウントされた結果セットのレコード数を示します。ほとんどの場合、count() と count(1) は同じ効果がありますが、count(col1) は結果セット内の col1 列の null ではないレコード数を示します。 count() を優先する

(2)大量のデータをカウントすることはリソースを消費する操作であり、データベース全体の速度が低下する可能性があります。クエリパフォーマンスの問題を解決できない場合は、製品設計を再構築する必要があります。たとえば、カウントクエリが頻繁に必要な場合は、サマリーテーブルの使用を検討してください。

(3)distinctの場合、group byメソッドの方が効率的である可能性があります。

17. 削除文と更新文を「選択してから説明する」に変更する

選択操作はデータベースの速度低下を引き起こすだけですが、書き込み操作はテーブルをロックする原因となります。

18. データベースとのやり取りを減らし、バッチSQL文を使用するようにする

(1) INSERT ... ON DUPLICATE KEY UPDATE ...: 挿入された行によってUNIQUEインデックスまたはPRIMARY KEYに重複した値が生じる場合、古い行は更新されます。重複がない場合は、古い行が直接挿入され、1行に影響します。

(2)REPLACE INTOも同様ですが、競合が発生した場合に古い行を削除します。 INSERT IGNORE はその逆を行い、古い行を保持し、挿入される新しい行を破棄します。

(3)INSERT INTO VALUES(),(),(),マージ挿入。

19. 危険なSQLを排除する

(1) 意味のない、または常に真となる条件「where 1=1」を削除します。これは、更新/削除や SQL インジェクションが発生した場合に非常に危険です。

(2)SQLではDDL文は使用できません。通常、作成/変更などの権限は付与されませんが、Alibaba Cloud RDS では読み取りユーザーと書き込みユーザーのみを区別します。

VI. 行動規範

(1)DBAの許可なくライブネットワークデータをインポートすることは許可されていない

(2)データの修復などの大規模な更新の場合は、ピーク時を避けてDBAに通知してください。 SQLの直接実行は、運用保守またはDBAの同僚によって行われます。

(3)オフラインサービスにおけるSQL文のタイムリーな処理

(4)複雑なSQLのオンラインレビュー

現在、SQL レビュー メカニズムがないため、複数テーブルの結合、カウント、グループ化などの複雑な SQL ステートメントは、評価のために DBA に積極的に報告する必要があります。

(5)重要なプロジェクトのデータベースソリューションの選択と設計は、事前にDBAに通知されなければならない。

要約する

以上がこの記事の全内容です。皆様のお役に立てれば幸いです。

参照:

MySQL準備原理の詳細な説明

いくつかの重要なMySQL変数

MySQL マスターライブラリ binlog (master-log) とスレーブライブラリ relay-log 間のコードの詳細な説明

読んでいただきありがとうございます。友人たちがこのサイトを応援してくれることを願っています。

以下もご興味があるかもしれません:
  • MySQL 使用仕様の概要
  • 超詳細なMySQL使用仕様の共有
  • MySQLデータベースの使用仕様の概要
  • 経験豊富な人が、プロフェッショナルで標準化されたMySQL起動スクリプトの開発方法を紹介します。
  • MySQL開発標準と使用スキルの概要
  • MySQL データベースの命名標準と規則
  • Mysql テーブル作成とインデックス使用仕様の詳細な説明
  • MYSQL データベースの命名と設計仕様
  • プロフェッショナルなMySQL開発設計仕様とSQL記述仕様

<<:  Bash スクリプトでの配列メソッドの作成と使用の概要

>>:  React useEffect の理解と使用

推薦する

MySQL データベースの基本的な SQL ステートメントの概要

この記事では、例を使用して、Mysql データベースの基本的な SQL ステートメントについて説明し...

MySQL のバックアップとリカバリの設計アイデア

背景まず、背景を説明します。ある制約により、当社の現在のバックアップ戦略では、1 日おきにフル バッ...

Nginx 構成検出サービスのステータスを実装する方法

1. チェックステータスモジュールがインストールされているかどうかを確認します。 [root@loc...

vue_drf は SMS 認証コードを実装します

目次1. 需要1. 需要2. SDKパラメータ設定1. ディレクトリ構造3. コードの実装1. バッ...

MySQL 5.7 JSON 型の使用の詳細

JSON は、言語に依存しないテキスト形式を使用する軽量のデータ交換形式で、XML に似ていますが、...

CSS スタイルで一般的なグラフィック効果を示すサンプルコード

一般的な基本グラフィックと私が遭遇するいくつかの小さなアイコンについて簡単に説明します。以下は CS...

React Router で履歴リダイレクトを使用する方法

react-routerでは、コンポーネント内のジャンプは<Link>で使用できます。し...

docker に php-fpm サービス/拡張機能/構成をインストールする詳細なチュートリアル

macにbrewを使ってphp56をインストールしたところ、 opensslがバージョン1.1だった...

ウェブページでよく使用される共有コードの完全なリスト(フロントエンドに必須)

コードをコピーコードは次のとおりです。 1. 新浪微博<a href="http:/...

VUE ユニアプリカスタムコンポーネントについての簡単な説明

1. 親コンポーネントはpropsを通じて子コンポーネントにデータを渡すことができる2. 子コンポー...

nginxフォワードプロキシとリバースプロキシの詳細な説明

目次フォワードプロキシnginx リバースプロキシnginx リバースプロキシ 02リバースプロキシ...

VMware vSphere 6.7 (ESXI 6.7) のグラフィック インストール手順

環境: VMware VCSA 6.7 (VMware-VCSA-all-6.7.0-8169922...

JTAを実装するためにAtomikosと組み合わせたTomcatについて

最近、プロジェクトは環境を切り替え、WebLogic を Tomcat に置き換えました。途中で発生...

bitronix を使用して MySQL に接続するときの MySQLSyntaxErrorException の解決方法

bitronix を使用して MySQL に接続するときの MySQLSyntaxErrorExce...

XshellがvirtualBox仮想マシンに接続できない問題の解決策

まず、VirtualBox仮想マシンのネットワーク設定モードについて説明します。NAT+ホストオンリ...