SQL语法合集

Mysql

  • 一、DQL(Data Query Language):数据查询语言
    • 1、条件查询
    • 2.分组和排序
    • 3.常用函数
    • 4.多表连接
    • 4.子查询
    • 5.联合查询
  • 二、sql数据类型、约束和变量
    • 1.sql的数据类型
    • 2.约束
    • 3.变量
  • 三,DML(Data Manipulate Language):数据操作语言
  • 四、DDL(Data Define Languge):数据定义语言
    • 1. create、drop、alter
  • 五、视图
  • 六、​ TCL(Transaction Control Language):事务控制语言
  • 七、存储过程
  • 八、函数
  • 九、mysql提高


DB:数据库(database):存储数据的“仓库”。它保存了一系列有组织的数据。
DBMS:数据库管理系统(Database Management System)。数据库是通过DBMS创
建和操作的容器
SQL:结构化查询语言(Structure Query Language):专门用来与数据库通信的语言

一、DQL(Data Query Language):数据查询语言

1、条件查询

一、按条件表达式筛选
简单条件运算符:> < = != <> >= <=

二、按逻辑表达式筛选
逻辑运算符:
作用:用于连接条件表达式
	&& || !
	and or not
	
&&和and:两个条件都为true,结果为true,反之为false
||或or: 只要有一个条件为true,结果为true,反之为false
!或not: 如果连接的条件本身为false,结果为true,反之为false

三、模糊查询
	like
	between and
	in
	is null



#案例:查询部门编号不是在90到110之间,或者工资高于15000的员工信息
SELECT
	*
FROM
	employees
WHERE
	NOT(department_id>=90 AND  department_id<=110) OR salary>15000;
	
	
#案例:查询员工的工种编号是 IT_PROG、AD_VP、AD_PRES中的一个员工名和工种编号
SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id = 'IT_PROT' OR job_id = 'AD_VP' OR JOB_ID ='AD_PRES';


#------------------

SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id IN( 'IT_PROT' ,'AD_VP','AD_PRES');


2.分组和排序

#①查询每个部门的员工个数
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;

#案例:查询哪个部门的员工个数>5
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>5;

#案例:查询每个工种每个部门的最低工资,并按最低工资降序

SELECT MIN(salary),job_id,department_id
FROM employees
GROUP BY department_id,job_id
ORDER BY MIN(salary) DESC;

#案例:查询员工信息,要求先按工资降序,再按employee_id升序
SELECT *
FROM employees
ORDER BY salary DESC,employee_id ASC;

3.常用函数

一、单行函数
字符函数:
length:获取字节个数(utf-8一个汉字代表3个字节,gbk为2个字节)
concat
substr
instr
trim
upper
lower
lpad
rpad
replace

数学函数:
round
ceil
floor
truncate:SELECT TRUNCATE(1.69999,1);保留一位小数
mod

日期函数:
now
curdate
curtime
year
month
monthname
day
hour
minute
second
str_to_date
date_format
其他函数:
version
database
user
控制函数
if
case

二、分组函数

功能:用作统计使用,又称为聚合函数或统计函数或组函数

分类:
sum 求和、avg 平均值、max 最大值 、min 最小值 、count 计算个数

特点:
1、sum、avg一般用于处理数值型
max、min、count可以处理任何类型
2、以上分组函数都忽略null值

3、可以和distinct搭配实现去重的运算

4、count函数的单独介绍
一般使用count(*)用作统计行数

5、和分组函数一同查询的字段要求是group by后的字段

单行函数
SELECT LENGTH('张三丰hahaha');//汉字默认占3个字节。
SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2)))  out_put
FROM employees;

SELECT SUBSTR('李莫愁爱上了陆展元',7)  out_put; #out_put是别名。

#结果a张aaaaaaaaaaaa翠山a
SELECT TRIM('aa' FROM 'aaaaaaaaa张aaaaaaaaaaaa翠山aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')  AS out_put;

