MySQL笔记

本文详细介绍了数据库的基本概念,如DB、DBMS和SQL,以及它们之间的关系。讨论了SQL语句的分类,如DQL、DML、DDL、TCL和DCL,提供了各种操作示例。还涵盖了SQL中的数据查询、排序、分组函数、子查询、连接查询、分页、存储引擎、事务处理和索引创建等内容,强调了索引在提高查询效率中的作用。此外,提到了视图的创建和作用,以及数据库设计的三范式和实际应用中的考虑因素。
摘要由CSDN通过智能技术生成

1.DB,DBMS与SQL

数据库:
   英文单词DataBase,简称DB。按照一定格式存储数据的一些文件的组合。
   顾名思义:存储数据的仓库,实际上就是一堆文件。这些文件中存储了
   具有特定格式的数据。
   数据库管理系统:
   DataBaseManagement,简称DBMS
   数据库管理系统是专门用来管理数据库中数据的,数据库管理系统可以
   对数据库当中的数据进行增删改查。
  
   常见的数据库管理系统:
   MySQL、Oracle、MS SqlServer、DB2、sybase等…
   SQL:结构化查询语言
   程序员需要学习SQL语句,程序员通过编写SQL语句,然后DBMS负责执行SQL
   语句,最终来完成数据库中数据的增删改查操作。
  
   SQL是一套标准,程序员主要学习的就是SQL语句,这个SQL在mysql中可以使用,
   同时在Oracle中也可以使用,在DB2中也可以使用。
  
   三者之间的关系?
   DBMS–执行–> SQL --操作–> DB
   mysql数据库启动的时候,这个服务占有的默认端口号是3306,这是大家都知道的事儿。记住。

2.SQL命令

2.1启动与关闭

net start 服务名
net stop 服务名

2.2mysql常用命令

登录:
mysql -u[name] -p[pwd]
退出:
exit
查看数据库:
show databases;
使用数据库:
use [db]
创建数据库:
create datebase [db];
查看表:
show tables;
查看数据库版本号:
select version();
查看当前数据库:
select database();

3.SQL语句

3.1 分类(DQL,DML,DDL,TCL,DCL)

DQL:
   数据查询语言(凡是带有select关键字的都是查询语句)
   select… 
DML:
   数据操作语言(凡是对表当中的数据进行增删改的都是DML)
   insert delete update
   insert 增
   delete 删
   update 改 
   这个主要是操作表中的数据data。  
DDL:
   数据定义语言
   凡是带有create、drop、alter的都是DDL。
   DDL主要操作的是表的结构。不是表中的数据。
   create:新建,等同于增
   drop:删除
   alter:修改
   这个增删改和DML不同,这个主要是对表结构进行操作。  
TCL:
   不是王牌电视。
   是事务控制语言
   包括:
   事务提交:commit;
   事务回滚:rollback;  
DCL:
   是数据控制语言。
   例如:授权grant、撤销权限revoke…

3.2 导入数据

导入sql
source [sql文件全路径]

3.3DQL查询语句

一般查询

查询一个表
select * from [table];
查看表结构 describe(描述)
desc [table];
按字段名查询:
select [字段], from [table]
起别名 as 或者空格
别名有空格时,需要引号括起来

条件查询(where)

= 等于
查询薪资等于800的员工姓名和编号?
  select empno,ename from emp where sal = 800;
<>或!= 不等于
   查询薪资不等于800的员工姓名和编号?
   select empno,ename from emp where sal != 800;
< > <= >=
   查询薪资小于2000的员工姓名和编号?
   mysql> select empno,ename,sal from emp where sal < 2000;
and or 并且 或者
and优先级比or高。 
between … and …. 两个值之间, 等同于 >= and <=
   查询薪资在2450和3000之间的员工信息?包括2450和3000
   select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;
   注意:
   使用between and的时候,必须遵循左小右大
   between and是闭区间,包括两端的值。
is null 为 null 或者=null (is not null 不为空)
   查询哪些员工的津贴/补助为null?
   select empno,ename,sal,comm from emp where comm = null;
in 包含,相当于多个 or (not in 不在这个范围中)
   查询工作岗位是MANAGER和SALESMAN的员工?
   select empno,ename,job from emp where job in(‘MANAGER’, ‘SALESMAN’);
