DBA動作仕様
1.事業に関連するデータの変更/削除は、事業者とCTOの承認後、電子メールで実行され、実行前にバックアップされ、必要に応じて元に戻すことができます。
2.すべてのオンライン要件は作業指示システムを通過する必要があり、口頭による通知は無効と見なされます。
3.フィールド属性の変更など、大きなテーブルのテーブル構造に変更を加えると、テーブルがロックされ、ライブラリで遅延が発生して、オンラインビジネスに影響します。これは、午前0時以降のビジネスの低ピーク期間、およびその他の統合使用中に実行する必要がありますツールpt-online-schema-changeは、テーブルのロックを回避し、遅延実行時間を短縮します。
使用例:
#pt-online-schema-change --alter="add index IX_id_no(id_no)" \
--no-check-replication-filters --recursion-method=none --user=dba \
--password=123456 D=test,t=t1 --execute
MongoDBの場合、テーブルのロックを回避するために、バックグラウンドでインデックスを作成します。
使用例:
db.t1.createIndex({idCardNum:1},{background:1})
4.すべてのオンラインビジネスライブラリは、シングルポイントの問題を回避するために、MHA高可用性アーキテクチャを構築する必要があります。
5.ビジネス側に権限を付与する場合、パスワードは少なくとも5桁のMD5で暗号化する必要があります。権限に特別な要件がない場合、それらはすべて選択クエリ権限であり、データベーステーブルレベルの制限の対象になります。
6.デフォルトの空のパスワードアカウントを削除します。
delete from mysql.user where user='' and password='';
flush privileges;
7.サマリーライブラリは、監査監査ログ機能を開き、問題を追跡できます。
行動規範
8. 1つのMySQLインスタンスに複数のビジネスデータベースを格納することは禁止されています。これにより、ビジネスの結合が高まります。問題が発生すると、池が損傷し、障害の特定が難しくなります。マルチインスタンスは通常、問題を解決するために使用され、1つのインスタンスには1つのサービスライブラリがあり、相互干渉はありません。
9.メインライブラリでバックグラウンド管理と統計関数クエリを実行することは禁止されていますこの複雑なタイプのSQLはCPUの増加を引き起こし、ビジネスに影響を与えます。
10.データをバッチでクリーンアップするには、開発とDBAが一緒にデータを確認する必要があり、営業時間のピーク時に実行を回避し、実行中にサービスのステータスを監視する必要があります。
11. DBパフォーマンスのボトルネックを防ぐために、マシンメモリの増加やアーキテクチャの1週間前の拡張など、トラフィック評価のために、プロモーション活動などを事前にDBAと直接面談しておく必要があります。
12.データベースのストレステストをオンラインで行うことは禁止されています。
基本仕様
13.平文のパスワードをデータベースに保存することは禁止されています。
14. InnoDBストレージエンジンを使用します。
- トランザクション、行レベルのロック、回復性の向上、および高い同時実行性の下でのパフォーマンスの向上をサポートします。
- InnoDBテーブルはCOUNT(*)オペレーションの使用を回避します。内部カウンターがないため、行ごとに計算する必要があります。カウント統計のリアルタイム要件は強力です。MemcacheまたはRedisを使用できます。
15.テーブル文字セットは、UTF8を均一に使用します。
- 文字化けのリスクはありません。
16.すべてのテーブルとフィールドに中国語のコメントを追加する必要があります。
- 他人や自分にとって便利です。
17.画像やファイルなどのビッグデータをデータベースに保存しないでください。
- 画像とファイルはGFS分散ファイルシステムにより適しており、ハイパーリンクをデータベースに保存できます。
18.ストアドプロシージャ、ビュー、トリガー、およびイベントの使用を避けます。
MySQLはOLTPアプリケーションです。これは、単純な追加、削除、変更、およびクエリ操作に最適ですが、論理計算および分析アプリケーションには適していないため、需要のこの部分はプログラムによって最もよく達成されます。
19.外部キーの使用を避ける外部キーは参照整合性を保護するために使用され、ビジネス側で実装できます。
- 外部キーは、親テーブルと子テーブル間の結合を引き起こし、SQLパフォーマンス、過度のロック待機、さらにはデッドロックに大きな影響を与えます。
20.ログテーブルなど、高いトランザクション整合性を必要としないビジネスは、MongoDBに格納することが推奨されます。
- シャーディングシャーディング機能はそれ自体でサポートされているため、水平方向の拡張機能が強化され、開発でビジネスコードをあまり調整する必要がありません。
ライブラリテーブルの設計仕様
21.テーブルには、自己増分主キーなどの主キーが必要です。
- これにより、データ行が順番に書き込まれることが保証されます。SASの従来の機械式ハードディスクの場合、書き込みパフォーマンスが向上し、主キーに基づく連想クエリのパフォーマンスが向上し、データウェアハウスの抽出も容易になります。パフォーマンスの観点から見ると、主キーとしてUUIDを使用することは最悪の方法であり、挿入がランダムになります。
22.パーティションテーブルの使用は禁止されています。
- 分割テーブルの利点は、開発のためにコードを変更する必要がないことです。時間フィールドの分割などのバックエンドDBの設定により、テーブルを簡単に分割できます。ただし、これには問題があり、クエリフィールドはパーティションキーである必要があります。そうしないと、すべてのパーティションテーブルを走査し、パフォーマンスは向上しません。また、パーティションテーブルは物理構造上はテーブルのままですが、現時点ではパフォーマンスを向上させることなくテーブル構造を変更しています。したがって、分割には分割テーブルを使用する必要があります。プログラムで履歴データをクエリする必要がある場合は、union allを使用してクエリを関連付けることができます。さらに、時間が経過すると、履歴データテーブルは不要になり、ライブラリからダンプするだけで済みます。つまり、バックアップマシンに簡単に移行できます。
フィールド設計仕様
23. FLOATおよびDOUBLEではなくDECIMALを使用して、正確な浮動小数点数を格納します。
浮動小数点数の欠点は、精度の問題が発生する可能性があることです。次の例を参照してください。
mysql> CREATE TABLE t3 (c1 float(10,2),c2 decimal(10,2));
Query OK, 0 rows affected (0.05 sec)
>mysql> insert into t3 values (999998.02, 999998.02);
Query OK, 1 row affected (0.01 sec)
>mysql> select * from t3;
+-----------+-----------+
| c1 | c2 |
+-----------+-----------+
| 999998.00 | 999998.02 |
+-----------+-----------+
1 row in set (0.00 sec)
c1列の値が999998.02から999998.00に変更されたことがわかります。これは、float型の不正確さが原因です。したがって、通貨などの精度に敏感なデータは、固定小数点数で表現または保存する必要があります。
24. ENUMタイプの代わりにTINYINTを使用します。
- enum列挙型を使用すると、この時間を増やすと、ユーザーのオンラインステータスなどの拡張の問題が発生します。5は邪魔しない、6は会議中、7は友人には不可視であり、次に新しいENUM値を追加してDDLを実行するテーブル構造操作を変更します。
25.フィールド長はできるだけ実際のニーズに応じて割り当てる必要があり、大容量をランダムに割り当てないでください。
フィールドを選択する一般的な原則は、フィールドを小さくするが大きくはしないことであり、バイト数が少ないフィールドには大きなフィールドは必要ありません。たとえば、uuidではなくint integerを使用することを主キーに強くお勧めします。省スペース。スペースとは?スペース効率!レコードを見つけるための4バイトと32バイトによると、誰が速く、誰が遅いかは明らかです。複数のテーブルが結合に関係している場合、その影響はより明白です。フィールドタイプが小さいほど、必要なメモリが少なくなり、ディスク領域とディスクI / Oが少なくなり、帯域幅も少なくなります。
多くの開発者は、テーブルフィールドをデザインするときにすべての数値型にintを使用しますが、ユーザーの年齢など、これは必ずしも適切ではありません。一般的に、ほとんどの年齢は1〜100歳で、長さは3歳です。 、その後、intの使用は適切ではありません。代わりにtinyintを使用できます。別の例としては、ユーザーのオンラインステータスがあります。0はオフライン、1はオンライン、2は不在、3はビジー、4は不可視などです。実際、intや無駄なスペースを使用する必要はありません。tinyintを使用すると、ニーズを完全に満たすことができます。 、Intは4バイトを占有し、tinyintは1バイトを占有します。
Int整数の符号付き(符号付き)最大値は2147483647で、符号なし(符号なし)最大値は4294967295です。負の数を格納する必要がない場合は、符号付き(符号なし)に変更することをお勧めします。int格納範囲を増やすことができます。
int(10)とint(1)の間に違いはありません。10と1は単なる幅であり、zerofill拡張属性を設定するときに役立ちます。次に例を示します。
root@localhost(test)10:39>create table test(id int(10) zerofill,id2 int(1));
Query OK, 0 rows affected (0.13 sec)
root@localhost(test)10:39>insert into test values(1,1);
Query OK, 1 row affected (0.04 sec)
root@localhost(test)10:56>insert into test values(1000000000,1000000000);
Query OK, 1 row affected (0.05 sec)
root@localhost(test)10:56>select * from test;
+------------+------------+
| id | id2 |
+------------+------------+
| 0000000001 | 1 |
| 1000000000 | 1000000000 |
+------------+------------+
2 rows in set (0.01 sec)
26.フィールドは、デフォルト値を提供するためにNOT NULLとして定義されています。
アプリケーション層の観点から、プログラム判定コードを削減できます。たとえば、レコードをクエリする場合、デフォルト値がない場合は、まずフィールドに対応する変数が設定されているかどうかを判断する必要がありますか?設定されていない場合は、javaを介して変数を設定する必要がありますデフォルト値が設定されている場合は、判定条件を直接スキップできます。
NULL値はクエリを最適化するのが難しく、インデックス統計をより複雑にしますが、MySQL内で特別な処理を必要とします。
27. TEXTおよびBLOBタイプはできるだけ使用しないでください。
- ストレージスペースの占有率を上げ、読み取り速度を遅くします。
インデックス仕様
28.インデックスはできるだけ多くないので、実際のニーズに応じて作成してください。
- インデックスは両刃の剣であり、クエリの効率を向上させることができますが、挿入と更新の速度を低下させ、ディスク領域を占有します。適切なインデックスはアプリケーションのパフォーマンスにとって重要であり、MySQLでインデックスを使用するのは非常に高速です。残念ながら、インデックスには関連するオーバーヘッドもあります。テーブル(INSERT、UPDATEH、DELETEなど)に書き込むたびに、1つ以上のインデックスがある場合、MySQLは各インデックスを更新する必要があるため、インデックスによって各テーブルへの書き込みのオーバーヘッドが増加します。列がWHERE句で使用されている場合にのみ、インデックスのパフォーマンス向上のメリットを享受できます。インデックスを使用しない場合、値はなく、メンテナンスのオーバーヘッドが発生します。
29.クエリフィールドにはインデックスを付ける必要があります。
- 例:1. SELECT、UPDATE、DELETEステートメントのWHERE条件列; 2.マルチテーブルJOINのフィールド。
30.インデックス列で数学演算および関数演算を実行しないでください。
インデックスを使用できないため、テーブル全体がスキャンされます。
例:SELECT * FROM t WHERE YEAR(d) >= 2016;
MySQLはOracleのような機能インデックスをサポートしていないため、dフィールドにインデックスがあっても、テーブル全体を直接スキャンします。
----->に変更する必要がありますSELECT * FROM t WHERE d >= '2016-01-01';
31.「gender」などのカーディナリティの低い列にインデックスを作成しないでください。
場合によっては、特にインデックスに均等に分散されたデータセットが含まれている場合、フルテーブルブラウジングの方が、インデックスとデータテーブルを読み取るよりも高速です。この典型的な例は性別で、2つの値(男性と女性)が均等に分布しています。性別を渡すには、行の約半分を読み取る必要があります。この場合、全表スキャンの方が高速です。
32. '%xxx'などの%先行クエリを使用しないでください。
インデックスを使用できないため、テーブル全体がスキャンされます。
低效查询
SELECT * FROM t WHERE name LIKE '%de%';
----->
高效查询
SELECT * FROM t WHERE name LIKE 'de%';
33. not in / not likeなどの逆クエリを使用しないでください。
インデックスを使用できないため、テーブル全体がスキャンされます。
34.冗長または重複したインデックスを避けます。
結合インデックスIX_a_b_c(a、b、c)は(a)、(a、b)、(a、b、c)と同等であり、インデックス(a)と(a、b)は冗長です。
SQL設計仕様
* 35. SELECTは使用されず 、必要なフィールドのみが取得されます。**
CPUとIOを消費し、ネットワーク帯域幅を消費します。
カバリングインデックスは使用できません。
36. ORをINに置き換えます。
低效查询
SELECT * FROM t WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30;
----->
高效查询
SELECT * FROM t WHERE LOC_IN IN (10,20,30);
37.矛盾するデータ型を避けます。
SELECT * FROM t WHERE id = '19';
----->
SELECT * FROM t WHERE id = 19;
38.データベースとの対話の数を減らします。
INSERT INTO t (id, name) VALUES(1,'Bea');
INSERT INTO t (id, name) VALUES(2,'Belle');
INSERT INTO t (id, name) VALUES(3,'Bernice');
----->
INSERT INTO t (id, name) VALUES(1,'Bea'), (2,'Belle'),(3,'Bernice');
Update … where id in (1,2,3,4);
Alter table tbl_name add column col1, add column col2;
39.大きなSQLを拒否し、小さなSQLに分割します。
低效查询
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id = tag.id
JOIN post ON tag_post.post_id = post.id
WHERE tag.tag = 'mysql';
可以分解成下面这些查询来代替
----->
高效查询
SELECT * FROM tag WHERE tag = 'mysql'
SELECT * FROM tag_post WHERE tag_id = 1234
SELECT * FROM post WHERE post_id in (123, 456, 567, 9098, 8904);
40. rand()による順序の使用は禁止されています
SELECT * FROM t1 WHERE 1=1 ORDER BY RAND() LIMIT 4;
---->
SELECT * FROM t1 WHERE id >= CEIL(RAND()*1000) LIMIT 4;