高度なmysqlの - キー、ストアドプロシージャ、取引(InnoDBの)

1.キー

1.1主キー

完全なプライマリキー(PRIMARY KEY)は、主キー制約と呼ばれています。MySQLの主キー制約は、値テーブル内の各行を一意に識別する列または列の組み合わせです。このような1つ以上の列がテーブルの主キーと呼ばれる、それはテーブルのエンティティの整合性によって強制することができます。

PRIMARY KEY 约束唯一标识数据库表中的每条记录。
主键列不能包含 NULL 值。
主键必须包含唯一的值。
每个表都应该有一个主键,并且每个表只能有一个主键。

使用例

ALTER TABLE table_name ADD PRIMARY KEY (Id); -- 添加主键
ALTER TABLE table_name DROP PRIMARY KEY; -- 删除主键
CREATE TABLE table_name (
Id int NOT NULL AUTO_INCREMENT,
...,
PRIMARY KEY (Id) -- 创建表时设置主键
)

プライマリキー違反

挿入されたデータでは、プライマリーキー既に存在に対応する値を仮定し、それが挿入不良の原因となります。(重複キー)主キーの衝突、選択的更新と交換する、処理することができます。

テーブルに挿入[フィールドリスト:主キー]重複キーの更新フィールドに値(値リスト)=新しい値

insert into table_name values(...) on duplicate key update;
replace into table_name values(...);

1.2外部キー

外部キー制約は、(FOREIGN KEY)リンクを確立するために、2つのデータテーブルとの間で使用される、または、複数の行であってもよいです。テーブルは、1つまたは複数の外部キーを持つことができます。

外部キーの参照整合性に対応するヌル値、各外部キー値の値が別のテーブルの主キーに等しくなければならない場合、外部キーテーブルは、ヌルであってもよいです。外部キーは、これはテーブルの主キーが、別のテーブルの対応する主キーではなく、テーブル内のフィールドです。関連する関係で、別のテーブルに行を削除することが許可されていない外部キーを定義します。外部キーの主な役割は、データの一貫性、整合性を維持することです。

使用例

ALTER TABLE curr_table_name ADD CONSTRAINT fk_name FOREIGN KEY column_name REFERENCES fk_table_name (column_name); -- 添加外键
ALTER TABLE curr_table_name DROP FOREIGN KEY fk_name; -- 删除外键
CREATE TABLE curr_table_name (
curr_Id int NOT NULL,
...,
fk_Id int,
PRIMARY KEY (curr_Id),
FOREIGN KEY (fk_Id) REFERENCES fk_table_name(fk_col) -- 创建表的时候添加外键
)

1.3インデックス

MySQLでは、インデックス(指数)も素早くレコードを検索するために使用されるデータ構造のストレージエンジンであるキー(鍵)と呼ばれます。システムは、いくつかのアルゴリズムに従って、高速なマッチングデータとすることができる文書ファイルの個別のインデックスデータを作成し、対応表をすばやく見つけることができます記録されます。

1.3.1インデックス機能

1. 提高查询效率,同时也会降低更新表的速度,如 insert/update/delete时,不仅要保存数据,还要保存一下索引文件。
2. 约束数据的有效性(如唯一性等)。
3. 索引本身会产生索引文件,会占用磁盘空间。

1.3.2分類インデックス

1. 主键索引: Primary Key
2. 外键索引: Foreign Key
2. 唯一索引: Unique Key|Index
3. 全文索引: fulltext
4. 普通索引: index

1.3.3インデックスタイプ:BTREEとHASH

BTREE 索引,对索引列是顺序存储的,并且每一个叶子页到根的距离相同。很适合查找范围数据。
HASH 索引,基于哈希表实现的,只有精确匹配索引所有列的查询才有效。

HASHインデックス使用時にはいくつかの重要な機能は、特別な注意が必要です

1. 只用于使用 = 或 <=> (NULL 安全的等于)操作符的等式比较。
2. 优化器不能使用 HASH 索引来加速 ORDER BY 操作。
3. 只能使用整个关键字来搜索一行。
而对于 BTREE 索引,当使用范围查询如>、<、>=、<=、BETWEEN、!=或者<>,或者 LIKE 'pattern'(其中'pattern'不以通配符开始)操作符时,都可以使用相关列上的索引。

設計原理1.3.4インデックス

1. 不是越多越好
2. 常更新的表越少越好
3. 数据量小的表最好不要建立索引
4. 不同的值比较多的列才需要建立索引
5. 某种数据本身具备唯一性的时候,建立唯一性索引,可以保证定义的列的数据完整性,以提高查询熟度
6. 频繁进行排序或分组的列(group by或者是order by)可以建立索引,提高搜索速度
7. 经常用于查询条件的字段应该建立索引