#out_put:张翠山
SELECT TRIM('    张翠山    ') AS out_put;
时间函数

SELECT NOW();#2022-03-16 14:54:04
SELECT CURTIME();#14:54:51
SELECT YEAR(NOW())#1998
SELECT MONTH(NOW())#3
其他函数
SELECT VERSION();
SELECT DATABASE();
SELECT USER();


分组函数
SELECT SUM(salary),AVG(salary) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 个数
FROM employees;

count(*)和count(1)一样的结果。
SELECT COUNT(*) FROM employees;
SELECT COUNT(1) FROM employees;
效率:
MYISAM存储引擎下  ,COUNT(*)的效率高
INNODB存储引擎下,COUNT(*)COUNT(1)的效率差不多,比COUNT(字段)要高一些

4.多表连接

1.注意要点:
sql92标准:仅仅支持内连接
sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接

功能:sql99支持的较多
可读性:sql99实现连接条件和筛选条件的分离,可读性较高


92语法:只显示每个表都符合的字段
#案例:三表连接,查询员工名、部门名和所在的城市
SELECT last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.`department_id`=d.`department_id`
AND d.`location_id`=l.`location_id`
AND city LIKE 's%'
ORDER BY department_name DESC
limit 0,5;

#2、非等值连接查询员工的工资和工资级别
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';
#自连接 员工名和上级的名称
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.`manager_id`=m.`employee_id`;

99语法
#案例2.查询名字中包含e的员工名和工种名(添加筛选)
SELECT last_name,job_title
FROM employees e
INNER JOIN jobs j#inner可以省略
ON e.`job_id`=  j.`job_id`
WHERE e.`last_name` LIKE '%e%';

 #左外连接
 SELECT b.*,bo.*
 FROM boys bo
 LEFT OUTER JOIN beauty b
 ON b.`boyfriend_id` = bo.`id`
 WHERE b.`id` IS NULL;

#左外:右表没有对应的字条,组表字条仍然显示,右表没有的内容填null
 #案例1:查询哪个部门没有员工
 #左外  from 后的为左,join后为右
 SELECT d.*,e.employee_id
 FROM departments d
 LEFT OUTER JOIN employees e
 ON d.`department_id` = e.`department_id`
 WHERE e.`employee_id` IS NULL;
 
  #右外 from 后的为左,join后为右
 SELECT d.*,e.employee_id
 FROM employees e
 RIGHT OUTER JOIN departments d
 ON d.`department_id` = e.`department_id`
 WHERE e.`employee_id` IS NULL;
 #全外
 USE girls;
 SELECT b.*,bo.*
 FROM beauty b
 FULL OUTER JOIN boys bo
 ON b.`boyfriend_id` = bo.id;


 #交叉连接 左(右)表的每一个字条都配对右(左)表的所以字条
 SELECT b.*,bo.*
 FROM beauty b
 CROSS JOIN boys bo;
 

4.子查询


ALLANY常常用在子查询前面,表示子表中的所有和任何。
子查询可以放在where/And/Having,select,from,in/exist后面。
————————————————————————————————————————————————————————————————————————————————————————————————————————————————
子查询在wherehaving后面
SELECT last_name,job_id,salary
FROM employees
WHERE job_id = (
	SELECT job_id
	FROM employees
	WHERE employee_id = 141
) AND salary>(
	SELECT salary
	FROM employees
	WHERE employee_id = 143

);


#案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工   的员工号、姓名、job_id 以及salary
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<ALL(
	SELECT DISTINCT salary
	FROM employees
	WHERE job_id = 'IT_PROG'

) AND job_id<>'IT_PROG';

#3、行子查询(结果集一行多列或多行多列)
#案例:查询员工编号最小并且工资最高的员工信息
SELECT * 
FROM employees
WHERE (employee_id,salary)=(
	SELECT MIN(employee_id),MAX(salary)
	FROM employees
);