like 称为模糊查询,支持%或下划线匹配
   %匹配任意多个字符
   下划线:任意一个字符。(%是一个特殊的符号,_ 也是一个特殊符号,查询时需要加\转义字符
   找出名字中含有O的?
   mysql> select ename from emp where ename like ‘%O%’;

排序

排序默认升序 order by:
select ename,sal from emp order byl sa;
指定升序order by [字段] asc:
select ename,sal from emp order by sal asc;
指定降序:order by [字段] desc
select ename,sal from emp order by sal desc;
多字段排序:order by [字段1] asc/desc,[字段2] asc/desc
查询员工名字和薪资,要求按照薪资升序,如果薪资一样的话,
   再按照名字升序排列。
   select
   ename,sal
   from
   emp
   order by
   sal asc, ename asc;
了解:根据字段的位置也可以排序
   select ename,sal from emp order by 2; // 2表示第二列。第二列是sal
   按照查询结果的第2列sal排序。
第一步:from
   第二步:where
   第三步:select
   第四步:order by(排序总是在最后执行!)

数据处理函数(单行处理函数)

常用的:
lower
upper
substr
concat
length
tirm
round
rand
ifnull

单行处理函数的特点:一个输入对应一个输出
常见的有:
lower 转小写
   mysql> select lower(ename) as ename from emp;
upper 转换大写
   mysql> select upper(name) as name from t_student;
substr 取子串(substr( 被截取的字符串, 起始下标,截取的长度))
   select substr(ename, 1, 1) as ename from emp;
   注意:起始下标从1开始,没有0.
concat函数进行字符串的拼接
   select concat(empno,ename) from emp;
   首字母大写?
select concat(upper(substr(name,1,1)),substr(name,2,length(name) - 1)) as result from t_student;
length 取长度
   select length(ename) as enamelength from emp;
trim 去空格
   mysql> select * from emp where ename = ’ KING’;
数据格式设置函数
str_to_date 将字符串转换成日期
   date_format 格式化日期
   format 设置千分位
case…when…then…when…then…else…end
   当员工的工作岗位是MANAGER的时候,工资上调10%,当工作岗位是SALESMAN的时候,工资上调50%,其它正常。
   (注意:不修改数据库,只是将查询结果显示为工资上调)
   select
   ename,
   job,
   sal as oldsal,
   (case job when ‘MANAGER’ then sal1.1 when ‘SALESMAN’ then sal1.5 else sal end) as newsal
   from
   emp;
round四舍五入
结论:select后面可以跟某个表的字段名(可以等同看做变量名),也可以跟字面量/字面值(数据)
select round(1236.567, 1) as result from emp; //保留1个小数
rand()生成随机数
mysql> select round(rand()*100,0) from emp; // 100以内的随机数
ifnull函数用法:ifnull(数据, 被当做哪个值)
补助为NULL的时候,将补助当做0
   select ename, (sal + ifnull(comm, 0)) * 12 as yearsal from emp;

分组函数(多行处理函数)

5个:
** count 计数
   sum 求和
   avg 平均值
   max 最大值
   min 最小值**
分组函数在使用的时候需要注意哪些?
   第一点:分组函数自动忽略NULL,你不需要提前对NULL进行处理。
   第二点:分组函数中count(*)表示行数, count(具体字段)表示该字段非空行数.
第三点:分组函数不能够直接使用在where子句中,需要分组 group by.

分组查询(重点)

书写顺序select … from … where … group by… order by …
  
   以上关键字的顺序不能颠倒,需要记忆。
   执行顺序是什么?
   1. from
   2. where
   3. group by
   4. select
   5. order by

为什么分组函数不能直接使用在where后面?
   select ename,sal from emp where sal > min(sal);//报错。
   因为分组函数在使用的时候必须先分组之后才能使用
   where执行的时候,还没有分组。所以where后面不能出现分组函数。
   select sum(sal) from emp;
   这个没有分组,为啥sum()函数可以用呢?
   因为select在group by之后执行。
重点结论:
   在一条select语句当中,如果有group by语句的话,
   select后面只能跟:参加分组的字段,以及分组函数。
   其它的一律不能跟。

使用having可以对分完组之后的数据进一步过滤
   having不能单独使用,having不能代替where,having必须
   和group by联合使用。
   找出每个部门最高薪资,要求显示最高薪资大于3000的?
   select deptno,max(sal)
   from emp
   group by deptno
   having max(sal)>3000
   优化策略:
   select deptno,max(sal)
   from emp
   where sal >3000
   group by deptno
   where和having,优先选择where,where实在完成不了了,再选择 having

去重函数distinct

distinct 只能出现在所有字段的最前方
     mysql> select ename,distinct job from emp; 
distinct出现在job,deptno两个字段之前,表示两个字段联合起来去重。
     mysql> select distinct job,deptno from emp;

连接查询(重点)

根据表连接的方式分类:
     内连接:
     等值连接
     非等值连接-
     自连接
     外连接:
     左外连接(左连接)
     右外连接(右连接)
     全连接(不讲)
当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象

内连接(SQL99语法)

等值连接
select
     …
from
    a
(inner)join
    b
on
    a和b的连接条件 // 条件是等量关系,所以被称为等值连接。
where 筛选条件
非等值连接
找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级
select
     e.ename, e.sal, s.grade
    from
     emp e
    join
     salgrade s
    on
     e.sal between s.losal and s.hisal; // 条件不是一个等量关系,称为非等值连接。
自然连接
查询员工的上级领导,要求显示员工名和对应的领导名
select
     a.ename as ‘员工名’, b.ename as ‘领导名’
    from
     emp a
    join
     emp b
    on
     a.mgr = b.empno; //员工的领导编号 = 领导的员工编号

外连接

右外连接
select
     e.ename,d.dname
    from
     emp e
    right (outer) join
     dept d
    on
     e.deptno = d.deptno;
    
    right代表什么表示将join关键字右边的这张表看成主表,主要是为了将
    这张表的数据全部查询出来,捎带着关联查询左边的表。
    在外连接当中,两张表连接,产生了主次关系。
左外连接
select
     e.ename,d.dname
    from
     dept d
    left join
     emp e
    on
     e.deptno = d.deptno;
    // outer是可以省略的,带着可读性强。
带有right的是右外连接,又叫做右连接。
    带有left的是左外连接,又叫做左连接。
    任何一个右连接都有左连接的写法。
    任何一个左连接都有右连接的写法。
思考:外连接的查询结果条数一定是 >= 内连接的查询结果条数?
     正确。

子查询

select语句中嵌套select语句,被嵌套的select语句称为子查询。
select
     …(select).
     from
     …(select).
     where
     …(select)

     找出比最低工资高的员工姓名和工资?
     select ename,sal from emp where sal > (select min(sal) from emp);
from子句中的子查询
     注意:from后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)