インデックスを作成します

インデックスは、テーブルを作成するとき、あなたはいつでも新しいインデックスを追加することができ、同時に作成することができます。新しいインデックス構文は次のとおりです作成します。

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
ON table_name (column_name, ...)
column_name: column_name [(length)] [ASC | DESC]
-- length 表示字节长度

以下を使用

CREATE UNIQUE INDEX index_name ON table_name column_name(length); -- 创建唯一索引
CREATE INDEX index_name ON table_name column_name(length);
ALTER table table_name ADD INDEX index_name(column_name); -- 添加索引(修改表的结构)
ALTER TABLE table_name ADD UNIQUE index_name(column_name);
ALTER TABLE table_name ADD PRIMARY KEY column_name(length);
ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);
ALTER TABLE table_name ADD FULLTEXT column_name(length);
DROP INDEX [index_name] ON table_name; -- 删除索引

2.ストアドプロシージャ

2.1機能

コールが実行されるときにパッケージ構造にコードの一部、構成を行うことができます。

2.1.1変数

システム変数:システム定義の変数、などのように自動コミット。しかし、一般的にシステム変数を使用しません。

show variables; -- 查看所有系统变量
set @@autocommit = 0; -- 修改系统变量,禁止自动提交,修改之后客户端需重启才能生效
set global autocommit=0; -- 全局修改,对所有的客户端都生效

カスタム変数:ユーザー定義変数

-- 通过 DECLARE 可以定义一个局部变量
DECLARE varname varchar(32) default ''; 
-- 定义变量并赋值,注意这里使用一个 @ 符号,而不是两个;如果不用 @ 则是局部变量
set @varname = "trent";  
select @varname := varname, varname from table_name; -- 在select中 := 表示赋值,而=表示比较。

2.1.2ループ

while expr do
statement...
-- iterate -- iterate 相当于 continue
-- leave -- leave 相当于 break
end while;
-- 类似的循环还有 loop,用法类似

2.1.3機能

カスタムシステム関数は、直接使用するために使用することができます。

create function func_name() return int  -- 定义函数
return 100; -- 当函数自由一条语句的时候,可以不使用 begin/end语句
select func_name();  -- 调用函数
select function status\G  -- 查看所有函数
show create function func_name;  -- 查看函数的创建语句
drop function func_name;  -- 删除函数

パラメータを使用します

パラメータの定義は、パラメータと呼ばれるときに呼び出すときに、パラメータが引数と呼ばれます。あなたは、データ型のパラメータを指定する必要があります。

delimiter $$
create function func_name(var1 int) return int 
begin
    set @varname = 1;
    set @i = 0;
    while @i < var1 do
        if mod(@i, 2) = 2 then
            set @varname = @varname + @i
        else iterate
        end if
        set @i = @i + 1
    return @varname
end $$
delimiter ;

2.2ストアドプロシージャ

外部プログラムが呼び出すようにデータベース・オブジェクトを格納するストアドプロシージャ(ストアドプロシージャ)は、データベース内の複雑な手順です。

ストアドプロシージャは、特定の機能を完了するには、SQLステートメントに設定されコンパイルされたデータベース内に作成され、保存された(必要な場合)、ユーザーが実行を呼び出すために、ストアドプロシージャの名前と指定されたパラメータを指定することができます。コードパッケージを再利用するために。

2.2.1利点

存储过程可封装,并隐藏复杂的商业逻辑。
存储过程可以回传值,并可以接受参数。
存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。
存储过程可以用在数据检验,强制实行商业逻辑等。

2.2.2短所

存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
存储过程的性能调校与撰写,受限于各种数据库系统。

いいえパラメータんストアドプロシージャ

delimiter $$
create procedure proc_name()
begin
select * from table_name;
-- ... do somethings
end $$
delimiter ;

CALL proc_name (); -- 调用存储过程
DROP PROCEDURE [IF EXISTS] proc_name; -- 删除存储过程
-- 修改存储过程,需要先删除后修改

2.2.3パラメータ

関数のパラメータは、データの型を指定する必要があり、プロセスは機能よりもより厳格である、プロセスは、独自の定義されたタイプがあります。

IN: IN 类型参数一般只用于传入,在调用存储过程中一般不作修改和返回。
OUT: OUT 是传出参数,不能用于传入参数值,在调用存储过程中,可以改变其值,并可返回。
INOUT: INOUT 参数集合了 IN 和 OUT 类型的参数功能,可传入值,也可修改其值,同时也可返回值。