子查询在select后面
SELECT d.*,(

	SELECT COUNT(*)
	FROM employees e
	WHERE e.department_id = d.`department_id`
 ) 个数
 FROM departments d;

子查询在 from后面
 SELECT  ag_dep.*,g.`grade_level`
FROM (
	SELECT AVG(salary) ag,department_id
	FROM employees
	GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

子查询在inexists后面
SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000);
SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
	SELECT department_id
	FROM employees

)

5.联合查询

UNION求两个表的交集,UNION ALL 把两个表进行拼接。
SELECT * FROM employees WHERE email LIKE '%a%' OR department_id>90;;

SELECT * FROM employees  WHERE email LIKE '%a%'
UNION
SELECT * FROM employees  WHERE department_id>90;

SELECT id,cname FROM t_ca WHERE csex='男'
UNION ALL#重复部分不合并
SELECT t_id,tname FROM t_ua WHERE tGender='male';

二、sql数据类型、约束和变量

1.sql的数据类型

整型:分类:tinyint(1)、smallint(2)、mediumint(3)、int/integer(4)、bigint(8)
小数:定点数 浮点数
较短的文本:char、varchar
较长的文本:text、blob(较长的二进制数据)

整数
字节数tinyint1smallint2mediumint3int/integer4bigint8

① 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加unsigned关键字
② 如果插入的数值超出了整型的范围,会报out of range异常,并且插入临界值
③ 如果不设置显示长度,会有默认的长度,如果不够会用0在左边填充,但必须搭配zerofill使用!

*/

#1.如何设置无符号和有符号

DROP TABLE IF EXISTS tab_int;
CREATE TABLE tab_int(
	t1 INT(7) unsigned,#7表示最大显示位数
	t2 INT(7) ZEROFILL 

);


