【学习:Mysql数据库三】

七、mysql函数

7.1 日期和时间相关的函数

这里写图片描述
案例一
这里写图片描述
案例二:date() 显示所有留言信息,发布日期
这里写图片描述
案例三:date_add() 查询在10分钟内发布的帖子
这里写图片描述

1、date_add() 中的interval 可以是 year、 minute、second、day
2、date_sub() 中的interval 可以是 year、 minute、second、day

案例四:datediff() 求出 2018-7-17 和 1990-1-1 相差多少天
这里写图片描述

7.1.1 unix_timestamp()和 from_unixtime()

unix_timestamp() 可以返回一个从1970-1-1:00:00:00 到现在的一个秒数,就是一个数值
这里写图片描述
from_unixtime(unix时间戳,日期格式) 可以将一个unix时间戳(从1970-1-1:00:00:00 到现在的一个秒数),转成一个你指定的日期格式.日期格式如下:'%Y-%m-%d %H-%i-%s'
这里写图片描述

7.2 字符串相关函数

这里写图片描述
案例一: concat 连接字串
这里写图片描述
案例二:ucase、lcase 转换大写、小写
这里写图片描述 这里写图片描述

7.3 数学相关函数

这里写图片描述

7.4 流程控制相关函数

这里写图片描述

7.5 其它函数

这里写图片描述
这里写图片描述

八、mysql查询加强

8.1 查看表结构

desc 表名
这里写图片描述
show create table 表名 显示详细的表结构
这里写图片描述

8.2 where子句

案例

// 1、查找2016.8.8后入职的员工
select * from `company` where entryDate > '2016-08-08';

// 2、查找第三个字符为大写O的所有员工的姓名和工资
// [ % 表示任意0到多; _ 表示任意单个字符]
select name,sal from `company` where name like '__O%';

// 3、查找没有上级的雇员的数据
select * from `cmpany` where up_level is null;

8.3 逻辑运算符

案例

// 1、查询工资高于500或是岗位为manager的雇员,同时还要满足他们的姓名首写字母为大写的J
select * from `company where (sal>500 or job='manager') and name like 'J%';

// 2、查找按照部门号升序而雇员的工资降序排列
select * from `company order by deptono, sal desc;   //默认是asc升序

// 3、对所有员工的年工资(薪水 + 奖金)进行排序
select name, (sal + ifnull(bonus,0))*12 AS totalSal from `company` order by totalSal;

8.4 分页查询

案例

当前页:$pageNow   页面显示记录数: $pageSize

// 代码
SELECT * FROM 表名 WHERE子句 LIIMT ($pageNow-1) * $pageSize , $pageSize;

8.5 统计函数max,min,sum,avg,count加强

// 1、查询工资最高的员工的信息 
select * from emp where sal = (select max(sal) from emp); //第一种写法
select * from emp order by sal desc limit 1;              //第二种写法         

// 2、工资高于平均工资的员工信息
select * from emp where sal > (select avg(sal) from emp);

8.6 group by 和 having 加强

// 1、每个部门的平均工资和最高工资
select avg(sal), max(sal), deptno from emp group by deptno;

// 2、每个部门的每种岗位的平均工资和最低工资
select avg(sal), min(sal), deptno from emp group by deptno, job;

// 3、平均工资低于2000的部门号和它的平均工资
select deptno,avg(sal) AS avgSal from emp group by deptno having avgSal < 2000;

// 4、统计各个部门的雇员的数量, 并且显示部门的编号
select deptno, count(*) from emp group by deptno;

// 5、统计雇员总数,以及奖金大于300的雇员数
select count(*) as '总人数', count(if(bonus > 300, 0, null)) as '奖金' from emp;

综合案例

// 统计各个部门的平均工资,并且是大于1000的,并且按照平均工资从高到低排序
select avg(sal) AS avgSal, deptno from emp group by deptno having avgSal > 1000 
order by avgSal desc;

九、多表操作

9.1 多表操作案例

数据表结构

// 部门表
Create Table: CREATE TABLE `dept` (
  `deptno` mediumint(8) unsigned NOT NULL DEFAULT '0',  /*部门编号*/
  `dname` varchar(20) NOT NULL DEFAULT '',  /*名字*/
  `loc` varchar(13) NOT NULL DEFAULT ''  /*部门代号码*/
) ENGINE=MyISAM DEFAULT CHARSET=utf8