出每个岗位的平均工资的薪资等级
select
     t.*, s.grade
     from
     (select job,avg(sal) as avgsal from emp group by job) t
     join
     salgrade s
     on
     t.avgsal between s.losal and s.hisal;

union合并查询结果集

查询工作岗位是MANAGER和SALESMAN的员工?
select ename,job from emp where job = ‘MANAGER’
     union
     select ename,job from emp where job = ‘SALESMAN’;
union的效率要高一些。对于表连接来说,每连接一次新表,
     则匹配的次数满足笛卡尔积,成倍的翻。。。
     但是union可以减少匹配的次数。在减少匹配次数的情况下,
     还可以完成两个结果集的拼接。
// MYSQL可以,oracle语法严格 ,不可以,报错。要求:结果集合并时列和列的数据类型也要一致

limit(非常重要)

limit作用:将查询结果集的一部分取出来。通常使用在分页查询当中。
完整用法:limit startIndex, length
起始下标从0开始。
缺省用法:limit 5; 这是取前5.
mysql当中limit在order by之后执行!!!!!!

limit分页(重点)

每页显示pageSize条记录
     第pageNo页:limit (pageNo - 1) * pageSize , pageSize
select
     …
     from
     …
     where
     …
     group by
     …
     having
     …
     order by
     …
     limit
     …
    
     执行顺序?
     1.from
     2.where
     3.group by
     4.having
     5.select
     6.order by
     7.limit…

3.4 DDL数据定义语言

建表create

表名:建议以t_ 或者 tbl_开始,可读性强。见名知意。
create table 表名(
     字段名1 数据类型(大小),
     字段名2 数据类型(大小),
     字段名3 数据类型(大小)
     );

数据类型

char 定长字符串 255
varcher 可变长字符串 255
int 11
bigint
float
double
date短日期
datetime长日期
clob大字符串
blob大二进制(存图片)

删表drop

drop table t_student; // 当这张表不存在的时候会报错!
drop table if exists t_student;// 如果这张表存在的话,删除

truncate表截断