小数
/*
分类:
1.浮点型                          2.定点型
float(M,D)                      dec(M,D)
double(M,D)                     decimal(M,D)

M:整数部位+小数部位
D:小数部位
如果超过范围,则插入临界值

M和D都可以省略
如果是decimal,则M默认为10,D默认为0
如果是floatdouble,则会根据插入的数值的精度来决定精度

③定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用

DROP TABLE tab_float;
CREATE TABLE tab_float(
	f1 FLOAT5,3,#可以保存2个整数,3个小数。
	f2 DOUBLE,
	f3 DECIMAL
);
SELECT * FROM tab_float;
DESC tab_float;

INSERT INTO tab_float VALUES(123.4523,123.4523,123.4523);
INSERT INTO tab_float VALUES(123.456,123.456,123.456);

字符型
写法		M的意思		特点(最大字符数是指汉字和字母可以显示的字符)			           空间的耗费   	效率
char	char(M)		最大的字符数,可以省略,默认为1	       	固定长度的字符		比较耗费	高
varchar varchar(M)	最大的字符数,不可以省略	        	可变长度的字符		比较节省	低

eunm型
CREATE TABLE tab_char(
	c1 ENUM('a','b','c')#c1列只能存放abc中的一个
);
INSERT INTO tab_char VALUES('a');
INSERT INTO tab_char VALUES('b');
INSERT INTO tab_char VALUES('m');#插入空字符
INSERT INTO tab_char VALUES('A');#插入a
setCREATE TABLE tab_set(
	s1 SET('a','b','c','d')#设置s1列只能存放 abcd中的一个或几个

);
INSERT INTO tab_set VALUES('a');
INSERT INTO tab_set VALUES('A,B');
INSERT INTO tab_set VALUES('a,c,d');

日期型
CREATE TABLE tab_date(
	t1 DATETIME,
	t2 TIMESTAMP
);
INSERT INTO tab_date VALUES(NOW(),NOW());

2.约束

六大约束
	NOT NULL:非空,用于保证该字段的值不能为空
	比如姓名、学号等
	DEFAULT:默认,用于保证该字段有默认值
	比如性别
	PRIMARY KEY:主键,用于保证该字段的值具有唯一性,并且非空
	比如学号、员工编号等
	UNIQUE:唯一,用于保证该字段的值具有唯一性,可以为空
	比如座位号
	CHECK:检查约束【mysql中不支持】
	比如年龄、性别
	FOREIGN KEY:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值

表级约束:除了非空、默认,其他的都支持
————————————————————————————————————————————————————————————————————————————————————————————————
创建表时,表级和列级约束的区别在于约束添加的位置。

列级约束
USE students;
DROP TABLE stuinfo;
CREATE TABLE stuinfo(
	id INT PRIMARY KEY,#主键
	stuName VARCHAR(20) NOT NULL UNIQUE,#非空
	gender CHAR(1) CHECK(gender='男' OR gender ='女'),#检查
	seat INT UNIQUE,#唯一
	age INT DEFAULT  18,#默认约束
	majorId INT REFERENCES major(id)#外键majorId的值必须是major.id的值。
);

CREATE TABLE major(
	id INT PRIMARY KEY,
	majorName VARCHAR(20)
);


DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT,
#表级约束添加	
# 【constraint 约束名】 约束类型(字段名) 可以去掉constraint pk
	CONSTRAINT pk PRIMARY KEY(id),#主键 可以直接写成PRIMARY KEY(id)
	CONSTRAINT uq UNIQUE(seat),#唯一键
	CONSTRAINT ck CHECK(gender ='男' OR gender  = '女'),#检查
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键
	
);
修改表级和列级约束的语法
1、添加列级约束
alter table 表名 modify column 字段名 字段类型 新约束;
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
2、添加表级约束
alter table 表名 addconstraint 约束名】 约束类型(字段名) 【外键的引用】;
ALTER TABLE stuinfo ADD PRIMARY KEY(id);
ALTER TABLE stuinfo ADD UNIQUE(seat);


创建标识列(设置某一类自增长)
CREATE TABLE tab_identity(
	id INT  ,
	NAME FLOAT UNIQUE AUTO_INCREMENT,
	seat INT 
);
SET auto_increment_increment=3;#设置增长步长


3.变量

系统变量包括全局变量和会话变量
全局变量作用域:针对于所有会话(连接)有效,但不能跨重启
会话变量作用域:针对于当前会话(连接)有效

注意:全局变量需要添加global关键字,会话变量需要添加session关键字,如果不写,默认会话级别
说明:变量由系统定义,不是用户定义,属于服务器层面
1、查看所有系统变量
show global|session】variables;
2、查看满足条件的部分系统变量
show global|session】 variables like '%char%';
3、查看指定的系统变量的值
select @@global|session】系统变量名;
4、为某个系统变量赋值
方式一:
set global|session】系统变量名=;
方式二:
set @@global|session】系统变量名=;

#①查看所有全局变量
SHOW GLOBAL VARIABLES;

#②查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
#②查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';

#①查看所有会话变量
SHOW SESSION VARIABLES;

#③查看指定的系统变量的值
SELECT @@global.autocommit;
#③查看指定的会话变量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;

#④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;
#④为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';

SHOW  VARIABLES;

自定义变量包括用户变量和局部变量
用户变量作用域:针对于当前会话(连接)有效,作用域同于会话变量
局部变量作用域:仅仅在定义它的begin end块中有效

用户变量:用户变量	当前会话	,加@符号,不用指定类型
#①声明并初始化
SET @变量名=;
SET @变量名:=;
SELECT @变量名:=;
#②赋值(更新变量的值)
#方式一:
	SET @变量名=;
	SET @变量名:=;
	SELECT @变量名:=;
#方式二:
	SELECT 字段 INTO @变量名
	FROM;
#③使用(查看变量的值)
SELECT @变量名;
#用户变量
SET @m=1;
SET @n=1;
SET @sum=@m+@n;
SELECT @sum;

局部变量:局部变量,定义它的BEGIN END中 ,BEGIN END的第一句话,一般不用加@,需要指定类型
应用在 begin end中的第一句话
#①声明
DECLARE 变量名 类型;
DECLARE 变量名 类型 【DEFAULT 值】;

#②赋值(更新变量的值)

#方式一:
	SET 局部变量名=;
	SET 局部变量名:=;
	SELECT 局部变量名:=;
#方式二:
	SELECT 字段 INTO 具备变量名
	FROM;
#③使用(查看变量的值)
SELECT 局部变量名;

DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 1;
DECLARE SUM INT;
SET SUM=m+n;

三,DML(Data Manipulate Language):数据操作语言

​1. insert 、update、delete

插入字条
方式一:insert into 表名(列名,...) values(1,...);
INSERT INTO beauty(id,NAME,sex,borndate,phone,photo,boyfriend_id)
VALUES(13,'唐艺昕','女','1990-4-23','1898888888',NULL,2);

支持多行插入
INSERT INTO beauty
VALUES(23,'唐艺昕1','女','1990-4-23','1898888888',NULL,2)
,(24,'唐艺昕2','女','1990-4-23','1898888888',NULL,2)
,(25,'唐艺昕3','女','1990-4-23','1898888888',NULL,2);

INSERT INTO beauty(id,NAME,phone)
SELECT 26,'宋茜','11809866';
支持子查询
INSERT INTO beauty(id,NAME,phone)
SELECT id,boyname,'1234567'
FROM boys WHERE id<3;

方式二(方式二只支持单行,且不支持子查询)
insert into 表名 set 列名=,列名=,...
INSERT INTO beauty
SET id=19,NAME='刘涛',phone='999';
————————————————————————————————————————————————————————————————————————————————————————————
修改表项

修改单表
update 表名set=新值,=新值,...where 筛选条件;
UPDATE boys SET boyname='张飞',usercp=10 WHERE id=2;

修改多表
sql92语法:update1 别名,2 别名set=,...where 连接条件 and 筛选条件;


sql99语法:update1 别名 inner|left|right join2 别名 on 连接条件 set=,... where 筛选条件;
UPDATE boys bo
RIGHT JOIN beauty b ON bo.`id`=b.`boyfriend_id`
SET b.`boyfriend_id`=2
WHERE bo.`id` IS NULL;
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
删除表项

删除单表
delete from 表名 where 筛选条件
DELETE FROM beauty WHERE phone LIKE '%9';

truncate table 表名;
TRUNCATE TABLE boys 
/*

1.delete 可以加where 条件,truncate不能加
2.truncate删除,效率高一丢丢
3.假如要删除的表中有自增长列,
如果用delete删除后,再插入数据,自增长列的值从断点开始,
而truncate删除后,再插入数据,自增长列的值从1开始。
4.truncate删除没有返回值,delete删除有返回值
5.truncate删除不能回滚,delete删除可以回滚.

*/

