启动MySQL:net start mysql
停止MySQL:net stop mysql
卸载MySQL:sc delete mysql
MySQL脚本基本组成:
- 标识符:
标识符用来命名一些对象, 如数据库、表、列、变量等, 以便在脚本中的其他地方引用。MySQL标识符命名规则稍微有点繁琐, 这里我们使用万能命名规则: 标识符由字母、数字或下划线(_)组成, 且第一个字符必须是字母或下划线。
对于标识符是否区分大小写取决于当前的操作系统, Windows下是不敏感的, 但对于大多数 linux\unix 系统来说, 这些标识符大小写是敏感的。 - 关键字:
MySQL的关键字众多。 - 语句:
MySQL语句是组成MySQL脚本的基本单位, 每条语句能完成特定的操作, 他是由 SQL 标准语句 + MySQL 扩展语句组成。 - 函数:
MySQL函数用来实现数据库操作的一些高级功能, 这些函数大致分为以下几类: 字符串函数、数学函数、日期时间函数、搜索函数、加密函数、信息函数。
MySQL数据类型: - 数字类型
-
整数: tinyint、smallint、mediumint、int、bigint
MySQL整数数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-32768~32767) mediumint(m) 3个字节 范围(-8388608~8388607) int(m) 4个字节 范围(-2147483648~2147483647) bigint(m) 8个字节 范围(+-9.22*10的18次方) 取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围 -
浮点数: float、double、real、decimal
MySQL浮点数数据类型 含义(有符号) float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位 double(m,d) 双精度浮点型 16位精度(8字节) m总个数,d小数位 设一个字段定义为float(5,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位 -
定点数
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。 decimal(m,d) 参数m<65 是总个数,d<30且 d
- 日期和时间
-
date、time、datetime、timestamp、year
MySQL日期时间数据类型 含义 date 日期 '0000-00-00' time 时间 '00:00:00' datetime 日期时间 '0000-00-00 00:00:00' timestamp 自动存储记录修改时间 若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,这个数据类型的字段可以存放这条记录最后被修改的时间
- 字符串类型
-
字符串: char、varchar
-
文本: tinytext、text、mediumtext、longtext
-
二进制(可用来存储图片、音乐等): tinyblob、blob、mediumblob、longblob
MySQL字符串数据类型 含义 char(n) 固定长度,最多255个字符 varchar(n) 固定长度,最多65535个字符 tinytext 可变长度,最多255个字符 text 可变长度,最多65535个字符 mediumtext 可变长度,最多2的24次方-1个字符 longtext 可变长度,最多2的32次方-1个字符 char和varchar的区别: 1. char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar不限于此。 2. char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以varchar(4),存入3个字符将占用4个字节。 3. char类型的字符串检索速度要比varchar类型的快。 varchar和text的区别: 1. varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。 2. text类型不能有默认值。 3. varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。 二进制数据(_Blob): 1. BLOB和_text存储方式不同,_TEXT以文本方式存储,英文存储区分大小写,而_Blob是以二进制方式存储,不分大小写。 2. BLOB存储的数据只能整体读出。 3. TEXT可以指定字符集,_BLO不用指定字符集。
MySQL属性关键字 | 含义 |
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT | 默认值 |
PRIMARY KEY | 主键 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
登录数据库:
登录MySQL:mysql -h 主机名 -u 用户名 -p
创建数据库:
CREATE DATABASE 数据库名 [其它选项];
CREATE DATABASE test_db CHARACTER SET GBK;
--创建名为test_db的数据库,并设定字符编码为GBK
选择要操作的数据库
登录时指定:mysql -D 所选择的数据库名 -h 主机名 -u 用户名 -p
在登录后使用USE语句指定:USE 数据库名;
--USE语句可以不加分号
创建数据库表
CREATE TABLE 表名称(列声明);
CREATE TABLE student(
id int unsigned not null auto_increment primary key,
name char(9) not null,
sex char(4) not null,
age tinyint unsigned nou null,
tel char(13) null default "-"
);
--创建名为student的数据库表
create table student(columns) 为创建数据库表的命令, 列的名称以及该列的数据类型将在括号内完成;
括号内声明了5列内容, id、name、sex、age、tel为每列的名称, 后面跟的是数据类型描述, 列与列的描述之间用逗号(,)隔开;
以 "id int unsigned not null auto_increment primary key" 行进行介绍:
"id" 为列的名称;
"int" 指定该列的类型为 int(取值范围为 -8388608到8388607), 在后面我们又用 "unsigned" 加以修饰, 表示该类型为无符号型, 此时该列的取值范围为 0到16777215;
"not null" 说明该列的值不能为空, 必须要填, 如果不指定该属性, 默认可为空;
"auto_increment" 需在整数列中使用, 其作用是在插入数据时若该列为 NULL, MySQL将自动产生一个比现存值更大的唯一标识符值。在每张表中仅能有一个这样的值且所在列必须为索引列。
"primary key" 表示该列是表的主键, 本列的值必须唯一, MySQL将自动索引该列
导入sql脚本
mysql -D test_db -u root -p < 脚本.sql
查询
SELECT 列名称 FROM 表名称 [查询条件];
--如果是查询所有的列,用 * 号表示
--SELECT * FROM 表名称 [查询条件];
按特定条件查询:
WHERE关键字用于指定查询条件:SELECT 列名称 FROM 表名称 WHERE 条件;
--SELECT * FROM student WHERE sex="男";
--查询sex值为男的行
插入数据
INSERT [INTO] 表名 [(列名1, 列名2, ...)] VALUES (值1, 值2, ....);
插入部分数据,或者不按列的顺序插入:
INSERT INTO studen(name, sex, age) VALUES(...);
INSERT INTO的几种方式:
方式1、 INSERT INTO t1(field1,field2) VALUES(v001,v002); // 明确只插入一条Value
方式2、 INSERT INTO t1(field1,field2) VALUES(v101,v102),(v201,v202),(v301,v302),(v401,v402);
在插入批量数据时方式2优于方式1.
方式3.1、 INSERT INTO t2(field1,field2) SELECT col1,col2 FROM t1 WHERE ……
由于可以指定插入到talbe2中的列,以及可以通过相对较复杂的查询语句进行数据源获取,可能使用起来会更加的灵活一些,但我们也必须注意,我们在指定目标表的列时,一定要将所有非空列都填上,否则将无法进行数据插入,还有一点比较容易出错的地方就是,当我们写成如下简写格式:
方式3.2、 INSERT INTO t2 SELECT id, name, address FROM t1
此时,我们如果略掉了目标表的列的话,则默认会对目标表的全部列进行数据插入,且SELECT后面的列的顺序 必须和目标表中的列的定义顺序完全一致 才能完成正确的数据插入,这是一个很容易被忽略的地方,值得注意。
更新表中数据:
UPDATE 表名称 SET 列名称=新值 WHERE 更新条件
删除表中数据:
DELETE FROM 表名称 WHERE 删除条件;
对表进行修改:
ALTER TABLE用于创建后对表进行修改:
添加列:
ALTER TABLE 表名 ADD 列名 列数据类型 [AFTER 插入位置];
修改列:
ALTER TABLE 表名 CHANGE 列名称 列新名称 新数据类型;
删除列:
ALTER TABLE 表名 DROP 列名称;
重命名表:
ALTER TABLE 表名 RENAME 新表名;
删除整张表:
DROP TABLE 表名;
删除整个数据库:
DROP DATABASE 数据库名;
查看显示所有数据库:
SHOW DATABASE;
查看当前使用数据库:
SELECT DATABASE();
查看数据库使用端口:
SHOW VARIABLES LIKE 'port';
查看当前数据库大小:
mysql> select concat(round(sum(data_length)/(1024*1024),2) + round(sum(index_length)/(1024*1024),2),'MB') as 'DB Size'
-> from tables
-> where table_schema='INVOICE'
查看索引所占空间大小:
mysql> select concat(round(sum(index_length)/(1024*1024),2),'MB') as 'DB Size'
-> from tables
-> where table_schema='INVOICE';
查看数据库编码:
SHOW VARIBALES LIKE '%character%';
character_set_client 为客户端编码方式;
character_set_connection 为建立连接使用的编码;
character_set_database 为数据库的编码;
character_set_results 为结果集的编码;
character_set_server 为数据库服务器的编码;
查看数据编码的另一种方式:
STATUS;
查看当前数据编码
查看数据库信息:
SHOW TABLES;
或者
select * from information_schema.tables where table_schema='databasename';
查看数据库所有用户信息:
SELECT DISTINCT CONCAT('user:' '',user,'''@''',host,''';') AS query FROM mysql.user;
查看某个具体用户权限:
SHOW GRANTS FOR 'root'@'localhost';
查看数据库的最大连接数:
SHOW VARIABLES LIKE '%max_connections%';
查看当前连接数,并发数:
SHOW STATUS LIKE 'Threads%';
Threads_cached : 代表当前此时此刻线程缓存中有多少空闲线程。
Threads_connected :代表当前已建立连接的数量,因为一个连接就需要一个线程,所以也可以看成当前被使用的线程数。
Threads_created :代表从最近一次服务启动,已创建线程的数量。
Threads_running :代表当前激活的(非睡眠状态)线程数。并不是代表正在使用的线程数,有时候连接已建立,但是连接处于sleep状态,这里相对应的线程也是sleep状态。
查看数据文件存放路径:
SHOW VARIABLES LIKE '%datadir%';
新建表并复制其他表:
复制表结构:
CREATE TABLE IF NOT EXISTS tb_new(LIKE db_table1);
复制表数据:
CREATE TABLE IF NOT EXISTS tb_new(SELECT * FROM db_table1);
清空数据:
TRUNCATE TABLE db.table;
DELETE FROM da.table;
删除数据表:
DROP db.table;
删除索引:
DROP INDEX index_name;
添加索引:
ADD FULLTEXT INDEX index_name USING BTREE (field1);
ALTER TABLE db.table1 ADD UNIQUE INDEX index_name USING BTREE (field1);
删除字段:
ALTER TABLE db.table1 DROP COLUMN field1;
修改字段:
ALTER TABLE db.table1
CHANGE COLUMN field_name new_field_name varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL AFTER `id`;
向另一个数据库中拷贝表:
SELECT * INTO table2 IN 'Backup.mdb' FROM table1;
删除数据库:
DROP DATABASE db_name;
查看表结构
DESC tableName;
模糊查询
LIKE 'data%';
LIKE '%data';
LIKE '%data%';
LIKE '_data'; 查看data结尾的五个字母数据
LIKE '[CK]ars[eo]n%'; CK选一个,eo选一个和ars,n组成字符
LIKE '[M-Z]data'; M到Z之间的任意单个字母的所有名称
LIKE 'd[^c]%'; d开头,第二个字母不是c的所有名称
其他见正则表达式...
主键
表中每一个都应该具有唯一标识自己的列(一组列),这个列成为主键
作为主键必须满足以下条件:
1、任何两行都不具有相同的主键值,就是这列的值互不相同;
2、每个行都具有一个主键值,主键列不能设置NULL;
3、主键的值不允许进行修改和更新
设定主键:
CREATE TABLE t1(
id int not null primary key
);
设定复合主键:
CREATE TABLE t1(
id int not null,
name char(20),
primary key(id,name)
);
主键自增:
CREATE TABLE t1(
id int not null primary key auto_increment
);
建完表设定主键
ALTER TABLE t ADD PRIMARY KEY (id);
外键
关键字:FOREIGN KEY,外键约束
实体A的某个字段,指向另一个实体B的主键,那么实体A的这个字段称为外键。
其中被指向的实体,成为主实体集(主表),也叫父实体集(父表)。
负责指向的实体集叫做从实体集(从表),也叫作子实体集(子表)。
1、增加子表记录的时候,需要判断是否有与之对应的附表记录?
2、当删除或更改附表记录的时候,子表应该如何处理相关记录?
定义父表:
CREATE TABLE web_class(
class_id int unsigned primary key,
class_teater varchar(20) not null
);
定义子表并设定外键:
CREATE TABLE web_student(
stu_id int unsigned primary key auto_increment,
stu_name varchar(20) not null,
stu_class_id int unsigned,
foreign key(stu_class_id) references web_class(class_id)
);
设置级联操作
级联操作(关联动作):操作一张表,影响另一张表
1、主表更新:
on update[级联操作]
2、主表删除:
on delete[级联操作]
上面级联操作常见的有三种形式:
cascade:同步操作,串联操作,也就是当主表的字段更新或者删除的时候,从表的外键也进行删除或者更新
set null:设置为空,当主表的字段更新或者删除的时候,子表的外键字段为空,前提是没有设置为非空约束
restrict:子表有匹配记录,就拒绝主表更新或删除
on update和on delete可以同时使用:
-- on update cascade on delete cascade //主表更新子表同步操作,主表删除子表也同步操作
-- on update cascade on delete set null
-- on update cascade on delete restrict
-- on update set null on delete cascade //主表更新子表设置为空,主表删除子表同步操作
-- on update set null on delete set null
-- on update set null on delete restrict
-- on update restrict on delete cascade //主表更新子表有匹配就拒绝主表更新,主表删除子表同步操作
-- on update restrict on delete set null
-- on update restrict on delete restrict
所以完整的外键定义语法:
foreign key(从表的外键字段) references 主表名(主表的主键)
on update cascade|set null|restrict on delete cascade|set null|restrict
删除外键:
alter table web_student drop foreign key 'foreign_key_name';
foreign_key_name不是外键的字段名,而是系统在定义外键的时候自动分配的一个名字,可以通过show create table table_name\G;查看
增加外键
alter table table_name add foreign key(从表的外键字段) reference 主表名(主表的主键)级联操作;
alter table 表名 add foreign key(从表的外键字段) references 主表名(主表的主键)
on update cascade|set null|restrict on delete cascade|set null|restrict
外键的约束,只有在InnoDB存储引擎上存储才能执行
多表操作
cross join(交叉连接):获取多个表中的交叉关系
inner join(内连接):获取两个表中字段匹配关系的记录
外连接:
left join(左连接):获取左表所有记录,即使右表没有匹配记录
right join(右连接):用于获取右表所有记录,即使左表没有对应匹配的记录
union:求两张表的并集
SELECT * FROM tb1 union (SELECT * FROM tb2); //查询出来的表,以tb1的表查询结果的字段为准,且列数相同
子查询
通过查询的结果为新表,然后对新表进行数据查询,一般发生在多对多关系中
语法:
select a.* from (select * from tb1 where 过滤条件) as a where 过滤条件;
多张表
select a.column1,a.column2,b.column1,b.column2... from (select * from tb1 where 过滤条件) as a , (select * from tb2 where 过滤条件) as b where 外键匹配 and 过滤条件;
[注](select * from tb1 where 过滤条件) as a:表示tb2查询出来的结果作为a表,整条语句的意思是:tb2查询的结果作为a表,通过匹配规则查询a表的相关数据
(select * from tb1 where 过滤条件) as a:只要把括号里面的当做一张表就好理解了。
交叉连接(笛卡尔积查询)
1、SELECT *FROM CUSTOMER C, ORDERS O;
2、SELECT c.id,c.name,o.order FROM CUSTOMER c CROSS JOIN O;
查询两张表的所有相匹配的数据:
SELECT * FROM table_1,table_2;
查询两种表对应关系:
SELECT * FROM table_1,table_2 WHERE table_1.c = table_2.c;
table tab_1:为避免表名太长,所有用简单的字符tab_1代替
内连接
1、隐式写法:
SELECT * FROM table_1 tb1,table_2 tb2 WHERE tb1.c = tb2.c;
2、显示写法:
SELECT * FROM table_1 tb1 inner join table_2 tb2 on tb1.c = tb2.c;
注意下面两种写法:
SELECT * FROM table_1 tb1 inner join table_2 tb2 on tb1.c = tb2.c;
SELECT * FROM table_2 tb2 inner join table_1 tb1 on tb1.c = tb2.c;
列的排序不同,第一种table_1的列排在前面(从左向右),后者相反
外连接
left join:
SELECT * FROM table_1 left join table_2 on table_1.c = xx;
SELECT * FROM table_2 left join table_1 on table_2.c = xx;
上面两种方式,第一种table_1显示在前面,table——2显示在后面,第二种相反
right join:
SELECT * FROM table_1 RIGHT JOIN table_2 on table_1.c=xx;
table_1在左边,table_2在右边
外连接不仅返回连接表中符合连接条件及查询条件的数据行,也返回左表(左外连接时)或右表(右外连接时)中仅符合查询条件但不符合连接条件的数据行
存储过程
储存过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。存储过程通常有以下优点:
1、编译优化,执行速度快
2、存储过程允许标准组件是编程,封装与抽象,简单调用
3、存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和教复杂的运算
4、存储过程可被作为一种机制来充分利用,限制与安全
5、存储过程减少网络流量
创建存储过程:
CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型...]]) [特性...] 过程体
DELIMITER //
CREATE PROCEDURE myproc(OUT S INT)
BEGIN
SELECT COUNT(*) INTO s FROM students;
END
DELIMITER;
MySQL默认以“;”为分隔符,如果没有声明分隔符,则编译器会把存储过程当成SQL语句进行处理,编译过程会报错,所以要实现用"DELIMITER //"声明当前段分隔,让编译器把两个“//”直接的内容当做存储过程的代码,不执行这些代码;“DELIMITER;”的意为把分隔符还原。
存储过程根据需要可能会有输入,输出,输入输出参数,如果有多个参数用逗号分开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:
IN:参数的值必须在调用存储过程时调用,在存储过程中修改该参数的值不能被返回,为默认值。
OUT:该值可在存储过程内部被改变,并可返回
INOUT:调用时指定,并且可被改变和返回
过程体:以BEGIN开始和END结束
DELIMITER //
CREATE PROCEDURE in_param(IN p_in int)
BEGIN
SELECT p_in; //检索p_in
SET p_in=2; //设定p_in=2
SELECT p_in; //检索p_in
END;
//
DELIMITER ;
#调用
SET @p_in=1; //设定p_in=1
CALL in_param(@p_in); //调用存储过程
SELECT @p_in; //检索p_in
变量
DECLARE 变量名1[,变量名2...]数据类型 [默认值];
变量赋值
SET 变量名 = 变量值[,变量名=变量值...]
用户变量一般以@开头
滥用用户变量会导致程序难以理解及管理
在MySQL客户端使用用户变量
SELECT 'Hello World' into @x;
SELECT @x;
SET @y='Goodbye Cruel World';
SELECT @y;
SET @z=1+2+3;
SELECT @z;
在存储过程中使用用户变量
CREATE PROCEDURE GreetWorld() SELECT CONCAT(@greeting,' World');
SET @greeting='Hello';
CALL GreetWorld();
在存储过程间传递全局范围的用户变量
CREATE PROCEDURE p1() SET @last_proc='p1';
CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc);
CALL p1();
CALL p2();
存储过程注释:-- 双杠
MySQL存储过程的调用
用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数
MySQL存储过程的查询
#查询存储过程
SELECT name FROM mysql.proc WHERE db='数据库名';
SELECT routine_name FROM information_schema.routines WHERE routine_schema='数据库名';
SHOW PROCEDURE STATUS WHERE db='数据库名';
#查看存储过程详细信息
SHOW CREATE PROCEDURE 数据库.存储过程名;
MySQL存储过程的修改
ALTER PROCEDURE 更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能
ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
characteristic:
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
sp_name参数表示存储过程或函数的名称;
characteristic参数指定存储函数的特性。
CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
NO SQL表示子程序中不包含SQL语句;
READS SQL DATA表示子程序中包含读数据的语句;
MODIFIES SQL DATA表示子程序中包含写数据的语句。
SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行,DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
COMMENT 'string'是注释信息
MySQL存储过程删除
DROP PROCEDURE [过程1[,过程2…]]
变量作用域
内部变量在其作用域范围内享有更高的优先权,当执行到end时,内部变量消失,不再可见了,在存储
过程外再也找不到这个内部变量,但是可以通过out参数或者将其值指派给会话变量来保存其值
DECLARE 变量名 数据类型 [DEFAULT ''];声明变量并设定默认值
条件语句
IF--THEN--ELSE
DROP PROCEDURE IF EXISTS proc3;
DELIMITER //
CREATE PROCEDURE proc3(IN parameter int)
BEGIN
DECLARE var int;
SET var=parameter+1;
IF var=0 THEN
INSERT INTO t VALUES (17);
END IF ;
IF parameter=0 THEN
UPDATE t SET s1=s1+1;
ELSE
UPDATE t SET s1=s1+2;
END IF ;
END ;
//
DELIMITER ;
CASE-WHEN-THEN-ELSE语句
DELIMITER //
CREATE PROCEDURE proc4 (IN parameter INT)
BEGIN
DECLARE var INT;
SET var=parameter+1;
CASE var
WHEN 0 THEN
INSERT INTO t VALUES (17);
WHEN 1 THEN
INSERT INTO t VALUES (18);
ELSE
INSERT INTO t VALUES (19);
END CASE ;
END ;
//
DELIMITER ;
循环语句:
WHILE-DO…END-WHILE
DELIMITER //
CREATE PROCEDURE proc5()
BEGIN
DECLARE var INT;
SET var=0;
WHILE var<6 DO
INSERT INTO t VALUES (var);
SET var=var+1;
END WHILE ;
END;
//
DELIMITER ;
REPEAT...END REPEAT
此语句的特点是执行操作后检查结果
DELIMITER //
CREATE PROCEDURE proc6 ()
BEGIN
DECLARE v INT;
SET v=0;
REPEAT
INSERT INTO t VALUES(v);
SET v=v+1;
UNTIL v>=5
END REPEAT;
END;
//
DELIMITER ;
LOOP...END LOOP
DELIMITER //
CREATE PROCEDURE proc7 ()
BEGIN
DECLARE v INT;
SET v=0;
LOOP_LABLE:LOOP
INSERT INTO t VALUES(v);
SET v=v+1;
IF v >=5 THEN
LEAVE LOOP_LABLE;
END IF;
END LOOP;
END;
//
DELIMITER ;
LABLES标号
标号可以用在begin repeat while或者loop语句前,语句标号只能在合法的语句前面使用,可以跳出循环,使运行指令到复合语句的最后一步。
ITERATE迭代
DELIMITER //
CREATE PROCEDURE proc8()
BEGIN
DECLARE v INT;
SET v=0;
LOOP_LABLE:LOOP
IF v=3 THEN
SET v=v+1;
ITERATE LOOP_LABLE;
END IF;
INSERT INTO t VALUES(v);
SET v=v+1;
IF v>=5 THEN
LEAVE LOOP_LABLE;
END IF;
END LOOP;
END;
//
DELIMITER ;
存储过程的基本函数
CHARSET(str) //返回字串字符集
CONCAT (string2 [,... ]) //连接字串
INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0
LCASE (string2 ) //转换成小写
LEFT (string2 ,length ) //从string2中的左边起取length个字符
LENGTH (string ) //string长度
LOAD_FILE (file_name ) //从文件读取内容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置
LPAD (string2 ,length ,pad ) //重复用pad加在string开头,直到字串长度为length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重复count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str
RPAD (string2 ,length ,pad) //在str后用pad补充,直到长度为length
RTRIM (string2 ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比较两字串大小,
SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符,
注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1
TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符
UCASE (string2 ) //转换成大写
RIGHT(string2,length) //取string2最后length个字符
SPACE(count) //生成count个空格
数学类
ABS (number2 ) //绝对值
BIN (decimal_number ) //十进制转二进制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //进制转换
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小数位数
HEX (DecimalNumber ) //转十六进制
注:HEX()中可传入字符串,则返回其ASC-11码,如HEX('DEF')返回4142143
也可以传入十进制整数,返回其十六进制编码,如HEX(25)返回19
LEAST (number , number2 [,..]) //求最小值
MOD (numerator ,denominator ) //求余
POWER (number ,power ) //求指数
RAND([seed]) //随机数
ROUND (number [,decimals ]) //四舍五入,decimals为小数位数] 注:返回类型并非均为整数
日期时间类
ADDTIME (date2 ,time_interval ) //将time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //转换时区
CURRENT_DATE ( ) //当前日期
CURRENT_TIME ( ) //当前时间
CURRENT_TIMESTAMP ( ) //当前时间戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或时间
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式显示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上减去一个时间
DATEDIFF (date1 ,date2 ) //两个日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1为星期天
DAYOFYEAR (date ) //一年中的第几天
EXTRACT (interval_name FROM date ) //从date中提取日期的指定部分
MAKEDATE (year ,day ) //给出年及年中的第几天,生成日期串
MAKETIME (hour ,minute ,second ) //生成时间串
MONTHNAME (date ) //英文月份名
NOW ( ) //当前时间
SEC_TO_TIME (seconds ) //秒数转成时间
STR_TO_DATE (string ,format ) //字串转成时间,以format格式显示
TIMEDIFF (datetime1 ,datetime2 ) //两个时间差
TIME_TO_SEC (time ) //时间转秒数]
WEEK (date_time [,start_of_week ]) //第几周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第几天
HOUR(datetime) //小时
LAST_DAY(date) //date的月的最后日期
MICROSECOND(datetime) //微秒
MONTH(datetime) //月
MINUTE(datetime) //分返回符号,正负或0
SQRT(number2) //开平方
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现
BEGIN 开始一个事务
ROLLBACK 事务回滚
COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
事务管理
1、事务的原子性:一组事务,要么成功;要么撤回。
2、稳定性 :有非法数据(外键约束之类),事务撤回。
3、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit 选项 决定什么时候吧事务保存到日志里。
在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交
事务控制语句:
BEGIN或START TRANSACTION;显式地开启一个事务;
COMMIT;也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改称为永久性的;
ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;
RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
ROLLBACK TO identifier;把事务回滚到标记点;
SET TRANSACTION;用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现
BEGIN 开始一个事务
ROLLBACK 事务回滚
COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb; # 创建数据表
Query OK, 0 rows affected (0.04 sec)
mysql> select * from runoob_transaction_test;
Empty set (0.01 sec)
mysql> begin; # 开始事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into runoob_transaction_test value(5);
Query OK, 1 rows affected (0.01 sec)
mysql> insert into runoob_transaction_test value(6);
Query OK, 1 rows affected (0.00 sec)
mysql> commit; # 提交事务
Query OK, 0 rows affected (0.01 sec)
mysql> select * from runoob_transaction_test;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.01 sec)
mysql> begin; # 开始事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into runoob_transaction_test values(7);
Query OK, 1 rows affected (0.00 sec)
mysql> rollback; # 回滚
Query OK, 0 rows affected (0.00 sec)
mysql> select * from runoob_transaction_test; # 因为回滚所以数据没有插入
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.01 sec)
触发器
触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行
创建触发器语法:
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:标识触发器名称,用户自行指定;
trigger_time:标识触发时机,取值为 BEFORE 或 AFTER;
trigger_event:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
tbl_name:标识建立触发器的表名,即在哪张表上建立触发器;
trigger_stmt:触发器程序体,可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句。
由此可见,可以建立6种触发器,即:BEFORE INSERT、BEFORE UPDATE、BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE。
另外有一个限制是不能同时在一个表上建立2个相同类型的触发器,因此在一个表上最多建立6个触发器。
trigger_event 详解
MySQL 除了对 INSERT、UPDATE、DELETE 基本操作进行定义外,还定义了 LOAD DATA 和 REPLACE 语句,这两种语句也能引起上述6中类型的触发器的触发。
LOAD DATA 语句用于将一个文件装入到一个数据表中,相当与一系列的 INSERT 操作。
REPLACE 语句一般来说和 INSERT 语句很像,只是在表中有 primary key 或 unique 索引时,如果插入的数据和原来 primary key 或 unique 索引一致时,会先删除原来的数据,然后增加一条新数据,也就是说,一条 REPLACE 语句有时候等价于一条。
INSERT 语句,有时候等价于一条 DELETE 语句加上一条 INSERT 语句。
INSERT 型触发器:插入某一行时激活触发器,可能通过 INSERT、LOAD DATA、REPLACE 语句触发;
UPDATE 型触发器:更改某一行时激活触发器,可能通过 UPDATE 语句触发;
DELETE 型触发器:删除某一行时激活触发器,可能通过 DELETE、REPLACE 语句触发。
BEGIN … END 详解
在MySQL中,BEGIN … END 语句的语法为:
BEGIN
[statement_list]
END
其中,statement_list 代表一个或多个语句的列表,列表内的每条语句都必须用分号(;)来结尾。
而在MySQL中,分号是语句结束的标识符,遇到分号表示该段语句已经结束,MySQL可以开始执行了。因此,解释器遇到statement_list 中的分号后就开始执行,然后会报出错误,因为没有找到和 BEGIN 匹配的 END。
这时就会用到 DELIMITER 命令(DELIMITER 是定界符,分隔符的意思),它是一条命令,不需要语句结束标识,语法为:
DELIMITER new_delemiter
new_delemiter 可以设为1个或多个长度的符号,默认的是分号(;),我们可以把它修改为其他符号,如$:
DELIMITER $
在这之后的语句,以分号结束,解释器不会有什么反应,只有遇到了$,才认为是语句结束。注意,使用完之后,我们还应该记得把它给修改回来
NEW 与 OLD 详解
在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;
在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName (columnName 为相应数据表某一列名)
另外,OLD 是只读的,而 NEW 则可以在触发器中使用 SET 赋值,这样不会再次触发触发器,造成循环调用(如每插入一个学生前,都在其学号前加“2013”)
查看触发器
SHOW TRIGGERS [FROM schema_name];
删除触发器
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
正则
SELECT * FROM users WHERE email NOT REGEXP '^[A-Z0-9._%-]+@[A-Z0-9.-]+.[A-Z]{2,4}$'
临时表
mysql> CREATE TEMPORARY TABLE SalesSummary (
-> product_name VARCHAR(50) NOT NULL
-> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
-> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
-> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO SalesSummary
-> (product_name, total_sales, avg_unit_price, total_units_sold)
-> VALUES
-> ('cucumber', 100.25, 90, 2);
当你使用 SHOW TABLES命令显示数据表列表时,你将无法看到 SalesSummary表。
如果你退出当前MySQL会话,再使用 SELECT命令来读取原先创建的临时表数据,那你会发现数据库中没有该表的存在,因为在你退出时该临时表已经被销毁了
删除MySQL 临时表
默认情况下,当你断开与数据库的连接后,临时表就会自动被销毁。当然你也可以在当前MySQL会话使用 DROP TABLE 命令来手动删除临时表。
DROP TABLE SalesSummary;
序列使用
MySQL中使用序列的方法是使用AUTO_INCREMENT属性来定义列。
AUTO_INCREMENT属性1开始,以1为基数递增。
当插入记录时,如果把一个NULL插入到一个AUTO_INCREMENT列,MySQL将自动生成下一个序列编号。
当插入记录时,没有为AUTO_INCREMENT明确指定值,则等同插入NULL值。
当插入记录时,如果为AUTO_INCREMENT字段明确指定了一个数值,则会出现两种情况。
一、如果插入的值与已有的编号重复,会出现出错信息, 因为AUTO_INCREMENT数据列的值必须是唯一的。
二、如果插入的值大于已编号的值,则会把该插入到数据列中,并使在下一个编号将从这个新值 开始递增。
如果用UPDATE命令更新自增列,如果列值与已有的值重复,则会出错。如果大于已有值,则下一个编号从该值开始递增。
索引
主键和唯一索引的区别:
键一定是唯一性索引,唯一性索引并不一定就是主键。
1.主键可以保证记录的唯一和主键域非空,数据库管理系统对于主键自动生成唯一索引,所以主键也是一个特殊的索引。
2. 一个表中可以有多个唯一性索引,但只能有一个主键。
3. 主键列不允许空值,而唯一性索引列允许空值。
4. 索引可以提高查询的速度。
主键是逻辑键,索引是物理键,意思就是主键不实际存在,而索引实际存在在数据库中,主键一般都要建,主要是用来避免一张表中有相同的记录,索引一般可以不建,但如果需要对该表进行查询操作,则最好建,这样可以加快检索的速度。
mysql> CREATE TABLE `wb_blog` (
-> `id` smallint(8) unsigned NOT NULL,
-> `catid` smallint(5) unsigned NOT NULL DEFAULT '0',
-> `title` varchar(80) NOT NULL DEFAULT '',
-> `content` text NOT NULL,
-> PRIMARY KEY (`id`),
-> UNIQUE KEY `catename` (`catid`)
-> ) ;
为wb_blog表的'catid'字段创建名为catename的唯一索引
在创建表之后使用CREATE命令来创建
CREATE UNIQUE INDEX catename ON wb_blog(catid);
删除唯一索引
ALTER TABLE wb_blog DROP INDEX catename;
复制表
1.只复制表结构到新表
CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2
CREATE TABLE 新表 LIKE 旧表
2.复制表结构及数据到新表
CREATE TABLE 新表 SELECT * FROM 旧表
3.复制旧表的数据到新表(假设两个表结构一样)
INSERT INTO 新表 SELECT * FROM 旧表
4.复制旧表的数据到新表(假设两个表结构不一样)
INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 旧表