MySQL学习笔记
MySQL学习
MySQL的连接
启动服务
通过管理员身份运行
格式:net start 服务名(启动服务)
1 | net start mysql57 |
停止服务
net stop 服务名(停止服务)
1 | net stop mysql57 |
连接数据库
mysql -u 用户名 -p
1 | mysql -u root -p |
断开连接
1 | exit 或 ctrl+C |
查看服务器的版本
方式一:登录到mysql服务端
1
select version();
方式二:没有登录到mysql服务端
1
mysql --version 或 mysql --V
显示时间-登录到MySQL服务端之后
1 | select now(); |
远程连接
1 | mysql -h IP地址 -u 用户名 -p 对方mysql密码 |
MySQL数据类型和基本操作
数据类型
二进制类型
bit
1 | bit[(M)] |
整数类型
tinyint
1 | tinyint[(m)] [unsigned] [zerofill] |
int
1 | int[(m)][unsigned][zerofill] |
bigint
1 | bigint[(m)][unsigned][zerofill] |
小数型
decimal
1 | decimal[(m[,d])] [unsigned] [zerofill] |
FLOAT
1 | FLOAT[(M,D)] [UNSIGNED] [ZEROFILL] |
DOUBLE
1 | DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL] |
作用:存储薪资、身高、体重、体质参数等
字符型
char
1 | char (m) |
varchar
1 | varchar(m) |
text
1 | text |
枚举类型(了解)
enum
1 | enum |
集合类型(了解)
set
1 | set |
日期/时间类型
1 | DATE 日期值 |
基本操作
创建数据库
create database <数据库名称> charset=utf8;
1 | create database skx charset=utf8; |
删除数据库
drop database <数据库名称>;
1 | drop database skx; |
切换数据库
use <数据库名称>;
1 | use zykj; |
查看当前选择的数据库
1 | select database(); |
MySQL之表操作
什么是表
表(TABLE) 是一种结构化的文件,可用来存储某种特定类型的数据。表中的一条记录有对应的标题,标题称之为表的字段。
查看当前数据库中所有表
1 | 格式:show tables; |
创建表
格式:create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件] )engine=innodb default charset utf8;
示例:
1 | create table student( |
注意:
not null
:表示此列不能为空auto_increment
:表示自增长,默认每次增长+1- 自增长只能添加在主键或者唯一索引字段上
- primary key :表示主键(唯一且不为空)
- engine = innodb :表示指定当前表的存储引擎
- default charset utf8 :设置表的默认编码集
删除表
drop table 表名;
1 | drop table student; |
查看表结构
desc 表名;
1 | desc student; |
查看建表语句
show create table 表名;
1 | show create table student; |
重命名表名
netame table <变更前表名> to <变更后表名>
1 | netame table car to newCar; |
修改表结构
alter table 表名 add|change|drop 列名 类型;
1 | alter table newCar add isDelete bit default 0; |
复制表
create table 新表名 select * from 原表名
1 | create table newinfo select * from oldinfo; |
ps:主键自增/索引/触发器/外键 不会 被复制
选择性插入
1
create table newinfo select * from oldinfo where id=1;
复制表结构
1
create table newinfo like oldinfo;
ps: 数据/触发器/外键 不会被复制
create table newinfo select * from oldinfo where 1!=1;
数据操作(增 删 改 查)
增 insert
全列插入
insert into 表名 values(...);
主键列是自动增长,但是全列插入时需要占位,通常使用0,插入成功一行以实际数据为准
1 | insert into student values(0,"tom",19,1,"北京",0); |
缺省插入
insert into 表名(列1,列2,...) values(值1,值2,...)
1 | insert into student(name,age,address) values("lilei",19,"上海"); |
同时插入多条数据
insert into 表名 values(...),(...),...;
1 | insert into student values(0,"hanmeimei",18,0,"北京",0),(0,"poi",22,1,"海南",0),(0,"wenli",20,0,"石家庄",0); |
删 delete
delete from 表名 where 条件;
1 | delete from student where id=4; |
注意:
- delete from student; – 删除整张表中的所有数据(一条一条数据的删除)
- truncate student; – 清空整张表(整个删,效率高)
truncate和delete的区别?[面试题]
- TRUNCATE 在各种表上无论是大的还是小的都非常快。而DELETE 操作会被表中数据量的大小影响其执行效率.
- TRUNCATE是一个DDL语言而DELETE是DML语句,向其他所有的DDL语言一样,他将被隐式提交,不能对TRUNCATE使用ROLLBACK命令。
- TRUNCATE不能触发触发器,DELETE会触发触发器。
- 当表被清空后表和表的索引和自增主键将重新设置成初始大小,而delete则不能。
改 update
update 表名 set 列1=值1,列2=值2,......where 条件;
1 | update student set age=16 where id = 7; |
注意:如果没有条件是全部列都修改
查 select
1 | 说明:查询表名中的全部数据 |
查
MySQL之单表查询
简单查询
查询语法
select [distinct]*(所有)|字段名,...字段名 from 表名;
查询所有字段信息
1
select * from person;
查询指定字段信息
1
select id,name,age,sex,salary from person;
别名查询,使用的as关键字,as可以省略的
1
select name,age as'年龄',salary '工资' from person;
直接对列进行运算,查询出所有人工资,并每人增加100块
1
2select (5/2);
select name, salary+100 from person;剔除重复查询 distinct
1
select distinct age from person;
条件查询
使用 WHERE 关键字 对简单查询的结果集 进行过滤
比较运算符:
>
<
>=
<=
=
<>
(!=)
null 关键字:
is null
,not null
逻辑运算符: 与
and
或or
(多个条件时,需要使用逻辑运算符进行连接)
查询格式
select [distinct]*(所有)|字段名,...字段名 from 表名 [where 条件过滤]
比较运算符:
>
<
>=
<=
=
<>
(!=)
,is null
是否为null1
2
3
4select * from person where age = 23;
select * from person where age <> 23;
select * from person where age is null;
select * from person where age is not null;逻辑运算符: 与
and
或or
1 | select * from person where age = 23 and salary = 29000; |
区间查询
关键字 between 10 and 20 :表示 获得10 到 20 区间的内容
使用 between…and 进行区间 查询
1
select * from person where salary between 4000 and 8000;
between…and 前后包含所指定的值
等价于 select * from person where salary >= 4000 and salary <= 8000;
集合查询
关键字: in, not null
使用 in 集合(多个字段)查询
1
2select * from person where age in(23,32,18);
等价于: select * from person where age =23 or age = 32 or age =18;使用 in 集合 排除指定值查询
1
select * from person where age not in(23,32,18);
模糊查询
关键字 like , not like
%
: 任意多个字符_
: 只能是单个字符
模糊查询 like % : 任意多个字符, _ :单个字符
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#查询姓名以"张"字开头的
select * from person where name like '张%';
#查询姓名以"张"字结尾的
select * from person where name like '%张';
#查询姓名中含有"张"字的
select * from person where name like '%张%';
#查询 name 名称 是四个字符的人
select * from person where name like '____';
#查询 name 名称 的第二个字符是 'l'的人
select * from person where name like '_l%';
#排除名字带 a 的学生
select * from student where name not like 'a%'
排序查询
ORDER BY 字段1 DESC, 字段2 ASC
排序查询格式
1
2
3
4
5select 字段|* from 表名 [where 条件过滤] [order by 字段[ASC][DESC]]
升序:ASC 默认为升序
降序:DESC
PS:排序order by 要写在select语句末尾示例
1
2
3
4
5
6
7
8
9
10
11
12
13#按人员工资正序排列,注意:此处可以省略 ASC关键字
select * from person order by salary ASC;
select * from person order by salary;
#工资大于5000的人,按工资倒序排列
select * from person where salary >5000 order by salary DESC;
#按中文排序
select * from person order by name;
#强制中文排序
select * from person order by CONVERT(name USING gbk);
ps:UTF8 默认校对集是 utf8_general_ci , 它不是按照中文来的。你需要强制让MySQL按中文来排序
聚合函数
聚合: 将分散的聚集到一起.
聚合函数: 对列进行操作,返回的结果是一个单一的值,除了 COUNT 以外,都会忽略空值
1
2
3
4
5COUNT:统计指定列不为NULL的记录行数;
SUM:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
MAX:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
MIN:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
AVG:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;格式
1
select 聚合函数(字段) from 表名;
示例
1
2#统计人员中最大年龄、最小年龄,平均年龄分别是多少
select max(age),min(age),avg(age) from person;
分组查询
分组的含义: 将一些具有相同特征的数据 进行归类.比如:性别,部门,岗位等等
怎么区分什么时候需要分组呢?
套路: 遇到 “每” 字,一般需要进行分组操作
例如:
- 公司每个部门有多少人
- 公司中有 多少男员工 和 多少女员工.
分组查询格式
1
2select 被分组的字段 from 表名 group by 分组字段 [having 条件字段]
ps: 分组查询可以与 聚合函数 组合使用示例
1
2
3
4
5
6
7
8
9#查询每个部门的平均薪资
select avg(salary),dept from person GROUP BY dept;
#查询每个部门的平均薪资 并且看看这个部门的员工都有谁?
select avg(salary),dept,GROUP_CONCAT(name) from person GROUP BY dept;
#GROUP_CONCAT(expr):按照分组,将expr字符串按逗号分隔,组合起来
#查询平均薪资大于10000的部门, 并且看看这个部门的员工都有谁?
select avg(salary),dept,GROUP_CONCAT(name) from person GROUP BY dept; having avg(salary)>10000;
where 与 having区别:
执行优先级从高到低:where > group by > having
- Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
- Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数
分页查询
好处:限制查询数据条数,提高查询效率
limit (起始条数),(查询多少条数);
1 | #查询前5条数据 |
联合查询
union 联合、合并
语法:
1 | select 字段|常量|表达式|函数 【from 表】 【where 条件】 union 【all】 |
特点:
- 多条查询语句的查询的列数必须是一致的
- 多条查询语句的查询的列的类型几乎相同
- union代表去重,union all代表不去重
正则表达式
MySQL中使用 REGEXP 操作符来进行正则表达式匹配。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。 |
$ | 匹配输入字符串的结束位置。 |
. | 匹配任何字符(包括回车和新行) |
[…] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^…] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
1 | ## ^ 匹配 name 名称 以 "e" 开头的数据 |
MySQL之多表查询
多表联合查询
数据
1 | #创建部门 |
多表查询语法
1 | select 字段1,字段2... from 表1,表2... [where 条件] |
注意: 如果不加条件直接进行查询,则会出现以下效果,这种结果我们称之为 笛卡尔乘积
1 | #查询人员和部门所有信息 |
笛卡尔乘积公式 : A表中数据条数 * B表中数据条数 = 笛卡尔乘积.
关联
建表语句
1 | create table class(id int auto_increment primary key,name varchar(20) not null,stuNum int not null); |
插入一些数据
1 | insert into class values(0,"python01",55),(0,"python02",50),(0,"python03",60),(0,"python04",60); |
关联查询
1 | select students.name,class.name from class inner join students on class.id=students.classid; |
分类
1 | 1、表A inner join 表B: |
约束
MySQL中的约束,添加约束,删除约束,以及其他的一些修饰:
NOT NULL(非空约束)
添加非空约束
建表时直接添加
1
CREATE TABLE t_user(user_id INT(10) NOT NULL);
通过ALTER 语句
1
2
3ALTER TABLE t_user MODIFY user_id INT(10) NOT NULL;
ALTER TABLE t_user CHANGE user_id user_id INT(10) NOT NULL;
删除非空约束
1 | ALTER TABLE t_user MODIFY user_id INT(10); |
UNIQUE(唯一约束)
添加唯一约束
建表时直接添加
1 | CREATE TABLE t_user(user_id INT(10) UNIQUE); |
通过ALTER语句
1 | ALTER TABLE t_user MODIFY user_id INT(10) UNIQUE; |
删除唯一性约束
ALTER TABLE t_user DROP INDEX user_id;
注:唯一但是可以为空(空和空不相等)
PRIMARY KEY(主键约束)
添加主键约束
建表时直接添加
1 | CREATE TABLE t_user(user_id INT(10) PRIMARY KEY); |
通过ALTER语句
1 | ALTER TABLE t_user MODIFY user_id INT(10) PRIMARY KEY; |
删除主键约束
1 | 1)ALTER TABLE t_user DROP PRIMARY KEY; |
FOREIGN KEY(外键约束)
对应的字段只能是主键或者唯一约束修饰的字段
1 | 首先创建两张表:class,students |
CHECK(检查约束)
1 | CREATE TABLE class( |
其他
AUTO_INCREMENT(自增长)
添加自增长
在创建表的时候添加
1
CREATE TABLE t_user(user_id INT(10) AUTO_INCREMENT PRIMARY KEY);
通过ALTER语句
1
2
3ALTER TABLE t_user MODIFY user_id INT(10) AUTO_INCREMENT;
ALTER TABLE t_user CHANGE user_id user_id INT(10) AUTO_INCREMENT;
删除自增长
1 | ALTER TABLE t_user MODIFY user_id INT(10); |
ZEROFILL(零填充)
添加零填充
在创建表的时候添加
1
CREATE TABLE t_user(user_id INT(10) ZEROFILL);
通过ALTER语句
1
2
3ALTER TABLE t_user MODIFY user_id INT(10) ZEROFILL;
ALTER TABLE t_user CHANGE user_id user_id INT(10) ZEROFILL;
删除零填充
1 | ALTER TABLE t_user MODIFY user_id INT(10); |
DEFAULT(默认)
添加默认约束
在创建表的时候添加
1
CREATE TABLE t_user(user_id INT(10) DEFAULT 3);
通过ALTER语句
1
2
3ALTER TABLE t_user MODIFY user_id INT(10) DEFAULT 2;
ALTER TABLE t_user CHANGE user_id user_id INT(10) DEFAULT 2;
删除默认约束
1 | ALTER TABLE t_user MODIFY user_id INT(10); |
UNSIGNED(无符号位)
添加无符号
在创建表的时候添加
1
CREATE TABLE t_user(user_id INT(10) UNSIGNED);
通过ALTER语句
1
2
3ALTER TABLE t_user MODIFY user_id INT(10) UNSIGNED;
ALTER TABLE t_user CHANGE user_id user_id INT(10) UNSIGNED;
删除无符号
1 | ALTER TABLE t_user MODIFY user_id INT(10); |
数据库事务
含义
通过一组逻辑操作单元(一组DML——sql语句),将数据从一种状态切换到另外一种状态
特点
(ACID)
- 原子性:要么都执行,要么都回滚
- 一致性:保证数据的状态操作前和操作后保持一致
- 隔离性:多个事务同时操作相同数据库的同一个数据时,一个事务的执行不受另外一个事务的干扰
- 持久性:一个事务一旦提交,则数据将持久化到本地,除非其他事务对其进行修改
相关步骤:
- 开启事务
- 编写事务的一组逻辑操作单元(多条sql语句)
- 提交事务或回滚事务
事务的分类
隐式事务,没有明显的开启和结束事务的标志
1
insert、update、delete语句本身就是一个事务
显式事务,具有明显的开启和结束事务的标志
开启事务
取消自动提交事务的功能编写事务的一组逻辑操作单元(多条sql语句)
insert
update
delete提交事务或回滚事务
使用到的关键字
1 | set autocommit=0; |
事务的隔离级别:
事务并发问题如何发生?
- 当多个事务同时操作同一个数据库的相同数据时
事务的并发问题有哪些?
- 脏读:一个事务读取到了另外一个事务未提交的数据
- 不可重复读:同一个事务中,多次读取到的数据不一致
- 幻读:一个事务读取数据时,另外一个事务进行更新,导致第一个事务读取到了没有更新的数据
如何避免事务的并发问题?
1 | 通过设置事务的隔离级别 |
设置隔离级别:
1 | set session|global transaction isolation level 隔离级别名; |
查看隔离级别:
1 | select @@tx_isolation; |
视图
含义:理解成一张虚拟的表
视图和表的区别:
1 | 使用方式 占用物理空间 |
视图的好处:
1 | 1、sql语句提高重用性,效率高 |
视图的创建
1 | 语法: |
视图的增删改查
查看视图的数据
1
2SELECT * FROM my_v4;
SELECT * FROM my_v1 WHERE last_name='Partners';插入视图的数据
1
INSERT INTO my_v4(last_name,department_id) VALUES('虚竹',90);
修改视图的数据
1
UPDATE my_v4 SET last_name ='梦姑' WHERE last_name='虚竹';
删除视图的数据
1
DELETE FROM my_v4;
某些视图不能更新
1 | 包含以下关键字的sql语句:分组函数、distinct、group by、having、union或者union all |
视图逻辑的更新
1 | #方式一: |
视图的删除
1 | DROP VIEW test_v1,test_v2,test_v3; |
视图结构的查看
1 | DESC test_v7; |
存储过程
含义:一组经过预先编译的sql语句的集合
好处:
1 | 1、提高了sql语句的重用性,减少了开发程序员的压力 |
分类:
1 | 1、无返回无参 |
创建存储过程
语法:
1 | create procedure 存储过程名(in|out|inout 参数名 参数类型,...) |
类似于方法:
1 | 修饰符 返回类型 方法名(参数类型 参数名,...){ |
注意
1 | 1、需要设置新的结束标记 |
调用存储过程
1 | call 存储过程名(实参列表) |
函数
创建函数
学过的函数:LENGTH、SUBSTR、CONCAT等
语法:
1 | CREATE FUNCTION 函数名(参数名 参数类型,...) RETURNS 返回类型 |
调用函数
1 | SELECT 函数名(实参列表) |
函数和存储过程的区别
1 | 关键字 调用语法 返回值 应用场景 |
流程控制结构
系统变量
一、全局变量
作用域:针对于所有会话(连接)有效,但不能跨重启
1 | 查看所有全局变量 |
二、会话变量
作用域:针对于当前会话(连接)有效
1 | 查看所有会话变量 |
自定义变量
一、用户变量
声明并初始化:
1 | SET @变量名=值; |
赋值:
1 | 方式一:一般用于赋简单的值 |
1 | 方式二:一般用于赋表 中的字段值 |
使用:
1 | select @变量名; |
二、局部变量
声明:
1 | declare 变量名 类型 【default 值】; |
赋值:
1 | 方式一:一般用于赋简单的值 |
1 | 方式二:一般用于赋表 中的字段值 |
使用:
1 | select 变量名 |
二者的区别:
1 | 作用域 定义位置 语法 |
分支
一、if函数
语法:if(条件,值1,值2)
特点:可以用在任何位置
二、case语句
语法:
1 | 情况一:类似于switch |
特点:
可以用在任何位置
三、if elseif语句
语法:
1 | if 情况1 then 语句1; |
特点:
只能用在begin end中!!!!!!!!!!!!!!!
三者比较:
应用场合
if函数 简单双分支
case结构 等值判断 的多分支
if结构 区间判断 的多分支
循环
语法:
1 | 【标签:】WHILE 循环条件 DO |
特点:
1 | 只能放在BEGIN END里面 |
数据库引擎
查看数据库支持的引擎
1 | show engines; |
查看数据库当前默认引擎
1 | show variables like '%storage_engine%'; |
查看数据表使用的引擎
1 | show create table table_name; |
修改表的存储引擎
1 | alter table table_name engine=engine_name; |
问题
Navicat for mysql连接远程数据库(1130错误解决方法)
进入mysql控制台:
执行命令1
1
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '您的数据库密码' WITH GRANT OPTION;
执行命令2
1
flush privileges;