删除多表
sql92语法:
delete1的别名,2的别名
from1 别名,2 别名
where 连接条件
and 筛选条件;

DELETE b
FROM beauty b
INNER JOIN boys bo ON b.`boyfriend_id` = bo.`id`
WHERE bo.`boyName`='张无忌';


sql99语法:
delete1的别名,2的别名
from1 别名
inner|left|right join2 别名 on 连接条件
where 筛选条件;

DELETE b,bo
FROM beauty b
INNER JOIN boys bo ON b.`boyfriend_id`=bo.`id`
WHERE bo.`boyName`='黄晓明';

四、DDL(Data Define Languge):数据定义语言

1. create、drop、alter

1.库的管理
语法:create database  [if not exists]库名;
CREATE DATABASE IF NOT EXISTS books ;
RENAME DATABASE books TO 新库名;
ALTER DATABASE books CHARACTER SET gbk;#更改库的字符集
DROP DATABASE IF EXISTS books;#3、库的删除

2.表的管理
表的创建:
CREATE TABLE book(
	id INT,#编号
	bName VARCHAR(20),#图书名
	price DOUBLE,#价格
	authorId  INT,#作者编号
	publishDate DATETIME#出版日期
);

CREATE TABLE copy LIKE author;#创建一个和author一样结构的表