// 雇员表
CREATE TABLE `emp`(
    `empno` MEDIUMINT UNSIGNED  NOT NULL  DEFAULT 0,  /*雇员编号*/
    `ename` VARCHAR(20) NOT NULL DEFAULT "",   /*名字*/
    `job` VARCHAR(9) NOT NULL DEFAULT "",   /*工作*/
    `mgr` MEDIUMINT UNSIGNED ,   /*上级编号*/
    `hiredate` DATE NOT NULL,   /*入职时间*/
    `sal` DECIMAL(7,2)  NOT NULL,   /*薪水*/
    `comm` DECIMAL(7,2) ,/*奖金*/
    `deptno` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/
)ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

// 工资级别表
CREATE TABLE `salgrade`(
    `grade` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,  /*级别*/
    `losal` DECIMAL(17,2)  NOT NULL,   /*最低值*/
    `hisal` DECIMAL(17,2)  NOT NULL   /*最高值*/
)ENGINE=MyISAM DEFAULT CHARSET=utf8;

临时插入数据

// 1、`emp` 雇员表
INSERT INTO `emp` VALUES(7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800.00,NULL , 20), 
(7499, 'ALLEN', 'SALESMAN', 7698, '1981-2-20', 1600.00, 300.00, 30),  
(7521, 'WARD', 'SALESMAN', 7698, '1981-2-22', 1250.00, 500.00, 30),  
(7566, 'JONES', 'MANAGER', 7839, '1981-4-2', 2975.00,NULL,20),  
(7654, 'MARTIN', 'SALESMAN', 7698, '1981-9-28',1250.00,1400.00,30),  
(7698, 'BLAKE','MANAGER', 7839,'1981-5-1', 2850.00,NULL,30),  
(7782, 'CLARK','MANAGER', 7839, '1981-6-9',2450.00,NULL,10),  
(7788, 'SCOTT','ANALYST',7566, '1987-4-19',3000.00,NULL,20),  
(7839, 'KING','PRESIDENT',NULL,'1981-11-17',5000.00,NULL,10),  
(7844, 'TURNER', 'SALESMAN',7698, '1981-9-8', 1500.00, NULL,30),  
(7900, 'JAMES','CLERK',7698, '1981-12-3',950.00,NULL,30),  
(7902, 'FORD', 'ANALYST',7566,'1981-12-3',3000.00, NULL,20),  
(7934,'MILLER','CLERK',7782,'1982-1-23', 1300.00, NULL,10);

// 2、`dept` 部门表
INSERT INTO `dept` VALUES
(10, 'ACCOUNTING', 'NEW YORK'), 
(20, 'RESEARCH', 'DALLAS'), 
(30, 'SALES', 'CHICAGO'), 
(40, 'OPERATIONS', 'BOSTON');

// 3、`salgrade` 工资级别表
INSERT INTO `salgrade` VALUES 
(1,700,1200),
(2,1201,1400),
(3,1401,2000),
(4,2001,3000),
(5,3001,9999);

案例

// 1、查询各个员工的姓名,工资,及其工资的级别(losal低值,hisal高值 => 对应级别)
SELECT ename,sal,grade FROM emp,salgrade WHERE sal BETWEEN losal AND hisal;

// 2、查询雇员名,雇员工资及所在部门的名字,并按部门排序
SELECT ename, sal, dname, emp.deptno FROM emp, dept WHERE emp.deptno=dept.deptno 
ORDER BY emp.deptno;

// 3、查询出 雇员的名字,薪水,工作, 部门的名称,工资的级别
SELECT ename, sal, job, dname, grade FROM emp, dept, salgrade WHERE 
emp.deptno = dept.deptno AND  emp.sal BETWEEN losal AND hisal;

9.2 自连接

需要将一个张表当做多表使用时,就会使用到自连接

// 1、某‘FORD’员工的上级领导的姓名 [mgr: 上级领导代号]
SELECT * FROM emp WHERE empno = (SELECT mgr FROM emp WHERE name ='FORD');

