MySQL 数据库开发与优化--开发篇

内容:

1.SQL查询

2.选择合适的引擎

3.合理的数据类型

4.选择合适的存储引擎

5.全球化特征--字符集

6.事务及隔离级别

7.存储过程与函数

8.触发器与视图

Sql查询:

DDL:

数据结构定义语言

扫描二维码关注公众号,回复: 3554399 查看本文章

create table ,alter table ,create index....

DCL:

数据控制语言:

:grant,reovke,...

DML:

数据操纵语言

Insert,delete,update,select(严格意义上属于DQL)

TCL

事务控制语言

如:start transcation,commit,rollback,set transcation level read commited

数据结构定义语言:

创建数据库:

https://dev.mysql.com/doc/refman/5.7/en/create-database.html

CREATE DATABASE语法

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] 

db_name [create_specification] ... 

create_specification:

[DEFAULT] CHARACTER SET [=] charset_name | 

[DEFAULT] COLLATE [=] collation_name

CREATE DATABASE用给定的名字创建一个数据库。 要使用此语句,您需要数据库的CREATE特权。

CREATE SCHEMACREATE DATABASE的同义词。

如果数据库存在并且您没有指定IF NOT EXISTS,则会发生错误。

具有活动的LOCK TABLES语句的会话中不允许CREATE DATABASE

create_specification选项指定数据库特征。 数据库特征存储在数据库目录的db.opt文件中。 CHARACTER SET子句指定默认的数据库字符集。 COLLATE子句指定默认的数据库排序规则。 第10章,字符集,排序规则,Unicode讨论了字符集和排序规则名称。见这个地址:https://dev.mysql.com/doc/refman/5.7/en/charset.html

MySQL中的数据库被实现为包含与数据库中的表相对应的文件的目录。 由于数据库最初创建时没有表,因此CREATE DATABASE语句只会在MySQL数据目录和db.opt文件下创建一个目录。

允许数据库名称的规则在第9.2节“模式对象名称”中给出。关键字约束

如果在数据目录(例如,使用mkdir)下手动创建目录,则服务器将其视为数据库目录,并显示在SHOW DATABASES的输出中。

也可以使用msyqladmin创建数据库:

数据定义语句

切换数据库:

use demodb;
查看当前数据库 :

select database();
修改数据库:
ALTER {DATABASE | SCHEMA} [db_name]
alter_specification ...
ALTER {DATABASE | SCHEMA} db_name
UPGRADE DATA DIRECTORY NAME
alter_specification:
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
删除数据库:drop database demodb;

数据结构定义语言 -- 表:

创建表对象: create table table_name(col1 datatype ,col2 datatype,..)
修改表:alter table add column col3 varchar(20);
删除表:drop table table_name;
重命名表: rename table old_name to new_name;
克隆表:http://blog.csdn.net/leshami/article/details/46800847
create table new_table like old_table;
insert into new_table select * from old_table;(插入前new_table应存在)
create table new_table as select * from old_table;

数据结构定义语言 -- 约束(建表前)

约束主要完成对数据的校验,保证数据库数据的完整性;如果有相互依赖数据,保证该数据不被删除

非空约束NOT NULL,指定的列不允许为空值
唯一约束UNIQUE,指定的列中没有重复值,或该表中每一个值或者每一组值都将是唯一的
CHECK:条件约束,指定该列是否满足某个条件
主键约束PRIMARY KEY,唯一的标识出表的每一行,且不允许空值值,一个表只能有一个主键约束
外键约束FOREIGN KEY,一个表中的列引用了其它表中的列,使得存在依赖关系,可以指向引用自身的列 reference13.1.17.2.
CREATE TABLE person
(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY(id)
);


CREATE TABLE shirt
(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20) UNIQUE,
style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
size tinyint check(size>36),
owner SMALLINT UNSIGNED NOT NULL REFERENCES
person(id) ON DELETE CASCADE
);

 

数据结构定义语言 -- 约束(建表后)

