記事のディレクトリ
まず、トランザクション
1.トランザクションリード
サービスが広くシステム、銀行システムを発注、さまざまなシナリオで使用されています。
例:
AユーザーとユーザーBがA、Bは$ 500を転送与えるようになりました銀行の預金、とされ、次のことを行う必要があります:
A> 500元の口座残高の確認を、
Aは500元を控除アカウント;
Bが500増加したアカウント元。
通常のプロセスでは、ダウンして、アカウントA 500、B 500プラスアカウントアップバックル;
Aがお金を控除した後のアカウントた場合、システムが故障していることを、500 Aを失うことになり、Bは彼に属し、これを受信しませんでしたが500。
同時にお金を控除AとBプラスお金、成功するか失敗すると同時に、次のいずれかのケースの上に、それは前提条件を非表示にします。この中で業務を要求します。
2.トランザクション定義
トランザクションは、それが仕事の不可分単位であり、これらの操作は、いずれかの実行、実行、またはされていない、一連の動作です。
たとえば、銀行振込の作業:デビット口座から別の口座や助成金は、これらの2つの操作は、いずれかの実行中または実行されません。したがって、我々は、ビジネスとしてそれらが表示されるはずです。
トランザクションは、データの一貫性を維持することができ、各トランザクションの終了時に、ユニットのデータの一貫性を維持するデータベースです。
次いで、少なくとも三つのステップ:
(1)口座残高より大きいまたは$ 1 100に等しいチェック
$ 100に口座残高から1を減算する(2)と、
アカウントに$ 100 2バランスの(3)に増加。
begin;
update bank1 set money = money - 100 where id = 1;
この時点では何もクエリは、物事の分離を反映するときにデータが変更されません、そこにコミットされません。
update bank2 set money = money + 100 where id = 1;
commit;
このとき、二つのテーブル内のデータは100、100の増加を減らし、変更されています。
以上の2つのステップが完全なトランザクションを形成します。
たびに自動的に成功し動作するために提出する、トランザクションを開いた後にSQL文を実行した後に提出されていません。
4件の取引の3特性(ACID)
(1)アトミック(原子性):
トランザクションが、トランザクション全体のすべての操作は、すべて正常に送信、またはすべてのトランザクションのロールバックに失敗のいずれかで、ワークの最小単位の不可欠な部分であると考えられる、それだけ場所を実行することは不可能ですトランザクションのアトミックな操作、の一部。
(2)整合性(一貫性):
データベースは、常に別の一貫性の一貫性の状態からの状態遷移です。
前の例では、一貫性は、システムが2つのUPDATE文の崩壊の間で実行された場合でも、確保され、銀行口座は、取引はとてもトランザクションに行われた変更はしませんが、最終的に提出していなかった、ではない失う$ 100になるので、データベースに保存されました。
(3)分離(単離):
一般的に言えば、会社は最終提出する前に修正した、他のトランザクションは表示されません。
前の例では、ステートメントを実行した後の最初の更新は、4番目の文はまだ開始されていないとき、この時間が実行されているプログラムの概要の別のアカウントが存在し、それは口座の残高がマイナス$ 100されていない見ました。
コマンドラインでは、トランザクションを開きます
begin;
update goods set name = 'palyer' where id = 3;
コミットされていない
別のコマンドラインで別の操作を実行
update goods set name = 'Player' where id = 3;
前のコマンドラインは、動作時に、トランザクションをコミットしていないため、ブロックされて表示されますが、他のデータベースの操作は、このようにデータの一貫性を確保すること、すなわち前に、ロックされます。
(4)持続的な(耐久性):
トランザクションのコミットしたら、それは永久にデータベースに保存なさ変更します。
システムがクラッシュした場合でも、この時点では、変更されたデータが失われることはありません。
4.トランザクション操作
エンジンタイプのテーブルはInnoDBのタイプがデフォルトエンジンのMySQLのテーブルでトランザクションを使用することができなければなりません。
オープン取引:
文法:start transation;
またはbegin;
変更コマンドの後に実行されたトランザクションを開いて、変更がローカルキャッシュを維持するのではなく、物理的なテーブルを維持します。
トランザクションをコミットします:
構文:commit;
データがテーブルの物理的な維持管理への変更をキャッシュします。
トランザクションをロールバックします:
構文:rollback;
データキャッシュの変更をあきらめます。
運動:
2を100rpmにトランザクションで今動作、1 100トランザクションで3への転送他のながら
次のようにデータであります
+----+-----+
| id | num |
+----+-----+
| 1 | 100 |
| 2 | 200 |
| 3 | 0 |
+----+-----+
処理動作が示されている
トランザクションが1を送信した後、二対は、このようにデータの一貫性を確保する、トランザクションはエラーであり、したがって、ロールバックする必要が変更ID1。
変更データは、自動的にコマンドを挿入、更新、削除を含め、業務をトリガし、
操作は多くのデータベース・データへの変更、および成功の成功を必要とする場合は、データそれ以外の場合は、前に一緒にロールバックされます、SQL文の手動への必要性オープン情勢。
第二に、インデックス
1.はじめに
在图书馆中是如何找到一本书的?
一般的应用系统对比数据库的读写比例在10:1左右(即有10次查询操作时有1次写的操作),而且插入操作和更新操作很少出现性能问题,遇到最多、最容易出问题还是一些复杂的查询操作,所以查询语句的优化显然是重中之重。
当数据库中数据量很大时,查找数据会变得很慢,所以引入索引进行优化。
2.定义
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
通俗地说,数据库索引就像一本书前面的目录,它们包含着对数据表里所有记录的引用指针。
索引的目的:
索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql。
索引原理:
生活中随处可见索引的例子,如词典、火车站的车次表、图书的目录等。它们的原理都是一样的,通过不断的缩小想要获得数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是我们总是通过同一种查找方式来锁定数据。
数据库也是一样,但显然要复杂许多,因为不仅面临着等值查询,还有范围查询(>、<、between、in)、模糊查询(like)、并集查询(or)等等。
如下图
索引使用的数据结构一般是B树。
索引分为:
- 单值索引:单个字段;
- 复合索引:多个字段;
- 唯一索引:列的值必须唯一,应用于身份证号、电话号等。
3.索引的使用
查看索引:
语法:show index from 表名;
show index from money;
打印
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| money | 0 | PRIMARY | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.01 sec)
主键会自动创建索引;
创建索引:
语法:create index 字段名称 on 表名(字段名称(长度));
create index idx_num on money(num);
再查看索引
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| money | 0 | PRIMARY | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
| money | 1 | idx_num | 1 | num | A | 2 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
如果指定字段是字符串,需要指定长度,建议长度与定义字段时的长度一致;
字段类型如果不是字符串,可以不填写长度部分。
创建唯一索引:
create unique index idx_num on money(num);
删除索引:
语法:drop index 索引名称 on 表名;
4.索引练习
创建测试表test:
create table test(title varchar(10));
使用python程序向表中加入十万条数据:
from pymysql import *
def main():
conn = connect(
host='127.0.0.1',
port=3306,
db='demo',
user='root',
passwd='root',
charset='utf8')
cur = conn.cursor()
for i in range(100000):
cur.execute('insert into test values("ts-%d")' % i)
conn.commit()
if __name__ == '__main__':
main()
开启运行时间监测:
set profiling=1;
查找第100000条数据:
select * from test where title='ts-99999';
打印
+----------+
| title |
+----------+
| ts-99999 |
+----------+
1 row in set (0.04 sec)
查看执行的时间:
show profiles;
打印
+----------+------------+-------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------+
| 1 | 0.03794450 | select * from test where title='ts-99999' |
+----------+------------+-------------------------------------------+
1 row in set, 1 warning (0.00 sec)
为表title_index的title列创建索引:
create index title_index on test(title(10));
再次执行查询语句:
select * from test where title='ts-99999';
打印
+----------+
| title |
+----------+
| ts-99999 |
+----------+
1 row in set (0.00 sec)
再次查看执行的时间:
show profiles;
打印
+----------+------------+---------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+---------------------------------------------+
| 1 | 0.03794450 | select * from test where title='ts-99999' |
| 2 | 0.26895350 | create index title_index on test(title(10)) |
| 3 | 0.00031875 | select * from test where title='ts-99999' |
+----------+------------+---------------------------------------------+
3 rows in set, 1 warning (0.00 sec)
显然,建立了索引后查询速度有了很大提升,即建立索引可以大幅提高查询效率。
适合建立索引的情况:
- 主键自动建立索引;
- 频繁作为查询条件的字段应该建立索引;
- 查询中与其他表关联的字段,外键关系建立索引;
- 在高并发的情况下创建复合索引;
- 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度 (建立索引的顺序跟排序的顺序保持一致)。
不适合建立索引的情况:
- 频繁更新的字段不适合建立索引;
- where条件里面用不到的字段不创建索引;
- 表记录太少,当表中数据量超过三百万条数据,可以考虑建立索引;
- 数据重复且平均的表字段,比如性别,国籍。
三、账户管理
在生产环境下操作数据库时,绝对不可以使用root账户连接,而是创建特定的账户,授予这个账户特定的操作权限,然后连接进行操作,主要的操作就是数据的crud。
MySQL账户体系:
根据账户所具有的权限的不同,MySQL的账户可以分为以下几种:
- 服务实例级账号:启动了一个mysqld,即为一个数据库实例;如果某用户如root,拥有服务实例级分配的权限,那么该账号就可以删除所有的数据库、连同这些库中的表;
- 数据库级别账号:对特定数据库执行增删改查的所有操作;
- 数据表级别账号:对特定表执行增删改查等所有操作;
- 字段级别的权限:对某些表的特定字段进行操作;
- 存储程序级别的账号:对存储程序进行增删改查的操作。
账户的操作主要包括创建账户、删除账户、修改密码、授权权限等。
授予权限:
需要使用实例级账户登录后操作,以root为例
主要操作包括:
(1)查看所有用户:
所有用户及权限信息存储在mysql数据库的user表中;
查看user表的结构:
use mysql;
desc user;
打印
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
| plugin | char(64) | NO | | mysql_native_password | |
| authentication_string | text | YES | | NULL | |
| password_expired | enum('N','Y') | NO | | N | |
| password_last_changed | timestamp | YES | | NULL | |
| password_lifetime | smallint(5) unsigned | YES | | NULL | |
| account_locked | enum('N','Y') | NO | | N | |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
45 rows in set (0.00 sec)
主要字段说明:
Host表示允许访问的主机;
User表示用户名;
authentication_string表示密码,为加密后的值。
查看所有用户:
select host,user,authentication_string from user;
+-----------+---------------+-------------------------------------------+
| host | user | authentication_string |
+-----------+---------------+-------------------------------------------+
| localhost | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| localhost | mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| 127.0.0.1 | Tom | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| localhost | Tom2 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+-----------+---------------+-------------------------------------------+
5 rows in set (0.00 sec)
(2)创建账户、授权
需要使用实例级账户登录后操作,以root为例
常用权限主要包括:create、alter、drop、insert、update、delete、select
如果分配所有权限,可以使用all privileges
语法:
grant 权限列表 on 数据库 to '用户名'@'访问主机' identified by '密码';
grant select on jingdong.* to 'Leo'@'localhost' identified by '123456';
--创建一个Mary的账号,密码为12345678,可以任意电脑进行链接访问, 并且对jd数据库中的所有表拥有所有权限
grant all privileges on jd.* to "Mary"@"%" identified by "12345678"
--刷新权限
flush privileges;
说明:
可以操作数据库的所有表,方式为:jingdong.*;
访问主机通常使用 百分号% 表示此账户可以使用任何ip的主机登录访问此数据库;
访问主机可以设置成 localhost或具体的ip,表示只允许本机或特定主机访问。
查看用户有哪些权限:
show grants for Leo@localhost;
打印
+---------------------------------------------------+
| Grants for Leo@localhost |
+---------------------------------------------------+
| GRANT USAGE ON *.* TO 'Leo'@'localhost' |
| GRANT SELECT ON `jingdong`.* TO 'Leo'@'localhost' |
+---------------------------------------------------+
2 rows in set (0.00 sec)
使用新创建的用户登录:
mysql -uLeo -p
查看数据库:
show databases;
打印
+--------------------+
| Database |
+--------------------+
| information_schema |
| jingdong |
+--------------------+
2 rows in set (0.00 sec)
进行删除操作
use jingdong;
drop table goods;
打印
ERROR 1142 (42000): DROP command denied to user 'Leo'@'localhost' for table 'goods'
あなたは、修正、削除操作を追加することはできませんのでだけで、ビューにレオに許可を与えたため、エラー、コマンドは拒否しました。
第四に、データベースのストレージエンジンの概要
1.MySQLアーキテクチャ:
- 接続層
- サービス層(コア)
- ストレージエンジン層
- ファイルシステム
図:
サービス層:
サービス層は、MySQLの中核である、この中にMySQLのこの層は、クエリの解析、SQLの実行計画の分析、SQLの実行計画の最適化、クエリキャッシュ内のコアサービス層だけでなく、クロスストレージエンジンの機能層を実装:ストアドプロシージャ、トリガ、およびその他のビュー。
:この図は、サービス層の内部構造である
ストレージエンジン層:
MySQLのデータストレージおよび抽出のための責任を負います。
クエリ実行エンジンサーバは、API、別々のストレージエンジン間の違いによるインタフェース画面を通じてストレージエンジンと通信します。
MySQLの用途は、プラグインのストレージエンジン。MySQLのストレージエンジンは、私たちの数を提供し、各ストレージエンジンは異なる特性を持っています。私たちは、異なる事業特性に応じて、最適なストレージエンジンを選択することができます。
あなたは、ストレージエンジンの性能に満足していない場合、あなたは、ソースコードを修正することで実現したいのパフォーマンスを得ることができます。例えばアリババX-エンジン、FacebookやすべてのInnoDBストレージエンジンの企業のニーズを満たすためにGoogleが拡張されました。
2.ストレージエンジンの操作
ビューストレージエンジン:
show engines;
プリント
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.01 sec)
デフォルトのストレージエンジンを表示します。
show variables like '%storage_engines%';
プリント
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| disabled_storage_engines | |
+--------------------------+-------+
1 row in set, 1 warning (0.00 sec)
グループチャットに参加することを歓迎し、[グループ]知識共有のpythonの交換、技術交流:https://jq.qq.com/?_wv=1027&k=5m5AduZ