// 2、显示公司每个员工名字和他的上级的名字 [把emp表当做是两个表来看 emp 是 worker , emp是boss]
SELECT worker.ename AS '雇员', boss.ename AS '上级领导' FROM emp AS worker, 
emp AS boss WHERE worker.mgr = boss.empno;

9.3 子查询

子查询是指嵌入在其它sql查询语句中的select语句,也叫嵌套查询

单行子查询: 单行子查询是指只返回一行数据的子查询语句

// 查询与 SMITH 同一部门的所有员工
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'SMITH');

多行子查询: 多行子查询指返回多行数据的子查询 使用关键字in

// 查询和10号部门的工作相同的雇员的
SELECT ename, job, sal, deptno FROM emp WHERE job IN
(SELECT  DISTINCT  job  FROM emp WHERE deptno=10) AND deptno!=10;

综合案例

// 查询`ggods`中各类别中,价格最高的商品
// [1、先按照类别进行排序,然后再按照价格进行排序]
SELECT goods_id,cat_id,goods_name, shop_price FROM `goods` ORDER BY 
cat_id, shop_price DESC;                                             // 第一步

// [2、如何取出排序后,各个类别中的第一条记录. mysql在默认情况下,进行分组时,会默认的返回第一条
//     记录,这里我们就需要使用到这个特点]
SELECT * FROM (select goods_id,cat_id,goods_name, shop_price from ecs_goods 
order by cat_id, shop_price desc) AS temp  GROUP  BY temp.cat_id;    // 第二步

9.4 all操作符

在多行子查询中使用 all 操作符

// 如何显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
SELECT * FROM `emp` where sal > all(SELECT sal FROM `emp` where deptno = 30);

9.5 any操作符

在多行子查询中使用 any 操作符

// 如何显示工资比部门30的其中一个员工的工资高的员工的姓名、工资和部门号
SELECT * FROM `emp` where sal > any(SELECT sal FROM `emp` where deptno = 30);

9.6 多列子查询

如果我们的一个子查询,他返回的结果是含有多列数据. 这个就叫做多列 子查询

// 请查询和'特朗普'数学,英语,语文成绩完全相同的学生 [主要:(字段1,字段2)=(字段1,字段2)]
SELECT name  FROM  `student` WHERE  (math, english,chinese) =
(SELECT math, english, chinese FROM `student` WHERE name ='特朗普') AND name <>'特朗普';

9.7 蠕虫复制(自我复制)

在我们项目开发中,我们有时需要快速的创建一张大表进行测试, 这时我们可以进入表的自我复制

// 语法
insert into 表名 select * from 表名 ;

引出问题?
例如 ‘emp’ 表有100万条数据,但有重复的,如何去重?

// 1、创建一个'temp_emp'表,表的结构和'emp'一模一样
create table `temp_emp` like `emp`;

// 2、将'emp'表中进行 distinct 的数据插入到'tempemp'表
insert into `temp_emp` select distinct * from `emp`;

// 3、truncat table 'emp', 把数据库清空
truncate table `emp`;

// 4、将'tempemp'数据重新导入到'emp'表
insert into `emp` select * from `temp_emp`;

// 5、'tempemp'表删除(drop)
drop table `temp_emp`;

9.8 合并查询

有时在实际应用中,为了合并多个select语句的结果,可以使用集合操作符号 union, union all

union 是将多个select的结果进行合并,但是是自动的去掉重复的记录

SELECT 语句 UNION  SELECT 语句

union all 是将多个select的结果进行合并,但是不会去掉重复的记录

SELECT 语句 UNION ALL  SELECT 语句;

十、表的内连接和外连接

10.1 内连接

// 语法
SELECT 字段列表 FROM1, 表2 WHERE 子句 条件1 AND 条件2...      // 第一种写法【推荐】
SELECT 字段列表 FROM1 inner join2 ON 条件1 AND 条件2...   // 第二种写法

外连接

左外连接 左侧表主表(全显示)
右外连接 右侧表主表(全显示)

SELECT  字段列表  FROM  表1  left  join  表2  ON 条件...   // 左外链接
SELECT  字段列表  FROM  表1  right join  表2  ON 条件...   // 右外连接