以下を使用

-- IN 参数, OUT 参数
delimiter $$
create procedure test(IN id varchar(32),OUT name varchar(32))
begin
  select users.name into name from users where users.id = id;
  select name;
end $$
dilimiter ;
-- INOUT 参数
delimiter $$
create procedure teste(INOUT id varchar(32), INOUT name varchar(32))
begin
  set id= '666';
  set name = 'trent';
  select users.id,users.name into id, name from users where users.id = id;
end $$
delimiter ;

3.トランザクション

MySQLのトランザクションは、主に大規模なデータ操作、プロセスの高い複雑のために使用されています。たとえば、人事管理システムでは、あなたはスタッフの基本的な情報を削除する必要があり、データベース操作文は、トランザクションを構成するように、スタッフは、などのメール、記事、などの関連情報を、削除する必要があり、つまり、人を削除します!

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
事务用来管理 insert, update, delete 语句

3.1構文

MySQLはSET AUTOCOMMITでローカルトランザクションをサポートし、トランザクションを開始し、COMMIT、およびROLLBACK文、次のように具体的な構文は次のとおりです。

START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] | ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] 
SET AUTOCOMMIT = {0 | 1}

デフォルトでは、MySQLは自動的に(自動コミット)に提出され、明示的なコミットとロールバックによってトランザクションをコミットし、ロールバックするために必要な、あなたは異なる大幅にOracleのトランザクション管理であると明示的なトランザクションを介して、トランザクション制御コマンドを起動する必要がある場合場所。

START TRANSACTION 或 BEGIN 语句可以开始一项新的事务。
COMMIT 用来提交事务。
ROLLBACK 用来回滚事务。
CHAIN 子句用来定义在事务提交之后的操作, CHAIN 会立即启动一个新事物,并且和刚才的事务具有相同的隔离级别。
RELEASE 子句用来定义在事务回滚之后的操作, RELEASE 会断开和客户端的连接。
SET AUTOCOMMIT 可以修改当前连接的提交方式,如果设置了 SET AUTOCOMMIT=0, 则设置之后的所有事务都需要通过明确的命令进行提交或者回滚,即禁止自动提交。

3.2点SAVEPOINT予約

在事务中可以通过定义 SAVEPOINT,指定回滚事务的一个部分,但是不能指定提交事务的一个部分。
需要注意的是,如果定义了相同名字的 SAVEPOINT,则后面定义的 SAVEPOINT 会覆盖之前的定义。
对于不再需要使用的 SAVEPOINT, 可以通过 RELEASE SAVEPOINT 命令删除 SAVEPOINT,删除后的 SAVEPOINT,不能再执行 ROLLBACK TO SAVEPOINT 命令。

3.3トランザクションが満たされなければならない4つの条件(酸)です。

A:Atomic,原子性,一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即 A 账户只要减去了 100,B 账户则必定加上了100;
I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

3.4分離レベル

1. Read Uncommitted 读未提交:在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
2. Read Committed 读已提交:这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
3. Repeatable Read 可重读:这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
4. Serializable 可串行化:这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
如果没有指定隔离级别,数据库就会使用默认的隔离级别。在 MySQL 中,如果使用 InnoDB,默认的隔离级别是 Repeatable Read。

4つの分離レベルは、同じデータが読み出される場合、それは問題を起こしやすい、ロックの異なるタイプが達成される取ります。例えば:

1. 脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个 RollBack 了操作,则后一个事务所读取的数据就会是不正确的。
2. 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
3. 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

MySQLでは、これら四つの分離レベルの実現、次のような問題を引き起こす可能性があります:

分離レベル ダーティー読み取り 非反復可能読み取り マジック読書
コミットされていないが、非コミット読み取り読みます
コミットコミット読み取りを読みます
反復可能読み取りは、再読み込みすることができます
シリアライズ可能な直列化

以下を使用

begin; -- 开始事务
set autocommit = 0; -- 禁止自动提交
insert into tablename values(10, "trent1"); -- 预操作数据
savepoint savepointname;  -- 定义一个标记/保留点,如果回滚就先回滚到这
insert into tablename values(11, "trent2");  -- 预操作数据 insert/update/delete
rollback to savepoint savepointname;  -- 回滚到定义 savepointname 处
release savepoint savepointname;  -- 删除标记
rollback;  -- 回滚数据,即取消
rollback and release;  -- 回滚数据,并断开连接
commit; -- 提交事务
commit and chain; -- 提交后又自动开始一个新的事务,之前操作的数据依然无效,等待 commit. 一般少使用

おすすめ

転載: www.cnblogs.com/trent-fzq/p/11072051.html