고급 MySQL의 - 키, 저장 프로 시저, 트랜잭션 (이노 디비)

1. 키

1.1 기본 키

전체 기본 키 (PRIMARY KEY) 기본 키 제약 조건이라고합니다. MySQL의 기본 키 제약은 고유 값 테이블의 각 행을 식별 열의 열 또는 조합이다. 하나 이상의 열이 테이블의 기본 키,이 테이블 엔티티 무결성을 강제 할 수 있습니다했다.

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) 링크를 설정하기 위해 두 개의 데이터 테이블 사이에 사용되는, 또는 복수 열 수 있습니다. 테이블은 하나 이상의 외부 키가있을 수 있습니다.

하지 null 값이 각각 외부 키 값의 값이 다른 테이블의 기본 키와 동일해야하는 경우 외부 참조 무결성 키에 대응하고, 외부 키 테이블은 널 (null) 일 수있다. 외부 키는이 테이블의 기본 키이지만 다른 테이블의 대응하는 기본 키가 아닌 테이블의 필드이다. 하지 연관된 관계에있는 다른 테이블의 행을 삭제할 수 외부 키를 정의합니다. 외부 키의 주요 역할은 무결성을 데이터 일관성을 유지하는 것입니다.

사용 예

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 索引,基于哈希表实现的,只有精确匹配索引所有列的查询才有效。

해시 인덱스 사용시 몇 가지 중요한 기능은 특별한주의를 필요가있다

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은 COMMIT, 트랜잭션을 시작, SET AUTOCOMMIT에 의해 로컬 트랜잭션을 지원하며, 다음과 같이 ROLLBACK 문은 특정 구문입니다.

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

커밋 명시 통해 롤백 트랜잭션이 커밋 및 롤백하는 데 필요한 경우 기본적으로 MySQL은 자동으로 (자동 커밋) 제출, 당신은 오라클의 트랜잭션 관리와 큰 차이가 명시 적 트랜잭션을 통해 트랜잭션 제어 명령을 시작해야 장소.

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

SAVEPOINT 소유 3.2 점

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

3.3 트랜잭션이 충족되어야합니다 네 가지 조건 (ACID)이다 :

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。

네 개의 분리 레벨은 동일한 데이터가 판독되는 경우, 다음 문제가되기 쉽다 잠금 다른 유형이 달성 취한다. 예를 들면 :

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