MySQLデータベースの高度なarticles_view、transaction、index

高度なMySQLデータベース

見る

複雑なクエリSQLステートメントの場合、関連するクエリの複数のテーブルによって取得されることがよくあります。要件やその他の理由でデータベースが変更された場合、クエリされたデータが以前と同じになるようにするには、複数のテーブルで変更する必要があります。場所、そしてメンテナンスは非常に面倒ですが、今回は定义视图解決する方法でできます。

ビューとは何ですか?

通俗一点来说,'视图' 其实就是一个 'SELECT' 语句的结果集。したがって、私たちがいた使用视图ときの主な仕事は、このSQLクエリを作成することでした。

视图的本质是对若干个基本表/引用表的引用,一张虚表(也可以理解为假的表),查询语句执行的结果, 実際には、実際のデータは保存されません(基本テーブル/参照テーブルのデータが変更されると、ビューのクエリ実行の結果も変更されます)。

视图利点は、クエリ操作、複雑なSQLステートメントの削減、および読みやすさの向上です。

ビューを定義する

  • ビュー名は「v_」で始めることをお勧めします
create view 视图名称 as select语句;

試行を表示

  • ビューテーブルには、すべてのビューも一覧表示されます
show tables;

ビューを使用

  • ビューの目的はクエリを実行することです
select * from v_stu_score;

ビューを削除

  • ドロップビュービュー名;
drop view v_stu_sco;

デモを見る

view01

view02

view03

view04

ビューの役割

  • 関数と同じように、再利用性が向上しました
  • プログラムの動作に影響を与えることなくデータベースをリファクタリングします
  • 改善されたセキュリティパフォーマンス、さまざまなユーザーに使用できます
  • データをより明確にする

一般大公司有自己的数据库设计规范,比如禁止使用视图之类的情况。

事務

トランザクションとは何ですか?

このトランザクションは、注文システム、銀行システムなどのさまざまなシナリオで広く使用されています。

例如:

	A用户和B用户是银行的储户,现在A要给B转账500元,那么需要做以下几件事:

		1、检查A的账户余额>500元;
		2、A 账户中扣除500元;
		3、B 账户中增加500元;

通常のプロセスがダウンし、Aアカウントから500が差し引かれ、Bアカウントから500が追加され、誰もが満足しています。

アカウントAからお金が差し引かれた後、システムに障害が発生した場合はどうなりますか?無駄に500を失い、Bは彼に属するはずの500を受け取りませんでした。

上記の場合、前提条件は隠されています。Aはお金を差し引き、Bはお金を増やすか、同時に成功するか、同時に失敗します。これはトランザクションの必要性です

所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

たとえば、銀行振込の作業:1つの口座からお金を差し引き、別の口座にお金を追加すると、これら2つの操作が実行されるか実行されないかのどちらかになります。したがって、それらは問題と見なされるべきです。トランザクションは、データベースがデータの整合性を維持するための単位です。各トランザクションの終了時に、データの整合性を維持できます。

トランザクションの4つの特性(略してACID)

  • アトミシティ
  • 一貫性
  • 隔離
  • 耐久性

次のコンテンツは、「High PerformanceMySQL」の第3版からのものです。トランザクションのACIDと4つの分離レベルを理解すると、トランザクション操作をよりよく理解するのに役立ちます。

以下は、トランザクションの必要性を説明する銀行アプリケーションの典型的な例です。銀行のデータベースに、小切手と普通預金の2つのテーブルがあるとします。ユーザーのジェーンの当座預金口座から普通預金口座に200ドルを送金するには、少なくとも3つの手順が必要です。

当座預金口座の残高が200ドル以上であることを確認してください。
当座預金口座の残高から$ 200を引きます。
普通預金口座の残高に200ドルを追加します。

上述三个步骤的操作必须打包在一个事务中,任何一个步骤失败,则必须回滚所有的步骤。

START TRANSACTIONステートメントを使用してトランザクションを開始し、COMMITを使用して変更されたデータを永続化するようにコミットするか、ROLLBACKを使用してすべての変更を元に戻すことができます。トランザクションSQLのサンプルは次のとおりです。

1、start transaction;
2、select balance from checking where customer_id = 10233276;
3、update checking set balance = balance - 200.00 where customer_id = 10233276;
4、update savings set balance = balance + 200.00 where customer_id = 10233276;
5、commit;

優れたトランザクション処理システムには、これらの標準機能が必要です。

  • アトミシティ

トランザクションは、分割できない最小作業単位と見なす必要があります。トランザクション全体のすべての操作が正常に送信されるか、すべて失敗してロールバックされます。トランザクションの場合、操作の一部のみを実行することはできません。これがトランザクションのAtomicityです。

  • 一貫性

データベースは常に、ある一貫性のある状態から別の一貫性のある状態に移行します。(前の例では、一貫性が保証されています。3番目と4番目のステートメントの実行の間にシステムがクラッシュした場合でも、トランザクションが最終的にコミットされていないため、当座預金口座で200ドルの損失はありません。トランザクションもデータベースに保存されません。)

  • 隔離

一般的に、ある会社によって行われた変更は、最終的に送信されるまで他のトランザクションには表示されません。(前の例では、3番目のステートメントが実行され、4番目のステートメントがまだ開始されていない場合、この時点で別のアカウント要約プログラムが実行されており、当座預金口座の残高から200米ドルが差し引かれていません。 )

  • 耐久性