CREATE TABLE copy3#只复制部分数据
SELECT id,au_name
FROM author 
WHERE nation='中国';

表的修改:
alter table 表名 add|drop|modify|change column 列名 【列类型 约束】;
ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;#①修改列名
ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;#②修改列的类型或约束
ALTER TABLE author ADD COLUMN annual DOUBLE; #③添加新列
ALTER TABLE book_author DROP COLUMN  annual;#④删除列
ALTER TABLE author RENAME TO book_author;#⑤修改表名

DROP TABLE IF EXISTS book_author;
SHOW TABLES;

五、视图

含义:虚拟表,和普通表一样使用
视图 create view 只是保存了sql逻辑 增删改查,只是一般不能增删改

一、创建视图
/*
语法:
create view 视图名
as
查询语句;

*/
CREATE OR REPLACE VIEW myv1
AS
SELECT last_name,email
FROM employees;

DROP VIEW emp_v1,emp_v2,myv3;
#更新
UPDATE myv1 SET m=9000 WHERE department_id=10;
#1.插入

INSERT INTO myv1 VALUES('张飞','[email protected]');

六、​ TCL(Transaction Control Language):事务控制语言

1.事务的特性:ACID
原子性:一个事务不可再分割,要么都执行要么都不执行
一致性:一个事务执行会使数据从一个一致状态切换到另外一个一致状态
隔离性:一个事务的执行不受其他事务的干扰
持久性:一个事务一旦提交,则会永久的改变数据库的数据.
2.并发问题:
脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.
幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插 入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.
3. Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE。 Oracle 默认的事务隔离级别为: READ COMMITED 。
Mysql 支持 4 种事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ。
SQL语法合集_第1张图片

脏读:在read uncommitted级别下,DBMS(Database Management System)的事务A会读取事务B提交但未committ的语句,所以当B回滚时,A读取的数据就是无效的(read uncommitted:事务只能读取已提交的数据)。
幻读:A读取某一字段后,事务执行期间,B事务对其增加几行,A再次读取该表就会多出几行,(只有在sepializable可以避免,串行化的要求是:A事务读取某表项后,在事务执行期间,禁止其他事务对表进行增删改)
不可重复读:A事务两次读取同一字段的数据不一样。(repeatable read:A事务读取某字段后,A事务未结束期间,禁止其他事务对该字段进行更新)

sql中,当提交SET autocommit=0;sql会将后续提交的每一条进行事务处理(每条语句都执行,但设置了备份,以防回滚),当接受到commit时,sql才会删掉备份。

1.回滚与提交
#开启事务
SET autocommit=0;
START TRANSACTION;#开启事务,这条不写也可以,不写的话,系统默认开启
#编写一组事务的语句
UPDATE account SET balance = 1000 WHERE username='张无忌';
UPDATE account SET balance = 1000 WHERE username='赵敏';
#结束事务
ROLLBACK;#commit;回滚或提交事务
2.deletetruncate
delete可以回滚,而truncate不能回滚,一旦提交这条语句就删除相应表项。

3.演示savepoint 的使用#回滚到保存点,之前的事务相当于已经提交
SET autocommit=0;
START TRANSACTION;#开启事务,这条不写也可以,不写的话,系统默认开启
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点

七、存储过程

#案例2 :创建存储过程实现,用户是否登录成功
delimiter $
CREATE PROCEDURE myp4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
	DECLARE result INT DEFAULT 0;#声明并初始化
	SELECT COUNT(*) INTO result#赋值
	FROM admin
	WHERE admin.username = username
	AND admin.password = PASSWORD;	
	SELECT IF(result>0,'成功','失败');#使用
