Advanced mysql - keys, stored procedures, transactions (Innodb)

1. Key

1.1 Primary Key

Complete primary key (PRIMARY KEY) is called the primary key constraint. MySql primary key constraint is a column or combination of columns whose values ​​uniquely identify each row in the table. Such one or more columns called the primary key for the table, it can be forced through the table entity integrity.

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

Examples of use

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) -- 创建表时设置主键
)

Primary key violation

In the data inserted, assuming a value corresponding to the primary key already exists, it will cause insert failure. When (Duplicate key) primary key conflict, may be selectively processed, to update and replace.

insert into table [field list: A primary key] value (value list) on duplicate key update field = the new value

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

1.2 foreign key

Foreign key constraint (FOREIGN KEY) is used between two data tables to establish a link, or it may be a plurality of rows. A table may have one or more foreign keys.

Corresponds to a foreign key referential integrity, a foreign key table may be null, if not a null value, the value of each foreign key value must be equal to a primary key of another table. A foreign key is a field in the table, this is not the primary key of the table, but the corresponding primary key of another table. Define a foreign key, not allowed to delete rows in another table in an associated relationship. The main role of the foreign key is to maintain data consistency, integrity.

Examples of use

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 Index

In MySQL, an index (index) also called key (key), which is a data structure storage engine used to quickly find the record. The system according to some algorithm, create a separate index data of a document file can be fast matching data, and records the correspondence table can be quickly found.

1.3.1 index features

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

1.3.2 Classification Index

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

1.3.3 index type: BTREE and HASH

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

HASH index there are some important features require special attention when in use

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

Design principles 1.3.4 Index

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

Creating an index

Index can be created at the same time when you create a table, you can also add a new index at any time. Create a new index syntax is:

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

Use the following

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. Stored Procedures

2.1 Functions

The piece of code to a package structure, the structure can be performed when the call to be performed.

2.1.1 Variables

System variables: the system-defined variable, such autocommit like. But will not use the system variables in general.

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

Custom variables: user-defined variables

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

2.1.2 Loops

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

2.1.3 Functions

Custom system functions can be directly used to use.

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;  -- 删除函数

Use parameters

When the definition of parameters called parameter, parameter called arguments when calling. You must specify the data type parameter.

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 Stored Procedures

Stored procedure (Stored Procedure) storing a database object is a complex procedure in the database, so that the external program calls.

A stored procedure is set to an SQL statement to complete a specific function, created and saved in a database compiled, users can specify the name of the stored procedure and the given parameters (if necessary) to invoke the execution. In order to reuse the code package.

2.2.1 advantage

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

2.2.2 shortcomings

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

No parameters stored procedure

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 Parameters

Function parameters need to specify the type of data, the process is more stringent than the function, the process also has its own defined type:

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

Use the following

-- 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. Transaction

MySQL transaction is mainly used for large data manipulation, high complexity of the process. For example, in personnel management system, you delete a person, that is, you need to remove the basic information of the staff, and the staff have to delete related information, such as mail, articles, etc., so that the database operation statement constitutes a transaction !

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

3.1 Syntax

MySQL supports local transactions by SET AUTOCOMMIT, START TRANSACTION, COMMIT, and ROLLBACK statements, the specific syntax is as follows.

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

By default, MySQL is automatically submitted (Autocommit), if required to commit and rollback transactions through explicit Commit and Rollback, you need to start transaction control commands through an explicit transaction, which is Oracle's transaction management and significantly different local.

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

3.2 points SAVEPOINT reserved

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

3.3 Transactions are four conditions that must be met (ACID):

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

3.4 Isolation Level

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。

The four isolation levels to take a different type of lock is achieved, if the same data is read, then it is prone to problems. E.g:

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

In MySQL, the realization of these four isolation levels, are likely to cause problems as follows:

Isolation Levels Dirty read Non-repeatable read Magic Reading
Read Uncommitted read Uncommitted
Read Committed Read Committed
Repeatable Read can be re-read
Serializable serializable

Use the following

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. 一般少使用

Guess you like

Origin www.cnblogs.com/trent-fzq/p/11072051.html