DB:数据库(database):存储数据的“仓库”。它保存了一系列有组织的数据。
DBMS:数据库管理系统(Database Management System)。数据库是通过DBMS创
建和操作的容器
SQL:结构化查询语言(Structure Query Language):专门用来与数据库通信的语言
一、按条件表达式筛选
简单条件运算符:> < = != <> >= <=
二、按逻辑表达式筛选
逻辑运算符:
作用:用于连接条件表达式
&& || !
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');
#①查询每个部门的员工个数
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;
一、单行函数
字符函数:
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(字段)要高一些
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;
ALL、ANY常常用在子查询前面,表示子表中的所有和任何。
子查询可以放在where/And/Having,select,from,in/exist后面。
————————————————————————————————————————————————————————————————————————————————————————————————————————————————
子查询在where和having后面
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;
子查询在in或exists后面
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
)
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';
整型:分类:tinyint(1)、smallint(2)、mediumint(3)、int/integer(4)、bigint(8)
小数:定点数 浮点数
较短的文本:char、varchar
较长的文本:text、blob(较长的二进制数据)
整数
字节数tinyint:1、smallint:2、mediumint:3、int/integer:4、bigint:8
① 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加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
如果是float和double,则会根据插入的数值的精度来决定精度
③定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用
DROP TABLE tab_float;
CREATE TABLE tab_float(
f1 FLOAT(5,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
set型
CREATE 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());
六大约束
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 表名 add 【constraint 约束名】 约束类型(字段名) 【外键的引用】;
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;#设置增长步长
系统变量包括全局变量和会话变量
全局变量作用域:针对于所有会话(连接)有效,但不能跨重启
会话变量作用域:针对于当前会话(连接)有效
注意:全局变量需要添加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;
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语法:update 表1 别名,表2 别名set 列=值,...where 连接条件 and 筛选条件;
sql99语法:update 表1 别名 inner|left|right join 表2 别名 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语法:
delete 表1的别名,表2的别名
from 表1 别名,表2 别名
where 连接条件
and 筛选条件;
DELETE b
FROM beauty b
INNER JOIN boys bo ON b.`boyfriend_id` = bo.`id`
WHERE bo.`boyName`='张无忌';
sql99语法:
delete 表1的别名,表2的别名
from 表1 别名
inner|left|right join 表2 别名 on 连接条件
where 筛选条件;
DELETE b,bo
FROM beauty b
INNER JOIN boys bo ON b.`boyfriend_id`=bo.`id`
WHERE bo.`boyName`='黄晓明';
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]');
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。
脏读:在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.delete和truncate
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') $
索引语法
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.sql;
unlock 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