END $
#调用
CALL myp3('张飞','8888')$

#案例2:根据输入的女神名,返回对应的男神名和魅力值
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT) 
BEGIN
	SELECT boys.boyname ,boys.usercp INTO boyname,usercp
	FROM boys 
	RIGHT JOIN
	beauty b ON b.boyfriend_id = boys.id
	WHERE b.name=beautyName ;	
END $
#调用
CALL myp7('小昭',@name,@cp)$
SELECT @name,@cp$


#4.创建带inout模式参数的存储过程
#案例1:传入a和b两个值,最终a和b都翻倍并返回
CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT)
BEGIN
	SET a=a*2;
	SET b=b*2;
END $
#调用
SET @m=10$
SET @n=20$
CALL myp8(@m,@n)$
SELECT @m,@n$


#三、删除存储过程
#语法:drop procedure 存储过程名
DROP PROCEDURE p1;

八、函数

CREATE FUNCTION myf1() RETURNS INT
BEGIN
	DECLARE c INT DEFAULT 0;#定义局部变量
	SELECT COUNT(*) INTO c#赋值
	FROM employees;
	RETURN c;	
END $
SELECT myf1()$

CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
	SET @sal=0;#定义用户变量 
	SELECT salary INTO @sal   #赋值
	FROM employees
	WHERE last_name = empName;
	
	RETURN @sal;
END $

SELECT myf2('k_ing') $

九、mysql提高

索引语法
SHOW INDEX FROM table_name ;
DROP INDEX index_name ON table_name ;
CREATE INDEX idx_user_name ON tb_user(name);
CREATE UNIQUE INDEX idx_user_phone ON tb_user(phone);
CREATE INDEX idx_user_pro_age_sta ON tb_user(profession,age,status);

explain select * from tb_user use index(idx_user_pro) where profession = '软件工 程';
explain select * from tb_user ignore index(idx_user_pro) where profession = '软件工 程';

select count(distinct substring(email,1,5)) / count(*) from tb_user ;
create index idx_email_5 on tb_user(email(5));#用email前五个字作为索引

系统记录了当前数据库的各个语句使用的次数
SHOW GLOBAL STATUS LIKE 'Com_______';#可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次

可以查看每条mysql的耗时情况
SELECT @@profiling ;#查看profile是否打开
SET profiling = 1;#开启profile
show profiles;#-- 查看每一条SQL的耗时基本情况 show profiles;

触发器
CREATE TRIGGER trigger_name 
BEFORE/AFTER INSERT/UPDATE/DELETE 
ON tbl_name FOR EACH ROW -- 行级触发器 
BEGIN
trigger_stmt ;
 END;

SHOW TRIGGERS ;
DROP TRIGGER [database_name.]trigger_name ;-- 如果没有指定 database_name,默认为当前数 据库


全局锁
flush tables with read lock ;
mysqldump -uroot –p1234 itcast > itcast.sqlunlock tables ;


表级锁
加锁:lock tables 表名 read/write。
释放锁:unlock tables / 客户端断开连接 。

管理语句
mysql -uroot –p123456 db01 -e "select * from stu";//打开mysql的db01数据库并执行语句退出

mysqlbinlog -s log-files1 log-files2   #以short简单形式打开log文件

mysqlshow -uroot -p1234 --count   #查询每个数据库的表的数量及表中记录的数量
mysqlshow -uroot -p1234 db01 --count #统计db01数据库的每个表的行数和列数
mysqlshow -uroot -p1234 db01 course --count统计db01中course的列信息
mysqlshow -uroot -p1234 db01 course id --count查看数据库db01中的course表的id字段的信息

mysqldump -uroot -p1234 db01 > db01.sql    #备份db01数据库
source db01.sql								导入db01.sql

你可能感兴趣的:(数据库,mysql,sql,数据库)