十一、mysql数据库的约束

主键约束(primary key) 当我们将一个字段设置为primary key 在字段不能为null, 而且不可以重复;可以是复合主键

唯一约束(unique) 当我们将一个字段设置为唯一约束后,该字段不可以重复,能否为null, 要看你有没有设置 not null

非空约束(not null) 将一个字段设置为not null 该字段就不可以为 null

外键约束(foreign key) 将一个字段设置为foreign key 该字段的值,就依赖于对应的主表的字段, 即foreign key 的字段的值,就不能随意给. 而是根据业务逻辑在添加;存储引擎必须是InnoDB

检查约束(check) 一个字段设置为check后,就必须满足check条件,才可以添加成功比如 age tinyint check(age >=0 AND age<=120); 在主流的数据库比如sql server ,oracle等都支持check ,mysql目前支持语法,但是不生效

删除约束

// 对于not null 、 check、unique 约束直接使用modify 就可以搞定
alter  table   表名  modify  重新定义字段即可

// 对应主键的删除
alter  table   表名  drop  primary key;

// 外键约束的删除
alter  table  表名 drop foreign key 外键名;

十二、索引

说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的'create index',查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的(影响很小),这些写操作,增加了大量的I/O
创建索引

CREATE  INDEX  索引名  ON  表名(列名);   // 原理B+树 二分查找

删除索引

alter  table  表名  drop  index 索引名;  // 1.删除非主键索引
alter  table  表名  drop  primary  key; // 2.删除主键索引

索引影响

1、磁盘占用很多
2、第insert ,delete ,updae会影响, 因为进行删除,添加,修改记录后,会对索引进行维护,因此会花费时间

索引分类
主键索引 当我们将某个字段设置成primary key后,这个字段就自动的成为主键索引.
唯一索引 当我们将某个字段设置成unique后,这个字段就自动的成为唯一索引.
普通索引 当我们给某个字段进行create index 操作后,该字段就是一个普通索引,普通索引是我们开发中使用的最多的。他不要求字段内容必须唯一.
全文索引 当我们需要对文章,文字进行关键字检索时,就可以使用到全文索引.

(1) mysql 支持全文索引,但是有几个需要注意的地方, 默认只支持对英文的全文索引,只有myisam存储引擎可以使用全文索引
(2) 如果我们需要对中文进行全文索引,那我们需要使用其它的相关技术(coreseeksphinx的中文版, 目前还有其它技术比如 xusearch迅搜等中文检索技术)

十三、事务

13.1 事务操作

事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败。如:网上转账就是典型的要用事务来处理,用以保证数据的一致性

// 1、开始事务
start  transaction;
// 2、创建一个保存点a
savepoint a;
// 3、删除操作
delete from `account` where id=10;
// 4、创建一个保存点b
savepoint b;
// 5、回退到保存点a
rollback to savepoint a;
// 6、如果用户确认没有任何的问题,则提交, 当提交后事务就结束了,也不能回退了
commit;

事务控制细节

1、如果开始事务后,没有设置保存点,那么默认会创建一个保存点.
2、一个事务可以有多个保存点,但是我们在回退时,必须顺序回退.
3、存储引擎:如果需要使用事务,那么该存储引擎需要是innodb的.
4、开启事务的方式
start transaction;
set autocommit=false;

13.2 事务隔离级别

13.2.1 隔离级别

当不同的客户端或是是一个线程,去访问mysql数据的同一张表时,mysql提供一种机制,来控制不同的客户端线程对数据访问的权限. 隔离级别定义了事务与事务之间的隔离程度, 在不同的事务中,看到数据是不一样的
1、读未提交(read uncommited)
2、读已提交(read commited)
3、可重复读(repeatable read)
4、可串行化(serializable)

13.2.2 隔离级别影响

脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读.

不可重复读 :同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生不可重复读。

幻读 :同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻读。

设置当前shiwu隔离级别

set  session  trnasaction   isolation  level  隔离级别;

13.2.3 可串行化(serializable)

可串行化,是最强的一种隔离级别,他不会出现脏读,不可重复读,幻读。 他在进行读操作时进行加锁,加锁后,其它的客户端就不可以进行dml(insert,update,delete)操作,但是读(select).