大表非常大,上亿条记录????
   删除的时候,使用delete,也许需要执行1个小时才能删除完!效率较低。
   可以选择使用truncate删除表中的数据。只需要不到1秒钟的时间就删除结束。效率较高。

alter字段修改

3.5DML数据操作语言

insert

insert into t_student(no,name,sex,age,email)
values(1,‘zhangsan’,‘m’,20,‘zhangsan@123.com’);
注意:字段名可省略,但字段名和值要一一对应。什么是一一对应?
     数量要对应。数据类型要对应。
插入时,可以用格式函数来改变格式
str_to_date:将字符串varchar类型转换成date类型
date_format:将date类型转换成具有一定格式的varchar字符串类型。
format(数字, ‘格式’):格式化数字

update

语法格式:
     update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3… where 条件;
注意:没有条件限制会导致所有数据全部更新。

delete

语法格式:
     delete from 表名 where 条件;
注意:没有条件,整张表的数据会全部删除!

4.约束

4.1五种约束

约束包括哪些
非空约束:not null
   唯一性约束: unique
   主键约束: primary key (简称PK)
   外键约束:foreign key(简称FK)
   检查约束:check(mysql不支持,oracle支持)

4.2唯一性约束

唯一性约束unique约束的字段不能重复,但是可以为NULL
**如何是两个字段联合起来唯一呢**
怎么创建这样的表,才能符合新需求呢?