トランザクションがコミットされると、加えられた変更はデータベースに永続的に保存されます。(現時点では、システムがクラッシュしても、変更されたデータは失われません。)

取引順序

  • トランザクションを使用するには、テーブルのエンジンタイプがinnodbタイプである必要があります。これは、mysqlテーブルのデフォルトエンジンです。

テーブルの作成ステートメントを表示すると、engine = innodbが表示されます。

-- 选择数据库
use jing_dong;
-- 查看goods表
show create table goods;

トランザクションを開くためのコマンドは次のとおりです。

  • トランザクションを開いた後に変更コマンドを実行すると、変更はローカルキャッシュに保持されますが、物理テーブルには保持されません。
begin;
或者
start transaction;

トランザクションをコミットします。コマンドは次のとおりです。

  • キャッシュ内のデータ変更を物理テーブルに保持します
commit;

トランザクションをロールバックするためのコマンドは次のとおりです。

  • キャッシュ内の変更されたデータを破棄します
rollback;

注意

  • データを変更するコマンドは、挿入、更新、削除などのトランザクションを自動的にトリガーします
  • SQLステートメントでトランザクションを手動で開く理由は次のとおりです。データを複数回変更できます。データが一緒に成功すると、前のデータに一緒にロールされます。

インデックス

一般的なアプリケーションシステムとデータベースの読み取りと書き込みの比率は約10:1(つまり、クエリ操作が10回ある場合に書き込み操作が1回)であり、挿入操作と更新操作でパフォーマンスの問題が発生することはめったになく、最も多く発生します。問題は依然としていくつかの複雑なクエリ操作であるため、クエリステートメントの最適化が明らかに最優先事項です。

データベース内のデータ量が非常に多い場合、データの検索が非常に遅くなり、今回はそれが使用されます优化解决方案:索引。

インデックスとは何ですか?

インデックスは特殊なタイプのファイルであり(InnoDBデータテーブルのインデックスはテーブルスペースの不可欠な部分です)、データテーブル内のすべてのレコードへの参照ポインターが含まれています。

より一般的に言えば、データベースインデックスは、本の前にある目次のようなものであり、データベースのクエリ速度を上げることができます。

インデックスの目的

インデックス作成の目的は、クエリの効率を向上させることです。辞書と比較できます。「mysql」という単語を検索する場合は、m文字を検索し、下からy文字を検索してから、残りのSQL。インデックスがない場合は、すべての単語を調べて必要なものを見つける必要があります。mで始まる単語を見つけたい場合はどうすればよいですか。またはzeで始まる単語?インデックスを付けないと、このことはできないと思いますか?

インデックスの原則

辞書に加えて、駅での列車の時刻表や本のカタログなど、インデックスの例は生活のいたるところにあります。それらの原理は同じです。取得するデータの範囲を絶えず絞り込むことで、ランダムなイベントを順次イベントに変換しながら、最終的な目的の結果を除外できます。つまり、常に同じ検索方法を使用してデータをロックします。

データベースは同じですが、同等のクエリだけでなく、範囲クエリ(>、<、between、in)、ファジークエリ(like)、ユニオンクエリ(or)、等々。データベースはすべての問題に対処するためにどのように選択する必要がありますか?辞書の例を振り返ってみましょう。データをセグメントに分割してから、セグメントでクエリを実行できますか?最も簡単なのは、1000個のデータ、1から100を最初の段落に分割し、101から200を2番目の段落に分割し、201から300を3番目の段落に分割する場合です。 250番目のデータ。3番目の段落を見つけるだけで済みます。無効なデータの90%を削除しました。

suoyin01

インデックスの使用

  • インデックスを表示
show index from 表名;
  • インデックスを作成する
    • 指定されたフィールドが文字列の場合、長さを指定する必要があります。長さは、フィールドが定義されたときの長さと同じにすることをお勧めします。
    • フィールドタイプが文字列でない場合は、長さの部分を入力する必要はありません
create index 索引名称 on 表名(字段名称(长度))
  • インデックスを削除する
drop index 索引名称 on 表名;

索引Demo

テストテーブルtestindexを作成します

create table test_index(title varchar(10));

pythonプログラム(ipythonも可能)を使用して、pymsqlモジュールを介してテーブルに10万個のデータを追加します

from pymysql import connect

def main():
    # 创建Connection连接
    conn = connect(host='localhost',port=3306,database='jing_dong',user='root',password='mysql',charset='utf8')
    # 获得Cursor对象
    cursor = conn.cursor()
    # 插入10万次数据
    for i in range(100000):
        cursor.execute("insert into test_index values('ha-%d')" % i)
    # 提交数据
    conn.commit()

if __name__ == "__main__":
    main()

お問い合わせ

  • 実行時間の監視をオンにします。
set profiling=1;
  • 10,000番目のデータを見つけるha-99999
select * from test_index where title='ha-99999';
  • 実行時間を表示します。
show profiles;
  • テーブルtitle_indexのタイトル列のインデックスを作成します。
create index title_index on test_index(title(10));
  • クエリステートメントを実行します。
select * from test_index where title='ha-99999';
  • 実行時間を再度確認してください
show profiles;

注意:

要注意的是,建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。对于一个
经常需要更新和插入的表格,就没有必要为一个很少使用的where字句单独建立索引了,对于比较小的表,
排序的开销不会很大,也没有必要建立另外的索引。

建立索引会占用磁盘空间

おすすめ

転載: blog.csdn.net/weixin_42250835/article/details/90694483