13.2.4 隔离级别的常用命令

1、查看当前会话隔离级别
select @@tx_isolation;
2、查看系统当前隔离级别
select @@global.tx_isolation;
3、设置当前会话隔离级别
set session transaction isolation level repeatable read;
4、设置系统当前隔离级别
set global transaction isolation level repeatable read;
5、mysql 默认的事务隔离级别是 repeatable read ,一般情况下,没有特殊要求,没有必要修改(因为该级别可以满足绝大部分项目需求)

13.3 事务的acid特性

原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
隔离性(Isolation) 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability) 持久性是指一个事务一旦被提交commit,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

十四、表的存储引擎

这里写图片描述

myisam存储引擎的特点
1、速度快
2、不支持事务,不支持外键
3、容易产生碎片,因此需要定义的进行碎片整理 optimize table tablename
4、如果不需要事务安全控制,那么一般情况都选用myisam
5、默认只有myisam支持全文索引

innodb存储引擎的特点
1、并发性很好
2、支持事务,支持外键
3、如果需要事务安全的话,只能选用innodb
4、目前很多项目开始选用innodb作为存储引擎,而且mysql默认就是innodb

memory存储引擎
1、数据是存放在内存中的, 这样速度很快 [内存 > 普通文件 > 数据库]
2、memory存储引擎的表,一般来说就是存少量的数据
3、一般来说,频繁变化的,不需要实时入库的数据,不是特别重要的数据可以考虑放到memory存储引擎,经典的用法 (用户的状态)
4、当我们重启mysql后,我们的数据就没有的. 但是表的结构还在

14.1 存储引擎的修改

alter  table  表名  engine=指定的引擎;

十五、mysql用户管理

15.1 数据库的用户介绍

这里写图片描述

创建用户

create user ‘用户名’@’允许登录位置’  identified by '密码'; 

删除用户

drop user  '用户名'@'登录ip'

修改密码

// 1、给自己修改密码
mysql> set  password = password('新密码');       

// 2、如何给指定用户修改密码,一般来说是root用户给别人修改
mysql> set  password  for  '用户'@'登录地址' =password(' 新密码 ');

给用户赋权限
这里写图片描述

grant 权限列表 on  库.对象名  to  ‘用户名’@’登录位置’  [identified  by ‘密码’];

1、赋权限的关键字是 grant on to
2、权限列表可以从权限上找,常见的有 select ,update,insert ,delete… 如果希望把所有的权限给该用户可以使用 all
3、库.对象名: 库表是数据库的名称,对象名是指的该库的所有数据对象(表,视图,过程,函数等等)
如果希望将某个库的所有对象给 库名.*
如果希望将把所有库的所有对象给 .
4、identified by 是可选项

1、如果用户存在,则相当于是修改密码
2、如果用户不存在,则相当与创建用户,并指定密码和权限

回收权限

revoke 权限列表  on  库.对象名  from  '用户名"@"登录位置';
// 例如: rovoke delete on mydb.user from 'zs"@"localhost' ;

让权限立即生效

FLUSH PRIVILEGES;

查询某个用户的当前有哪些权限

show grants for 'zs"@"localhost';

权限细节说明

在创建用户的时候,如果不指定Host, 则为% , %表示表示所有IP都有连接权限
create user xxx; [在项目开发,一定要避免root 可以远程登录]
你也可以这样指定
create user ‘xxx’@’192.168.0.%’ 表示 xxx用户在 192.168.0.*的ip可以登录mysql
在删除用户的时候,如果 host 不是 %, 需要明确指定 '用户'@'host值'

15.2 如何找回丢失的root密码

1、关闭mysql服务器 net stop mysql
2、使用 mysqld.exe进行重启,重启时需要指定参数 mysqld.exe --skip-grant-tables
3、新开客户端 mysql.exe,使用mysql连接进入服务器
4、查看用户及密码 select user,password,host from use
5、修改密码 update user set password=password('root') where user='root' and host= 'localhost'
6、退出服务器重启服务器
7、修改密码 mysqladmin.exe -hlocalhost -uroot -p111111 password 123456

猜你喜欢

转载自blog.csdn.net/hello_sgw/article/details/81075042
今日推荐