drop table if exists t_vip;
   create table t_vip(
   id int,
   name varchar(255),
   email varchar(255),
   unique(name,email) // 约束没有添加在列的后面,这种约束被称为表级约束
在mysql当中,如果一个字段同时被not null和unique约束的话,
   该字段自动变成主键字段。

4.3主键约束

一张表,主键约束只能添加1个。(主键只能有1个。)
不建议使用:varchar来做主键。主键值一般都是数字,一般都是定长的!
主键除了:单一主键和复合主键之外,还可以这样进行分类?
   自然主键:主键值是一个自然数,和业务没关系。
   业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。这就是业务主键!
auto_increment表示自增,从1开始,以1递增! 
id int primary key auto_increment

4.4外键约束(重要)

创建表的顺序?
   先创建父,再创建子。
删除数据的顺序?
   先删子,再删父。
插入数据的顺序?
   先插入父,再插入子。
  思考:子表中的外键引用的父表中的某个字段,被引用的这个字段必须是主键吗?
   不一定是主键,但至少具有unique约束。
   测试:外键可以为NULL吗?
   外键值可以为NULL。

5.存储引擎

5.1 概念

实际上存储引擎是一个表存储/组织数据的方式。
 不同的存储引擎,表存储数据的方式不同。

5.2 给表添加存储引擎

	CREATE TABLE `t_student` (
  	  `no` int(11) NOT NULL AUTO_INCREMENT,
  	  `name` varchar(255) DEFAULT NULL,
  	  `cno` int(11) DEFAULT NULL,
  	  PRIMARY KEY (`no`),
  	  KEY `cno` (`cno`),
  	  CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`)
  	) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
		ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8

在建表的时候可以在最后小括号的")"的右边使用:
   ENGINE来指定存储引擎。
   CHARSET来指定这张表的字符编码方式。
   结论:
   mysql默认的存储引擎是:InnoDB
   mysql默认的字符编码方式是:utf8

查看支持的存储引擎:show engines \G
mysql支持九大存储引擎

5.3各大存储引擎优点

InnoDB:支持事务,数据库崩溃后悔自动恢复
MyISAM:可压缩,省空间,不支持事务
MEMORY:查询效率最高,但关机后数据消失

6.事务

6.1 概况

一个事务其实就是一个完整的业务逻辑
是一个最小的工作单元。不可再分
本质上,一个事务其实就是多条DML语句同时成功,或者同时失败!

6.2 事务开启,提交与回滚

start transaction开启事务(停止自动提交)
commit提交
rollback回滚
事务对应的英语单词是:transaction

6.2事务的隔离性四个级别

读未提交:read uncommitted(最低的隔离级别)《没有提交就读到了》
读已提交:read committed《提交之后才能读到》
可重复读:repeatable read《提交之后也读不到,永远读取的都是刚开启事务时的数据》
序列化/串行化:serializable(最高的隔离级别)synchronized

7. 索引

7.1概述

索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。
一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引
索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制。

7.2索引的实现

提醒1:在任何数据库当中 主键上都会自动添加索引对象,id字段上自动有索引,
因为id是PK。另外在mysql当中, ** 一个字段上如果有unique约束**的话,也会自动
创建索引对象。

提醒2:在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有
一个硬盘的物理存储编号

提醒3:在mysql当中,索引是一个单独的对象,不同的存储引擎以不同的形式
存在,在MyISAM存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中
索引存储在一个逻辑名称叫做tablespace的当中。在MEMORY存储引擎当中索引
被存储在内存当中。不管索引存储在哪里,索引在mysql当中都是一个树的形式
存在。(自平衡二叉树:B-Tree)‘’

7.3 索引应用场景

条件1:数据量庞大(到底有多么庞大算庞大,这个需要测试,因为每一个硬件环境不同)
条件2:该字段经常出现在where的后面,以条件的形式存在,也就是说这个字段总是被扫描。
条件3:该字段很少的DML(insert delete update)操作。(因为DML之后,索引需要重新排序。)

建议不要随意添加索引,因为索引也是需要维护的,太多的话反而会降低系统的性能。
建议通过主键查询,建议通过unique约束的字段进行查询,效率是比较高的。

7.4索引创建

创建索引:
mysql> create index emp_ename_index on emp(ename);
给emp表的ename字段添加索引,起名:emp_ename_index

删除索引:
mysql> drop index emp_ename_index on emp;
将emp表上的emp_ename_index索引对象删除。

7.5索引失效

失效的第1种情况:%开头
select * from emp where ename like ‘%T’;
失效的第2种情况: or只有一个有索引
使用or的时候会失效,如果使用or那么要求or两边的条件字段都要有
索引,才会走索引,如果其中一边有一个字段没有索引,那么另一个
字段上的索引也会实现。
失效的第3种情况:
使用复合索引的时候,没有使用左侧的列查找,索引失效
什么是复合索引?
两个字段,或者更多的字段联合起来添加一个索引,叫做复合索引。
失效的第4种情况:
在where当中索引列参加了运算,索引失效。
mysql> create index emp_sal_index on emp(sal);
失效的第5种情况:
在where当中索引列使用了函数

8.视图

view:站在不同的角度去看待同一份数据

8.1 视图创建与删除

创建视图对象:
create view dept2_view as select * from dept2;

删除视图对象:
drop view dept2_view;

注意:只有DQL语句才能以view的形式创建。
create view view_name as 这里的语句必须是DQL语句;

8.1视图的作用

我们可以面向视图对象进行增删改查,对视图对象的增删改查,会导致
原表被操作
!(视图的特点:通过对视图的操作,会影响到原表数据。)

//面向视图查询*
select * from dept2_view;
// 面向视图插入
insert into dept2_view(deptno,dname,loc) values(60,‘SALES’, ‘BEIJING’);
// 查询原表数据
mysql> select * from dept2;

假设有一条非常复杂的SQL语句,而这条SQL语句需要在不同的位置上反复使用。
每一次使用这个sql语句的时候都需要重新编写,很长,很麻烦,怎么办?
可以把这条复杂的SQL语句以视图对象的形式新建
在需要编写这条SQL语句的位置直接使用视图对象,可以大大简化开发
并且利于后期的维护,因为修改的时候也只需要修改一个位置就行,只需要
修改视图对象所映射的SQL语句。
个人理解:为了方便维护和修改select语句查询到的内容

9.DBA数据库管理常用命令

9.1 数据的导入导出(会用)

数据导出?
注意:在windows的dos命令窗口中:
mysqldump bjpowernode>D:\bjpowernode.sql -uroot -p123456
可以导出指定的表吗?
mysqldump bjpowernode emp>D:\bjpowernode.sql -uroot -p123456

数据导入?
注意:需要先登录到mysql数据库服务器上。
然后创建数据库:create database bjpowernode;
使用数据库:use bjpowernode
然后初始化数据库:source D:\bjpowernode.sql

10 数据库三范式

10.1三范式介绍

第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分。

第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,
不要产生部分依赖。设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。

第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,
不要产生传递依赖。设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X

10.2 数据库设计

一对多:
一对多,两张表,多的表加外键!!!!!!!!!!!!

多对多:
多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!

一对一:
一对一放到一张表中不就行了吗?为啥还要拆分表?
在实际的开发中,可能存在一张表字段太多,太庞大。这个时候要拆分表。
最终的目的都是为了满足客户的需求,有的时候会拿冗余换执行速度。
因为在sql当中,表和表之间连接次数越多,效率越低。(笛卡尔积)
有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值