mysql> CREATE TABLE s --建表
-> (
-> id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
-> name CHAR(60) NOT NULL,
-> PRIMARY KEY(id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE TABLE t --建表
-> (
-> id int ,
-> name varchar(20) ,
-> style ENUM('t-shirt', 'polo', 'dress') ,
-> size tinyint ,
-> owner SMALLINT UNSIGNED
-> );
Query OK, 0 rows affected (0.03 sec)
--添加非空约束
mysql> alter table t modify name varchar(20) not null;
--添加唯一约束
mysql> alter table t modify name varchar(20) unique;
mysql> alter table t add constraint unique(name);
--添加主键约束
mysql> alter table t add primary key(id);
--添加自增列
mysql> alter table t modify id int auto_increment;
--添加check约束
mysql> alter table t add check (size>30);
--添加外键约束
mysql> alter table t add foreign key(owner) references s(id);

数据控制语言 -- DCL

权限授权grant
需要指定授予哪些权限
权限应用在那些对象上(全局,特定对象等)
ON *.*
ON db_name.*
ON db_name.table_name
ON db_name.table_name.column_name
ON db_name.routine_name
 授予给哪个帐户
 可以指定密码(可选项,用此方式会自动创建用户)
 权限回收revoke
 有哪些权限可以授予,相应地就有哪些权限可以撤销
 原来的to子句则变成from子句
 参考:http://blog.csdn.net/leshami/article/details/39805285

SQL 简单查询:

查询语法链接: http://dev.mysql.com/doc/refman/5.6/en/sql-syntax-data-manipulation.html

Mysql的示例数据库https://dev.mysql.com/doc/index-other.html
基本样式
select * from table_name where col=A’…
统计表上记录数
select count(*) from sakila.actor;
select count(actor_id) from sakila.actor;
滤重统计(distinct)
select count(distinct first_name) from sakila.actor;
限制查询的结果列
select first_name,last_name from sakila.actor;
限制查询结果记录数及分页
select * from sakila.actor limit 3;
select * from sakila.actor limit 100,5;
排序结果集
select * from sakila.actor order by 2 desc limit 3;
记录筛选:
select * from sakila.actor where first_name like WOODY%;
select * from sakila.actor where actor_id in (1,3,5,7);
select * from sakila.actor where last_name=BERRY

SQL 子查询

子查询就是位于SELECTUPDATEDELETE语句中内部的查询
子查询分类
单行子查询,返回零行或一行
多行子查询,返回一行或多行
多列子查询,返回多列
相关子查询,引用外部SQL语句中的一列或多列
嵌套子查询,位于其它子查询中的查询


子查询(内部查询)在执行主查询之前执行一次,然后主查询(外部查询)会使用该子查询的结果
子查询语法
SELECT select_list
FROM table
WHERE expr operator
(SELECT select_list
FROM table);
参考链接:http://blog.csdn.net/leshami/article/details/5592002

SQL 表连接查询

语法:注mysql 不支持oracle(+)
join_table:
table_reference [INNER | CROSS] JOIN table_factor [join_condition]
| table_reference STRAIGHT_JOIN table_factor
| table_reference STRAIGHT_JOIN table_factor ON conditional_expr
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor
join_condition:
ON conditional_expr
| USING (column_list)
内连接:inner join
只连接匹配的行
左外连接:left outer join
包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
右外连接:right outer join
包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
全外连接:natural outer join
包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。
交叉连接(笛卡尔连接)cross join
不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配
参考链接:http://blog.csdn.net/leshami/article/details/5563199

数据操纵语言 -- DML

Insert语法
INSERT [LOW_PRIORITY | DELAYED |
HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
{VALUES | VALUE} ({expr |
DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
注意事项
数值类型的值不需要用单引号括起来
字符和日期类型数据需要用单引号括起来
输入值的顺序必须与表中定义的顺序或者在表后列出的顺序相同
MySQL语法扩展
可以在insert一条语句里插入多行值
--多行值insert
mysql> insert into country(country) values('IsIs'), ('New_country');
mysql> select * from country where country='IsIs';
+------------+---------+---------------------+
| country_id | country | last_update |
+------------+---------+---------------------+
| 111 | IsIs | 2015-07-09 09:28:52 |
+------------+---------+---------------------+
--单行值insert
mysql> insert into city(city,country_id)  values('Baghdad',111);
mysql> select l.country,m.city from country l inner join city m on l.country_id=m.country_id
where l.country='IsIs';
+---------+---------+
| country | city |
+---------+---------+
| IsIs | Baghdad |
+---------+---------+

数据操纵语言 -- DML

Delete语法
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[PARTITION (partition_name,...)]
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
Multiple-table syntax:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
tbl_name[.*] [, tbl_name[.*]] ...
FROM table_references
[WHERE where_condition]
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
FROM tbl_name[.*] [, tbl_name[.*]] ...
USING table_references
[WHERE where_condition]
提示
可以同时进行多表删除,OracleSQL server不支持
多表删除时语法1 from子句之前的表记录会被删除
多表删除时语法2 fom之后,using之前的表记录会被删除
删除表上最后一条记录
mysql> delete from country order by country_id desc limit 1;
下面的语句删除表city上且在country表国家名为'New Iraq'记录
mysql> delete m from country l,city m
-> where l.country_id=m.country_id
-> and l.country='New Iraq';
Query OK, 1 row affected (0.00 sec)
--多表删除,如下提示违反外键约束
mysql> delete l,m from city l,country m
-> where l.country_id=m.country_id
-> and m.country='China';
ERROR 1451 (23000): Cannot delete or update a parent row:
a foreign key constraint fails (`sakila`.`city`, CONSTRAINT
`fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `country`
(`country_id`) ON UPDATE CASCADE)
--临时修改参数
mysql> set foreign_key_checks = 0;
mysql> delete l,m from city l,country m
-> where l.country_id=m.country_id and m.country='China';
Query OK, 54 rows affected (0.00 sec)
--第二种写法
mysql> delete from city,country
-> using city inner join country
-> on city.country_id=country.country_id
-> and country.country='Iraq';
Query OK, 2 rows affected (0.00 sec)
mysql> set foreign_key_checks = 1; 

存储引擎概述

Storage engines are MySQL components that handle the SQL operations for different table types. InnoDB is the most general-purpose storage engine, and Oracle recommends using it for tables except for specialized use cases. (The CREATE TABLE statement in MySQL 5.6 creates InnoDB tables by default.)
 MySQL Server uses a pluggable storage engine architecture that enables storage
engines to be loaded into and unloaded from a running MySQL server.
To determine which storage engines your server supports, use the SHOW ENGINES statement. The value in the Support column indicates whether an engine can be used. A value of YES, NO, or DEFAULT indicates that an engine is available, not available, or available and currently set as the default storage engine.

设置或修改引擎

编译安装时指定:WITHOUT_xxx_STORAGE_ENG
http://dev.mysql.com/doc/refman/5.6/en/source-installation.html
mysqld启动时指定缺省存储引擎
--default-storage-enginemy.cnf(my.ini)设置default-storage-engine
Session级别修改缺省存储引擎
SET default_storage_engine=NDBCLUSTER
建表时指定engine表选项
 ENGINE=INNODB not needed unless you have set a different default storage engine.
CREATE TABLE t1 (i INT) ENGINE = INNODB;
-- Simple table definitions can be switched from one to another.
CREATE TABLE t2 (i INT) ENGINE = CSV;
建表后修改存储引擎
ALTER TABLE t2 ENGINE = InnoDB;
临时表存储引擎可单独设置
设置参数default_tmp_storage_engine或在启动时指定

Innodb存储引擎支持的能力

MyISAM存储引擎支持的能力

 

Memory存储引擎支持的能力  

选择合适的存储引擎

总原则:除非需要用到某些InnoDB不具备的特性,且无法替代,否则都应该优先选择InnoDB引擎

1. InnoDB,使用于高并发,对数据完整性要求较高(事务,外键),支持崩溃恢复等等如计费或财务系统,订单数据等。

2. MyISAM,适用于以插入或读取操作为主,对事务完整性,并发要求不高,比如日志型应用,如果要对日志做报表分析,建议分时段或基于复制库完成

3. Memory,频繁访问,较少变化,且表大小不是太大的表建议采用memory引擎,缺陷是过大的表导致内存开销过大。

4. 尽可能少的使用混合存储引擎,否则增加潜在Bug以及边界问题风险,其次备份恢复,管理维护都比较麻烦。

5. 大数据存储,对于TB及以上的情形,需要考虑使用数据仓库如Infobright或者TokuDB或者gp引擎等。

合理化数据类型

合理化数据类型准则 

前提:选择合理的存储引擎

先确定类型,再确定长度

更小的通常更好

在确定没有低估需要存储数值的前提下,更小的数据类型通常更快,因为他们占用更小的磁盘,内存以及更CPU处理周期。

简单就好

简单数据类型通常需要更少的CPU周期,如使用整型代替字符型;使用日期时间型存储日期时间,而不是字符型;使用整型代替字符型存储IP地址(借助INET_ATON 以及INET_NTOA函数实现)

尽量避免NULL

NULL值列使用索引,索引统计和值都比较复杂以及导致索引失效等情形,尽可能的指定缺省值(default),除非正的需要NULL值。

不同引擎下的数据类型选择差异

MyISAM 数据存储引擎和数据列
MyISAM数据表,最好使用固定长度的数据列代替可变长度的数据列。
MEMORY存储引擎和数据列
MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHARVARCHAR列都没有关系。两者都是作为CHAR类型处理的。
InnoDB 存储引擎和数据列
建议使用 VARCHAR类型
对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的 CHAR列不一定比使用可变长度VARCHAR列简单。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因 此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

MySQL索引概述  

MySQL中,索引(key)是位于存储引擎级别,用于快速定位特定记录的一种数据结构。少而精的高效索引能极大程度地提升性能,反之,低效或冗余的索引随着数据量的增大会降低系统性能。

索引的类型(按物理结构划分)

B-Tree索引,从根节点到叶子节点的高度一致,各叶子节点采用双向链表连接

哈希索引,基于哈希表实现,只有精确匹配索引所有列的查询在有效

空间数据索引,用于MyISAM引擎,可以用作地理数据存储

全文索引,是一种特殊类型索引,通过词干的方式进行匹配,而不是直接比较索引中的值其他类型索引,如TokuDB使用分属性索引等

索引的优缺点

索引的优点
大大减少了服务器需要扫描的数据量
可以帮助服务器避免排序或减少使用临时表排序
索引可以将随机I/O变为顺序I/O
索引的缺点
需要占用磁盘空间,因此冗余低效的索引将占用大量的磁盘空间
降低DML性能,对于数据的任意增删改都需要调整对应的索引,甚至出现索引分裂索引

会产生相应的碎片,产生维护开销

索引类型(按用途非严格划分)

普通索引,这是最基本的索引,无任何限制
唯一索引,与普通索引类似,索引列值必须唯一,允许NULL
全文索引,基于词干方式创建索引,多用于BLOB数据类型
单列索引,仅基于一列创建的索引
多列索引,基于多列创建的索引,列顺序非常重要
空间索引,用作地理数据存储
主键索引,是一种特殊的唯一索引,不允许有NULL值,通常在建表时创建

索引构建步骤

预估及收集正在使用的所有数据读取类型
寻找能够满足所有读取要求的比较理想的索引或索引组合
创建相应索引
选择性与基数
选择性是一个介于01之间的值,代表被一个操作过虑的记录的比例。
一个操作所返回的记录条数称为基数。
cardinality = selectivity * num_rows
其中num_rows为被处理的记录数
索引列(含组合索引)的选择顺序:
频繁使用的列 1) c1(=),c2(between),c3(=)
经常使用等值运算的列 2) c2(=),c3(between),c4(>)
具有更好选择性的列 3) c1(=),c2(=),c3(like)
经常按何种方式排序 4) c1(=),c2(=),c4(>)

索引构建--建表时

语法格式

CREATE TABLE [IF NOT EXISTS] tbl_name

[ ( [column_definition] , ... | [index_definition] ) ]

其中,index_definition为索引项:

PRIMARY KEY (index_col_name,...) /*主键*/

| {INDEX | KEY} [index_name] (index_col_name,...) /*索引*/

| UNIQUE [INDEX] [index_name] (index_col_name,...) /*唯一性索引*/

| [FULLTEXT] [INDEX] [index_name] (index_col_name,...) /*全文索引*/

说明:KEY通常是INDEX的同义词。在定义列选项的时候,也可以将某列定义为

PRIMARY KEY,但是当主键是由多个列组成的多列索引时,定义列时无法定义此

主键,必须在语句最后加上一个PRIMARY KEYcol_name)子句。

构建索引--使用create index

语法格式:

CREATE [UNIQUE | FULLTEXT] INDEX index_name

ON tbl_name (index_col_name,...)

其中,index_col_name格式为:col_name [(length)] [ASC | DESC]

说明:

index_name:索引的名称,索引在一个表中名称必须是唯一的。

index_col_namecol_name表示创建索引的列名。

length表示使用列的前length个字符创建索引。使用列的一部分创建索引可以使索引文件大大减小,从而

节省磁盘空间。在某些情况下,只能对列的前缀进行索引。例如,索引列的长度有一个最大上限,因此,如果索

引列的长度超过了这个上限,那么就可能需要利用前缀进行索引。BLOBTEXT列必须用前缀索引。

另外还可以规定索引按升序(ASC)还是降序(DESC)排列,默认为ASC。如果一条SELECT语句中的某

列按照降序排列,那么在该列上定义一个降序索引可以加快处理速度。

UNIQUE | FULLTEXT UNIQUE表示创建的是唯一性索引;FULLTEXT表示创建全文索引;

可以看出,CREATE INDEX语句并不能创建主键。

构建索引--使用alter table

语法:

ALTER TABLE tbl_name

ADD INDEX [index_name] (index_col_name,...) /*添加索引*/

| ADD PRIMARY KEY [index_type] (index_col_name,...) /*添加主键*/

| ADD UNIQUE [index_name] (index_col_name,...) /*添加唯一性 索引*/

| ADD FULLTEXT [index_name] (index_col_name,...) /*添加全文索引*/

q 示例:

drop table if exists shirt;

CREATE TABLE shirt (

id INT ,

name VARCHAR(20) not null,

style ENUM('t-shirt', 'polo', 'dress') NOT NULL,

size TINYINT,

owner SMALLINT UNSIGNED NOT NULL);

alter table shirt add constraint pk_shirt primary key (id);

alter table shirt add index(size);

alter table shirt add unique index(name);

alter table shirt add foreign key(owner) references person(id);

-- show index from person \G

-- show index from shirt \G

删除索引

语法:

ALTER TABLE tbl_name

ADD INDEX [index_name] (index_col_name,...) /*添加索引*/

| ADD PRIMARY KEY [index_type] (index_col_name,...) /*添加主键*/

| ADD UNIQUE [index_name] (index_col_name,...) /*添加唯一性 索引*/

| ADD FULLTEXT [index_name] (index_col_name,...) /*添加全文索引*/

示例:

drop table if exists shirt;

CREATE TABLE shirt (

id INT ,

name VARCHAR(20) not null,

style ENUM('t-shirt', 'polo', 'dress') NOT NULL,

size TINYINT,

owner SMALLINT UNSIGNED NOT NULL);

alter table shirt add constraint pk_shirt primary key (id);

alter table shirt add index(size);

alter table shirt add unique index(name);

alter table shirt add foreign key(owner) references person(id);

-- show index from person \G

-- show index from shirt \G

使用DROP INDEX语句删除索引

语法格式:DROP INDEX index_name ON tbl_name

drop index idx_shirt_name on shirt;

使用ALTER TABLE语句删除索引

语法格式:

ALTER [IGNORE] TABLE tbl_name

| DROP PRIMARY KEY /*删除主键*/

| DROP INDEX index_name /*删除索引*/

其中,DROP INDEX子句可以删除各种类型的索引。使用DROP

PRIMARY KEY子句时不需要提供索引名称,因为一个表中只有一个主键。

alter table shirt drop primary key,drop index size;

索引失效的情形

请求表上的数据行超出表总记录数30%,变成全表扫描

谓词上的索引列上存在NULL

谓词上的索引列条件使用函数

谓词上的索引列条件进行了相关运算

谓词上的索引列条件上使用了<>NOT IN 操作符

复合索引中,第一个索引列使用范围查询 -- 只能用到部分或无法使用索引

复合索引中,第一个查询条件不是最左索引列

模糊查询条件列最左以通配符 % 开始

内存表(HEAP )使用HASH索引时,使用范围检索或者ORDER BY

表关联字段类型不一样(包括某些长度不一样,但像varchar(10)char(10)则可以,MySQL经过内部优化处理)

全球化特性--字符集

A character set is a set of symbols and encodings. A collation is a set of rules
for comparing characters in a character set.
Suppose that we have an alphabet with four letters: “A”, “B”, “a”, “b”. We
give each letter a number: “A”= 0, “B” = 1, “a” = 2, “b” = 3. The letter
“A” is a symbol, the number 0 is the encoding for “A”, and the combination
of all four letters and their encodings is a character set.
Suppose that we want to compare two string values, “A” and “B”. The
simplest way to do this is to look at the encodings: 0 for “A” and 1 for “B”.
Because 0 is less than 1, we say “A” is less than “B”. What we've just done is
apply a collation to our character set. The collation is a set of rules (only one rule
in this case): “compare the encodings.” We call this simplest of all possible
collations a binary collation.
But what if we want to say that the lowercase and uppercase letters are
equivalent? Then we would have at least two rules: (1) treat the lowercase letters
“a” and “b” as equivalent to “A” and “B”; (2) then compare the
encodings. We call this a case-insensitive collation. It is a little more complex
than a binary collation.

MySQL字符集

MySQL includes character set support that enables you to store data using a variety of character sets and perform comparisons according to a variety of collations. You can specify character sets at the server,database, table, and column level. MySQL supports the use of character sets for the MyISAM,MEMORY, and InnoDB storage engines. Character set issues affect not only data storage, but also communication between client programs and the MySQL server. If you want the client
program to communicate with the server using a character set different from the default, you'll need to indicate which one. For example, to use the utf8 Unicode character set, issue this statement after connecting to the server: SET NAMES 'utf8' ;
MySQL can do these things for you:
Store strings using a variety of character sets.
Compare strings using a variety of collations.
Mix strings with different character sets or collations in the same server, the same
database, or even the same table.
Enable specification of character set and collation at any level.
q list the available character sets and collation
SHOW CHARACTER SET; SHOW COLLATION LIKE 'latin1%';

MySQL字符集层级图

MySQL Server收到请求时将请求
数据从character_set_client转换为character_set_connection
进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:
使用每个列上的CHARACTER SET
否则使用表上的CHARACTER SET
否则使用DBCHARACTER SET
否则使用server级别的
CHARACTER SET
将交互结果转换为
character_set_results

设定MySQL字符集

 编译安装时可以指定字符集,如DEFAULT_CHARSET=utf8DEFAULT_COLLATION=utf8_general_ci (Ref: 10.1.3.1)

 启动时指定字符集(my.cnf或者my.ini)[mysqld]下添加:defaultcharacter-set=utf8

 建库是设定字符集(Ref: 10.1.3.2)

 建表时设定字符集(Ref: 10.1.3.3)

 建表时列上设定字符集(Ref: 10.1.3.4)

 文本字符串字符集(Ref: 10.1.3.5)

 参数查看show variables like ‘%char%’| ‘%colla%’

MySQL中字符集变量

与字符集相关的系统变量
character_set_server:默认的服务器操作字符集
character_set_client:客户端来源数据使用的字符集
character_set_connection:连接层字符集
character_set_results:查询结果字符集
character_set_database:当前选中数据库的默认字符集
character_set_system:系统元数据(字段名等)字符集
与校对规则相关的系统变量
collation_connection:连接字符集的排序规则
collation_database:数据库字符集的排序规则
collation_server:服务器字符集的排序规则

MySQL连接字符集与排序规则:

 

SET NAMES 'charset_name' [COLLATE 'collation_name']

SET NAMES indicates what character set the client will use to send SQL statements to the server. Thus, SET NAMES 'cp1251' tells the server, “future incoming messages from this client are in character set cp1251.” It also specifies the character set that the server should use for sending results back to the client. (For example, it indicates what character set to use for column values if you use a SELECT statement.)

SET NAMES 'charset_name' statement is equivalent to these three statements:

SET character_set_client = charset_name;

SET character_set_results = charset_name;

SET character_set_connection = charset_name;

SET CHARACTER SET charset_name

SET CHARACTER SET is similar to SET NAMES but sets character_set_connection and collation_connection to character_set_database and collation_database .

SET CHARACTER SET charset_name statement is equivalent to these three statements:

SET character_set_client = charset_name;

SET character_set_results = charset_name;

SET collation_connection = @@collation_database;

 

事务及其隔离级别

事务的由来

银行应用程序是为什么交易是必要的典型例子。 想象一下银行的数据库有两个表格:检查和储蓄。 要将Jane的支票账户中的200美元移动到她的储蓄账户,您至少需要执行三个步骤:

1.确保她的支票账户余额大于$ 200

2.从支票帐户余额中扣除$ 200

3.200美元到她的储蓄账户余额。

使用START TRANSACTION语句启动事务,然后使用COMMIT使其更改保持永久,或使用ROLLBACK丢弃更改。 所以,我们的示例事务的SQL可能如下所示:

 

START TRANSACTION;
SELECT balance FROM checking WHERE customer_id = 10233276;
UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;
COMMIT;

事务的特性 :

事务的特征(ACID)
原子性(Atomiocity)、一致性(Consistency)、隔离性(Isolation) 和持久性(Durability)
原子性
事务是数据库的逻辑工作单位,事务中包括的所有操作要么都做,要么都不做。
一致性
事务执行的结果必须是使数据库从一个一致性的状态变到另外一个一致性状态。
隔离性
一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对其他
事务是隔离的,并发执行的各个事务之间互相不干扰。
持久性
一个事务一旦成功提交,对数据库中数据的修改就是持久性的。接下来其他 操作或
故障不应该对其执行结果有任何影响。

事务的相关用法(1) 

语法:

START TRANSACTION

[transaction_characteristic [, transaction_characteristic] ...]

transaction_characteristic:

WITH CONSISTENT SNAPSHOT --等同于与start transaction

| READ WRITE

| READ ONLY

BEGIN [WORK] --编写DML语句

COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] --提交事务

ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] --回滚事务

SET autocommit = {0 | 1}

START TRANSACTION or BEGIN start a new transaction.

COMMIT commits the current transaction, making its changes

permanent.

ROLLBACK rolls back the current transaction, canceling its changes.

SET autocommit disables or enables the default autocommit mode

for the current session.

By default, MySQL runs with autocommit mode enabled. This means that as soon as you execute a

statement that updates (modifies) a table, MySQL stores the update on disk to make it permanent. The

change cannot be rolled back.

事务的相关用法(2)

事务开启,使用START TRANSACTION语句:

START TRANSACTION;

SELECT @A:=SUM(salary) FROM table1 WHERE type=1;

UPDATE table2 SET summary=@A WHERE type=1;

COMMIT;

BEGINBEGIN END

The BEGIN statement differs from the use of the BEGIN keyword that starts a

BEGIN ... END compound statement. The latter does not begin a transaction.

Within all stored programs (stored procedures and functions, triggers, and

events), the parser treats BEGIN [WORK] as the beginning of a BEGIN ...

END block. Begin a transaction in this context with START TRANSACTION

instead.

事务回滚rollback

事务提交commit

事务---隐式提交

Data definition language (DDL) statements that define or modify

database objects

ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME, ALTER EVENT, ALTER PROCEDURE, ALTER SERVER, ALTER TABLE,

ALTER VIEW, CREATE DATABASE, CREATE EVENT, CREATE INDEX,CREATE PROCEDURE, CREATE SERVER, CREATE TABLE,

CREATE TRIGGER, CREATE VIEW,DROP DATABASE, DROP EVENT, DROP INDEX, DROP PROCEDURE, DROP SERVER, DROP

TABLE, DROP TRIGGER, DROP VIEW, RENAME TABLE, TRUNCATE TABLE

Statements that implicitly use or modify tables in the mysql

database.

CREATE USER, DROP USER, GRANT, RENAME USER, REVOKE, SET PASSWORD.

Transaction-control and locking statements.

BEGIN, LOCK TABLES, SET autocommit = 1 START TRANSACTION, UNLOCK TABLES.

Data loading statements.

LOAD DATA INFILE

Administrative statements.

ANALYZE TABLE, CACHE INDEX, CHECK TABLE, LOAD INDEX INTO CACHE, OPTIMIZE TABLE, REPAIR TABLE.

Replication control statements.

START SLAVE, STOP SLAVE,RESET SLAVE, CHANGE MASTER TO

 

事务---保存点

语法:

SAVEPOINT identifier

ROLLBACK [WORK] TO [SAVEPOINT] identifier

RELEASE SAVEPOINT identifier

引擎支持:InnoDB

The SAVEPOINT statement sets a named transaction savepoint with a name of identifier. If

the current transaction has a savepoint with the same name, the old savepoint is deleted

and a new one is set.

The ROLLBACK TO SAVEPOINT statement rolls back a transaction to the named savepoint

without terminating the transaction. Modifications that the current transaction made to

rows after the savepoint was set are undone in the rollback, but InnoDB does not release

the row locks that were stored in memory after the savepoint.

The RELEASE SAVEPOINT statement removes the named savepoint from the set of

savepoints of the current transaction. No commit or rollback occurs. It is an error if the

savepoint does not exist.

All savepoints of the current transaction are deleted if you execute a COMMIT, or a

ROLLBACK that does not name a savepoint.

参考链接:http://blog.csdn.net/leshami/article/details/5717020

事务隔离级别:

READ UNCOMMITED

SELECT的时候允许脏读,即SELECT会读取其他事务修改而还没有提交的数据。

READ COMMITED

SELECT的时候无法重复读,即同一个事务中两次执行同样的查询语句,若在第一次与第二次查询之间时间段,

其他事务又刚好修改了其查询的数据且提交了,则两次读到的数据不一致。

REPEATABLE READ

SELECT的时候可以重复读,即同一个事务中两次执行同样的查询语句,得到的数据始终都是一致的。

SERIALIZABLE

与可重复读的唯一区别是,默认把普通的SELECT语句改成SELECT . LOCK IN SHARE MODE。即为查询语句涉及到的数据加上共享琐,阻塞其他事务修改真实数据。

作用:不同(多个)事务在同一时间点操作相同数据时的处理规则,影响并发。

设置事务隔离级别(1)

语法:
SET [GLOBAL | SESSION] TRANSACTION
transaction_characteristic [,
transaction_characteristic] ...
transaction_characteristic:
ISOLATION LEVEL level
| READ WRITE
| READ ONLY
level:
REPEATABLE READ
| READ COMMITTED
| READ UNCOMMITTED
| SERIALIZABLE

作用范围:

With the GLOBAL keyword, the statement applies globally for all subsequent sessions.

Existing sessions are unaffected.

With the SESSION keyword, the statement applies to all subsequent transactions performed within the current session.

Without any SESSION or GLOBAL keyword, the statement applies to the next (not started) transaction performed within the current session.

The isolation level is used for operations on InnoDB tables.

Note: SET TRANSACTION without GLOBAL or SESSION is not permitted while there is an active transaction:

mysql> START TRANSACTION;

Query OK, 0 rows affected (0.02 sec)

mysql> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progress

设置事务隔离级别(2)

mysqld启动时指定隔离级别: --transaction-isolation=level

使用参数文件指定隔离级别:

[mysqld]

transaction-isolation = REPEATABLE-READ

运行时修改隔离级别:

SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

SET GLOBAL tx_isolation='REPEATABLE-READ';

SET SESSION tx_isolation='SERIALIZABLE';

设置事务隔离级别(3)

Session 1

Session 2

mysql> select @@global.tx_isolation;
REPEATABLE-READ
mysql> select @@session.tx_isolation;
REPEATABLE-READ

mysql> select @@global.tx_isolation;
REPEATABLE-READ
mysql> select @@session.tx_isolation;
REPEATABLE-READ

mysql> create table t(id int);
mysql> start transaction;
mysql> insert into t values(1);
mysql> select * from t;
1

mysql> select * from test.t;
Empty set (0.00 sec)

mysql> set session transaction isolation level read
uncommitted;
mysql> select * from test.t;
1 ---事务并没有提交,出现脏读

事务及隔离级别的相关建议

事务持续时间越短越好

事务期间避免与用户互动

查询数据期间,尽量不要启用事务

活用事务隔离级别和锁提示

尽可能使用缺省的隔离级别,如特殊情况,应基于session级别调整隔离级别

存储过程与函数

MySQL 复合语句---BEGINEND

It is used for writing compound statements which can appear within stored programs (stored procedures and functions, triggers, and events).

A compound statement can contain multiple statements, enclosed by the BEGIN and END keywords. statement_list represents a list of one or more statements, each terminated by a semicolon (;) statement delimiter. The statement_list itself is optional, so the empty compound statement (BEGIN END) is legal. end-of-statement delimiter (for example, to //)

BEGIN ... END blocks can be nested.

A BEGIN ... END block can be labeled.

MySQL --- 标签

语法:
[begin_label:] BEGIN
[statement_list]
END [end_label]
[begin_label:] LOOP
statement_list
END LOOP [end_label]
[begin_label:] REPEAT
statement_list
UNTIL search_condition
END REPEAT [end_label]
[begin_label:] WHILE search_condition DO
statement_list
END WHILE [end_label]
Labels are permitted for BEGIN ... END blocks
and for the LOOP, REPEAT, and WHILE statements.
使用规则:
begin_label must be followed by a colon.
begin_label can be given without end_label. If end_label is present, it must be the same as begin_label.
end_label cannot be given without begin_label.
Labels at the same nesting level must be distinct.
Labels can be up to 16 characters long.
To refer to a label within the labeled construct, use an ITERATE or LEAVE statement.

MySQL --- 变量声明(Declare)

Local variables

DECLARE var_name [, var_name] ... type [DEFAULT value]

Cursors

DECLARE cursor_name CURSOR FOR select_statement

Conditions and handlers

DECLARE condition_name CONDITION FOR condition_value

condition_value:

mysql_error_code

| SQLSTATE [VALUE] sqlstate_value

Notes:

DECLARE is permitted only inside a BEGIN ... END compound statement

and must be at its start, before any other statements.

Declarations must follow a certain order. Cursor declarations must appear

before handler declarations.Variable and condition declarations must

appear before cursor or handler declarations

MySQL --- 本地变量赋值与作用域

Syntax:

DECLARE var_name [, var_name] ... type [DEFAULT value]

Notes:

Variable declarations must appear before cursor or handler declarations.

Local variable names are not case sensitive.

The scope of a local variable is the BEGIN ... END block within which it is declared.

A local variable should not have the same name as a table column.

Assign values

[DEFAULT value]

SELECT ... INTO var_list

FETCH ... INTO var_list

Using set clause: set var=exp

MySQL --- 条件处理

Conditions may arise during stored program execution that require special handling, such as exiting the current program block or continuing execution. Handlers can be defined for general conditions such as warnings or exceptions, or for specific conditions such as a particular error code.

To name a condition, use the DECLARE ... CONDITION statement.

To declare a handler, use the DECLARE ... HANDLER statement.

Condition declarations must appear before cursor or handler declarations.

Handler declarations must appear after variable or condition declarations

MySQL --- DECLARE ... CONDITION

The DECLARE ... CONDITION statement declares a named error condition, associating a name with a condition that needs specific handling. The name can be referred to in a subsequent DECLARE ... HANDLER statement

Syntax

DECLARE condition_name CONDITION FOR condition_value condition_value

mysql_error_code | SQLSTATE [VALUE] sqlstate_value

condition_valuecan be a MySQL error code (a number) or an SQLSTATE value (a 5-character string literal)

Sample(Ref 13.6.7.1)

MySQL --- DECLARE ... HANDLER

The DECLARE ... HANDLER statement specifies a handler that deals with one or

more conditions.If one of these conditions occurs, the specified statement

executes. statement can be a simple statement such as SET var_name = value, or

a compound statement written using BEGIN and END.

q Syntax

DECLARE handler_action HANDLER

FOR condition_value [, condition_value] ...

statement

handler_action: CONTINUE | EXIT | UNDO

condition_value:

mysql_error_code

| SQLSTATE [VALUE] sqlstate_value

| condition_name

| SQLWARNING

| NOT FOUND

| SQLEXCEPTION

q Sample(Ref 13.6.7.2)

MySQL --- 游标

定义

映射在结果集中某一行数据的具体位置,类似于C语言中的指针。即通

过游标方式定位到结果集中某个特定的行,然后根据业务需求对该行进

行相应特定的操作。

游标使用的一般过程:声明, 打开, 读取, 关闭

声明:DECLARE cursor_name CURSOR FOR select_statement

打开:OPEN cursor_name

读取:FETCH [[NEXT] FROM] cursor_name INTO var_name [,var_name] ...

关闭:CLOSE cursor_name

MySQL---存储过程和函数概述

定义:
mysql中称为Stored routines (procedures and functions)
存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合
优点:
更快的速度(经过了预处理,减少网络数据传送)
避免代码冗余
提高数据库的安全性
缺点:跨数据库平台迁移比较复杂
两者的差异:
函数必须有返回值,而存储过程没有
存储过程的参数可以使用INOUTINOUT类型,而函数只能用IN类型

MySQL --- 存储过程和函数定义语法

语法:(Ref 13.1.15)

相关权限:

CREATE ROUTINE权限

ALTER ROUTINE权限

EXECUTE权限

缺省情况下,alter routineexecute会自动授予给创建者,通过参数

automatic_sp_privileges配置

注意事项:

客户端程序创建过程时,需要单独指定终止符,因为分号(;)作为语句分隔符

(Ref19.1)

函数可以不需要单独定义终止符,除非使用了复合体结构,如begin..end

当过程和函数被调用时,隐士式USE db_name 被执行

USE 语句不能够在存储过程和函数中使用  

MySQL ---过程函数definer,sql security

DEFINERSQL SECURITY用于指定在routine执行时检查相应的上下文访问权限

DEFINER用于描述当前的routine被谁定义或者创建,省略时为当前用户,方式为:'user_name'@'host_name'

SQL SECURITY后可以跟definer以及invoker

definer ,使用定义者权限执行存储过程,缺省值

invoker,使用调用者权限执行存储过程

对比定义者与调用者示例(Ref P1385)

当使用invoker时,除了需要有routine的执行权限之外,还需要有相关对象的访问权限

MySQL --- 过程及函数的调用

过程的调用方式
CALL sp_name([parameter[,...]])
CALL sp_name[()]
没参数的存储过程CALL p()等价于CALL p
Ref : 13.2.1
函数的调用方式
select fun_name();
http://blog.chinaunix.net/uid-25909722-id-4415328.html  

MySQL --- 过程及函数的查看

查看过程定义:SHOW CREATE PROCEDURE proc_name
查看函数定义:SHOW CREATE FUNCTION func_name
查看过程状态:SHOW PROCEDURE STATUS[LIKE 'pattern' | WHERE expr]
查看函数状态:SHOW FUNCTION STATUS[LIKE 'pattern' | WHERE expr]
通过information_schema.routines查看过程及函数
通过mysq.proc查看过程及函数
Debug模式查看过程定义:SHOW PROCEDURE CODE
proc_name (Ref 13.7.5.28)
Debug模式查看函数定义:SHOW FUNCTION CODE func_name

MySQL ---过程函数的修改与删除  

ROUTINE的修改
过程使用ALTER PROCEDURE proc_name [characteristic ...]
函数使用ALTER FUNCTION func_name [characteristic ...]
修改注意事项
有限修改routine的相关特性,如comment, sql security 等
不支持参数及body修改(不能使用oracle create or replace方式)
终极方案,先drop再create
 ROUTINE的删除
语法:DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_nam
示例:drop procedure sp1; drop function sakila.func1;

MySQL --- 触发器  

A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table.
Some uses for triggers are to perform checks of values to be inserted into a table or to perform calculations on values involved in an update.
Trigger events:INSERT,DELETE,UPDATE
Trigger time:before , after
Dependent object:permanent table, not temporary table, view
such as information_schema,performance_schema , update on NDB
engine
Synatax:Ref 13.1.19
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }

MySQL --- 触发器示例 

mysql> CREATE TABLE account (acct_num INT,
amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TRIGGER ins_sum BEFORE INSERT
ON account
-> FOR EACH ROW SET @sum = @sum +
NEW.amount;
Query OK, 0 rows affected (0.06 sec)
mysql> SET @sum = 0;
mysql> INSERT INTO account
VALUES(137,14.98),(141,1937.50),
(97,-100.00);
mysql> SELECT @sum AS 'Total
amount inserted';
+-----------------------+
| Total amount inserted |
+-----------------------+
| 1852.48 |
+-----------------------+
1 Trigger name:action time
2 Permanent table:account
3 Trigger time:before
4 Trigger event:insert
5 trigger body:for each row … the trigger body is a simple SET that accumulates into a user variable the values inserted into the amount column. The statement refers to the column as NEW.amount which means
“the value of the amount column to be inserted into the new row.

MySQL --- OLD and NEW keywords in trigger

Within the trigger body, the OLD and NEW keywords enable you to access columns in the rows affected by a trigger. OLD and NEW are MySQL extensions to triggers; they are not case sensitive.

When

In an INSERT trigger, only NEW.col_name can be used; there is no old row.

In an INSERT trigger, only NEW.col_name can be used; there is no old row.

In an UPDATE trigger, you can use OLD.col_name to refer to the columns of a row before it is updated and NEW.col_name to refer to the columns of the row after it is updated.

Limitation

The trigger cannot use the CALL statement to invoke stored procedures that return data to the client or that use dynamic SQL.

The trigger cannot use statements that explicitly or implicitly begin or end a transaction, such as START TRANSACTION, COMMIT, or ROLLBACK.

View Trigger:show triggers, desc trigger, information_schema.triggers

Example:Ref p2603

MySQL --- 视图

Views are stored queries that when invoked produce a result set. A view acts as a virtual table.

A view can be created from many kinds of SELECT statements. It can refer to base tables or other views. It can use joins, UNION, and subqueries.The SELECT need not even refer to any tables.

Some views are updatable. That is, you can use them in statements such as UPDATE, DELETE, or INSERT to update the contents of the underlying table. For a view to be updatable, there must be a one-to-one relationship between the rows in the view and the rows in the underlying table.

Syntax:Ref(13.1.20 19.5)

CREATE [OR REPLACE]

[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

[DEFINER = { user | CURRENT_USER }]

[SQL SECURITY { DEFINER | INVOKER }]

VIEW view_name [(column_list)]

AS select_statement

[WITH [CASCADED | LOCAL] CHECK OPTION]

MySQL --- View Processing Algorithms

MySQL extension : ALGORITHM. The default algorithm is UNDEFINED if no ALGORITHM clause is present.

MERGE:the text of a statement that refers to the view and the view definition are merged such that parts of the view definition replace corresponding parts of the statement.

TEMPTABLE:the results from the view are retrieved into a temporary table,which then is used to execute the statement.

UNDEFINED:MySQL chooses which algorithm to use. It prefers MERGE over TEMPTABLE if possible, because MERGE is usually more efficient and because view cannot be updatable if a temporary table is used.

猜你喜欢

转载自blog.csdn.net/wangjunji34478/article/details/79310277