MySQL基础(一位小白)

MySQL

mysql -u root -p --default-character-set=utf8mb4

需要明白SQL查询语句的写法:

1、SELECT ....
2、FROM ....
3、JOIN ... ON ....
4、WHERE ... 
5、GROUP BY ...
6、HAVING ...
7、ORDER BY ...

执行顺序与书写顺序不同:

2、FROM
3、JOIN ... ON ...
4、WHERE ...
5、GROUP BY ...
6、HAVING ...
1、SELECT ...
7、ORDER BY ...

一、数据库基本操作

1.1、用户管理

*1.1.1、*登录
mysql -u user -p;
*1.1.2、*查看当前用户
select user;

-- from dual可省略
select user from dual;
*1.1.3、*创建新用户
create user 用户名@localhost identified by'密码';
*1.1.4、*为用户授权
grant all on *.* to 用户名@localhost

 -- 将新数据库中所有权限授予给新用户
grant all on 数据库名.* to 用户名@localhost ;
*1.1.5、*删除用户
drop user 用户名@localhost

1.2、数据库管理

*1.2.1、*查看当前用户可操作的所有数据库
show databases;
*1.2.2、*创建新数据库
create database 数据库名;

-- []可省略
create database 数据库名 [ default character set utf8mb4 ];
*1.2.3、*选择数据库
use 数据库名;

 -- 查看当前数据库(即被选中的数据库)
 select database();
 
 尚未选择任何数据库会返回NULL
*1.2.4、*导出数据库
mysqldump -u ddy -p ddy market>d:/market.sql

mysqldump -u 用户名 -p 数据库名 > 路径名称
*1.2.5、*导入数据库
mysql -u ddy -p market<d:/market.sql

mysql -u 用户名 -p 数据库名 < 路径名称

15和16均在命令提示符下执行

*1.2.6、*导入source
mysql> source D:\scripts\region_dept_emp.sql

17必须在mysql里面先选中数据库后再执行source

*1.2.7、*删除数据库
drop database 数据库名;

1.3、表管理

*1.3.1、*查看表
show tables;
*1.3.2、*创建表
create table 表名 (列名 类型(宽度) , ... );
*1.3.3、*删除表
drop table 表名;
*1.3.4、*截断表
truncate table 表名;
*1.3.5、*添加列
alter table 表名 add column ( 列名 类型(宽度) , ... )
*1.3.6、*删除列
ALTER TABLE 表名 DROP COLUMN 列名
*1.3.7、*修改列名
 ALTER TABLE 表名 CHANGE COLUMN 原列名 新列名 类型(宽度);

1.4、数据管理

*1.4.1、*添加数据

添加数据时按顺序依次添加

insert into 表名 (列名) values (值);
*1.4.2、*删除数据

先删除字表记录,再删除主表记录

DELETE FROM kfm WHERE id = 1 ;
*1.4.3、*更新数据
UPDATE kfm SET name = 'tom' , birthdate='2001-05-06' WHERE id = 1 ;

1.5、数据查询

1.5.1、查询
SELECT id , name , birthdate FROM kfm where 条件;
1.5.2、排序
SELECT id , name , birthdate FROM kfm ORDER BY name ASC;
1.5.3、分页查询
-- limit 0 ,5  0是从第几条开始查询,5是查询几条数据  -1为最后一行记录
SELECT * FROM kfm  LIMIT 0 , 5;
1.5.4、提出查询中重复行
使用 DISTINCT 可以剔除查询结果中的 "重复行"
mysql> SELECT DISTINCT deptno FROM emp ;

二、约束和高级查询

1、约束

通过 show create table 查看约束

1.1、主键约束

表中经常有一个列或多列的组合,其值能唯一地标识表中的每一行,这样的一列或多列称为表的主键,也称作主键约束。

主键约束最显著的特征是主键列中的值是不允许重复的 不为空,通过主键约束可强制表的实体唯一性。

alter table 表名 add 可写(constraint 约束名) primary key(列名);

ALTER TABLE 表名 MODIFY 列名 INT PRIMARY KEY;

创建表时可直接在类型后加primary key

删除主键约束(不使用名称))
mysql> ALTER TABLE 表名DROP PRIMARY KEY ;

自增长列

自增长列必须是主键列

-- 设置自增长列
auto_increment
1.2、唯一约束

对于非主键列的值需要具有唯一性是使用唯一约束

不允许有重复的,可以有一个为空

alter table 表名 add constraint unique(列名);
1.3、默认约束

为列中的值设置默认值,使用insert添加记录时,没有指定值就会使用默认值,指定值则默认值无效

alter table 表名 change column 旧列名 新列名 数据类型 default 数值;
1.4、外键约束

关系:一对一、一对多、多对多

alter table 子表名 add 可写(constraint 约束名)  foreign key 子表名(子表列名)references 主表名(主键列名);

尝试删除外键约束
ALTER TABLE 表名 DROP CONSTRAINT 约束名 ;

1.5、检查约束

用于检验列中值是否符合要求

alter table 表名 add constraint 列名 check(检查条件);

2、高级查询

2.1、基本查询
2.1.1、查询所有信息
select * from 表名;
2.1.2、查询指定列
select 列1,列2,....  from 表名;
2.1.3、去掉列中重复值
select distinct 列名 from 表名;
2.1.4、使用运算
select  列1+列2 from 表名;
2.1.5、使用列别名
select 列名 as 显示名 from 表名;
2.2、条件查询
2.2.1、比较运算符
select * from 表名 where 列名>(< | >=  | <=  |  <>和!=一样)条件;
2.2.2、逻辑运算符
select * from 表名 where 条件 and(or  |  not)  条件;
2.2.3、between…and…
select * from 表名 betweeen 条件  and 条件;
2.2.4、in 和 exists
select	* FROM 表名 where	job IN ('项目经理',	'项目组长'	);

in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询

如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
not in 和not exists:如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快

2.2.5、模糊查询like

通配符%_实现,%表示任个任意字符,_表示任意一个字符。

-- 查询姓宋的
select	* FROM 表名 where 列名 like'宋%';
-- 查询以x结尾的三个字
select	* FROM 表名 where 列名 like'_ _x';

-- 显示 ename 中第二个字母是下划线的员工信息
SELECT empno , ename FROM emp WHERE ename LIKE '_\_%' ;

-- 使用 escape 来显式定义转义字符
SELECT empno , ename FROM emp WHERE ename LIKE '_$_%' ESCAPE '$' ;

-- 成对的单引号总是表示字符串边界,如果在字符串中需要出现单个单引号,只需要将单引号写两次即可
mysql> SELECT empno , ename FROM emp WHERE ename LIKE '_''_%' ESCAPE '''' ;
2.2.6、null查询

NULL在数据库中表示没有数据,应使用is来判断列中是否存在NULL

select	* FROM 表名 where 列名 is null;
2.3、排序

order by 升序(ASC) | 降序(DESC)默认是升序

select	* FROM 表名 where ....  order by 列名  asc;
2.4、分组查询

按照指定的列,将列中相同的值分为一组,一组用一条记录来表示。分组后,可以对每组中的数据进行聚合查询

SELECT	deptno 部门编号, COUNT(*) 人数 FROM emp group by deptno;
2.5、筛选

Having子句是对分组后,每组中的数据进行筛选。相对于where子句是在分组前进行的筛选,having子句是在分组后进行的筛选

SELECT	deptno 部门编号, COUNT(*) 人数 FROM emp GROUP BY deptno having 人数 > 3;
2.6、连接查询
2.6.1、内连接

我们将 emp.deptno = dept.deptno 条件称作 连接条件
我们将 返回 满足连接条件的查询 称作 内连接( inner join )

非等值连接
-- 内连接之非等值连接
mysql> select empno , ename , sal from emp ;
等值连接
-- 内连接之等值连接
mysql> -- 查询 emp 表中每个员工的工号、姓名、部门号、部门名称
mysql> select * from emp ;

两个表连接

FROM 表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号

三个表连接

FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号

四个表连接

FROM ((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号
2.6.2、外连接

若查询结果中除满足连接条件的数据外,还包含不满足连接条件的数据,则 将这种查询称作外连接

 -- 右外连接   左边没有值得补充为null
mysql> SELECT * FROM dept d RIGHT OUTER JOIN emp e ON e.deptno = d.deptno ;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1SdfO5Bu-1629766404292)(https://i.loli.net/2021/08/12/Xhv5FnekjWf2sbY.png)]

以下语句被认为是右连接的非标准写法 ( MySQL 8.0.25 不支持 )
SELECT * FROM t_major m , t_class c WHERE m.id(+) = c.major_id ;

 -- 左外连接    右边没有值得补充为null
mysql>  SELECT * FROM dept d LEFT OUTER JOIN emp e ON e.deptno = d.deptno ;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3m4WL2pq-1629766404294)(https://i.loli.net/2021/08/13/UFAQE4GhjZbgleD.png)]

以下语句被认为是左连接的非标准写法 ( MySQL 8.0.25 不支持 )
SELECT * FROM t_major m , t_class c WHERE m.id = c.major_id(+) ;

-- 全外连接( MySQL不支持 )
SELECT * FROM t_class c FULL OUTER JOIN t_major m ON c.major_id = m.id ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FULL OUTER JOIN t_major m ON c.major_id = m.id' at line 1
2.6.3、自连接查询
from emp e1 join emp e2 on e1.mgr=e2.empno
2.7、子查询
-- 单行子查询: 返回单行单列
-- 多列子查询: 返回单行多列 (使用了成对比较))
SELECT * FROM emp WHERE ( deptno , job , manager ) = ( SELECT deptno , job , manager FROM emp WHERE upper(ename) = 'SMITH' ) ;
-- 多行子查询: 返回多行单列
image-20210818193500547
-- 相关子查询: 子查询使用了外部SQL的某些表或列 (但是外部SQL不可使用子查询中的表和列)
image-20210818193642370
-- 嵌套子查询:在子查询内部可以继续嵌套子查询
2.8、case
-- 用1来表示公 2表示母
mysql> SELECT id , name , CASE
    ->                         WHEN gender = 1 THEN '公'
    ->                         WHEN gender = 2 THEN '母'
    ->                         ELSE '未知'
    ->                    END AS gender
    -> FROM t_dogs ;
+------+------+--------+
| id   | name | gender |
+------+------+--------+
|    1 | 旺财 | 公     |
|    2 | 来福 | 母     |
|    3 | 小黑 | 未知   |
|    3 | 大黄 | 未知   |
+------+------+--------+
4 rows in set (0.00 sec)

3、函数

3.1、聚合函数

聚合函数有summaxminavgcount共五个

使用聚合函数必须的分组

3.2、数学函数
round函数

round(x) x四舍五入取整、

round(x,[y]) y指保留几位数

floor函数

floor(x) x向下取整 如:floor(15.87)取整后是15

ceiling函数

ceiling(x) x向上取整 如:ceiling(15.34)取整后是16

abs函数

abs(-12) 12 取绝对值

mod函数

mod(x,y) 取x除以y的余数

power函数

power(x,y) 取x的y次幂

sqrt函数

sqrt(x) 取x开根号

3.3、字符串函数
length函数

获取字符串长度

upper/lower函数

upper函数是将所有字符全部改成大写

lower函数是将所有字符全部改成小写

concat函数

concat(x,y)将x和y两个字符串连接起来

instr函数

instr(‘java web’ ‘web’) 6 检索子字符串在父字符串中的索引

ltrim函数

ltrim(’ java’) 去掉左边空格

rtrim函数

rtrim('java ') 去掉右边空格

trim函数

trim(’ java ') 去掉两端的空格

replace函数

replace(‘hello java’,‘java’,‘123’) hello 123 替换文本

substr函数

substr(‘12345’,2) 2345 第一个参数是被截取的字段,第二个参数是从第几位开始截取

3.4、日期函数
3.4.1、日期格式符
格式描述
%a缩写星期名
%b缩写月名
%c月,数值
%D带有英文前缀的月中的天
%d月的天,数值(00-31)
%e月的天,数值(0-31)
%f微秒
%H小时(00-23)
%h小时(01-12)
%I小时(01-12)
%i分钟,数值(00-59)
%j年的天(001-366)
%k小时(0-23)
%l小时(1-12)
%M月名
%m月,数值(00-12)
%pAM 或 PM
%r时间,12-小时(hh:mm:ss AM 或 PM)
%S秒(00-59)
%s秒(00-59)
%T时间, 24-小时(hh:mm:ss)
%U周(00-53)星期日是一周的第一天
%u周(00-53)星期一是一周的第一天
%V周(01-53)星期日是一周的第一天,与 %X 使用
%v周(01-53)星期一是一周的第一天,与 %x 使用
%W星期名
%w周的天(0=星期日, 6=星期六)
%X年,其中的星期日是周的第一天,4 位,与 %V 使用
%x年,其中的星期一是周的第一天,4 位,与 %v 使用
%Y年,4 位
%y年,2 位
3.4.2、查询今天
/*
  NOW() 函数返回当前的日期和时间。
  TO_DAYS()函数返回日期和年份0(日期"0000-00-00")之间的天数。
*/
SELECT * FROM cpidata WHERE TO_DAYS( 时间字段名 ) = TO_DAYS(NOW());
3.4.3、查询昨天
/*
  NOW() 函数返回当前的日期和时间。
  TO_DAYS()函数返回日期和年份0(日期"0000-00-00")之间的天数。
*/
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) = 1
3.4.4、查询本周
/*
  YEARWEEK()返回年份和星期
  DATE_FORMAT(被格式化的日期,格式符)日期格式化函数
*/
SELECT * FROM 表名 WHERE YEARWEEK(DATE_FORMAT(日期字段名,'%Y-%m-%d')) = YEARWEEK(NOW());
3.4.5、查询上周
/*
  YEARWEEK()返回年份和星期
  DATE_FORMAT(被格式化的日期,格式符)日期格式化函数
*/
SELECT * FROM 表名 WHERE YEARWEEK(DATE_FORMAT(日期字段名,'%Y-%m-%d')) = YEARWEEK(NOW())-1;
3.4.6、查询近7天
/*
  DATE_SUB() 函数从日期减去指定的时间间隔
  DATE_SUB(合法的日期表达式,INTERVAL 希望添加的时间间隔 时间类型)
  CURDATE() 函数返回当前的日期。
*/
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
3.4.7、查询近30天
/*
  DATE_SUB() 函数从日期减去指定的时间间隔
  DATE_SUB(合法的日期表达式,INTERVAL 希望添加的时间间隔 时间类型)
  CURDATE() 函数返回当前的日期。
*/
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)
3.4.8、查询本月
/*
  DATE_FORMAT(被格式化的日期,格式符)日期格式化函数
*/
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' );
3.4.9、查询上一月
/*
  PERIOD_DIFF(第一个日期,第二个日期)函数返回两日期之间的差异。结果以月份计算
*/
SELECT * FROM 表名 WHERE PERIOD_DIFF( DATE_FORMAT( NOW( ) , '%Y%m' ) , DATE_FORMAT( 时间字段名, '%Y%m' ) ) =1
3.4.10、查询本季度
/*
 QUARTER(日期)返回日期的季度:
*/
SELECT * FROM 表名 WHERE QUARTER(日期字段名)=QUARTER(NOW());
3.4.11、查询上季度
/*
 QUARTER(日期)返回日期的季度:
 DATE_SUB() 函数从日期减去指定的时间间隔
 DATE_SUB(合法的日期表达式,INTERVAL 希望添加的时间间隔 时间类型)
*/
SELECT * FROM 表名 WHERE QUARTER(日期字段名)=QUARTER(DATE_SUB(NOW(),INTERVAL 1 QUARTER));
3.4.12、查询本年度
/*
 year(日期字段名)返回日期中的年份
*/
SELECT * FROM 表名 WHERE YEAR(日期字段名)=YEAR(NOW());
3.4.13、查询上年度
/*
 year(日期字段名)返回日期中的年份
 DATE_SUB() 函数从日期减去指定的时间间隔
 DATE_SUB(合法的日期表达式,INTERVAL 希望添加的时间间隔 时间类型)
*/
SELECT * FROM 表名 WHERE YEAR(日期字段名)=YEAR(DATE_SUB(NOW(),INTERVAL 1 YEAR));
3.4.14、日期截取函数
函数作用函数作用
dayofweek(date)date是星期几dayofmonth(date)date是该月中第几日
dayofyear(date)date是一年中第几日year(date)返回date的年份
month(date)返回date的月份day(date)返回date的日期
week(date)返回date是一年中第几周hour(time)返回time的小时数
minute(time)返回time中的分钟数second(time)返回time的秒数
current_timestamp()获取当前时间current_date()获取当前日期
current_time()获取当前时间now()获取当前日期+时间
datediff(date1,date2)返回两个日期之间的天数

三、事务

MySQL 8 默认的引擎是 InnoDB ,该引擎是支持事务的;MySQL 5.5 之前默认的引擎是 MyISAM ,它是不支持事务的

构成单一逻辑工作单元的操作集合称作事务( transaction ), 它是作为不可分割的逻辑单元执行的一组SQL语句。

退出mysql提示符就意味着结束事务、终止会话、断开连接;重新登录mysql需要重新设置事务提交方式

一个事务开时,在没提交的前提下又开始一个新事务,之前的事务会自动提交

-- 查询事务提交方式(若返回1则表示自动提交)
SELECT @@autocommit ;

所有的 DDL 语句都会导致事务自动提交。 CREATE TABLE / ALTER TABLE / DROP TABLE / TRUNCATE TABLE

3.1、特性

Atomicity 原子性 : 事务中的所有操作要么都发生、要么都不发生

Consistency 一致性 : 事务将数据库从一种一致状态转变为下一种一致状态

Isolation 隔离性 : 一个事务的执行,不应该受到其它事务的干扰

Durability 持久性 : 事务一旦提交,其结果就是持久的

3.2、控制语句

通过begin和start transaction开启事务,事务提交方式默认为手动提交,会话提交方式还是自动的(没改的前提下)

-- 开始事务 BEGIN
begin;
start transaction ;
-- 使用commit意味着上一个事务以完结,开启了一个新的事务
commit;
-- 提交事务 COMMIT 
commit;
-- 回滚事务: 这里是为了撤销删除的数据
rollback ;
rollback to

3.3、事务提交模式

-- 开启事务自动提交
set autocommit = 1 ;
-- 关闭事务自动提交
set autocommit = 0 ;

3.4、隔离级别

连接建立并创建会话时就已经隐式开启的事务的隔离级别是 可重复读读
因此需要显式地终结这个事务,以便于让新事务使用我们设置后的 隔离级别

  • READ UNCOMMITTED 读未提交
  • READ COMMITTED 读已提交
  • REPEATABLE READ 可重复读
  • SERIALIZABLE 串行化
-- 使用 SET TRANSACTION 来设置事务隔离级别
SET session TRANSACTION ISOLATION LEVEL read committed ;
set @@session.transaction_idolation='red-uncommitted';

3.5、保存点

SAVEPOINT identifierName 设置保存点
RELEASE SAVEPOINT identifierName 释放保存点
ROLLBACK TO identifierName 回滚到保存点

3.6、并发产生的问题

事务并发冲突_6隔离级别
  • Dirty Read 脏读:个事务读取到了另外一个事务尚未提交的数据

    (比如隔离级别为read uncommitted将事务隔离级别调高到read committed即可解决)

事务并发冲突_1脏读
  • Nonrepeatable Read 不可重复读:同一个事务中多次査询到的数据竞然是不同的

    因为读取到了另一个事务中没有提交的数据(比如隔离级别为 read uncommitted)

    因为读取到了另一个事务中已经提交的数据(比如隔离级别为 read committed)

    将事务隔离级别调高到 repeatable read 即可解决

事务并发冲突_2不可重复读
  • Lost Update 丢失更新1
事务并发冲突_4丢失更新1
  • Lost Update 丢失更新2
事务并发冲突_5丢失更新2
  • Phantom Read 幻读
事务并发冲突_3幻象读

3
ZN5.png" alt=“事务并发冲突_6隔离级别” style=“zoom:50%;” />

  • Dirty Read 脏读:个事务读取到了另外一个事务尚未提交的数据

    (比如隔离级别为read uncommitted将事务隔离级别调高到read committed即可解决)

事务并发冲突_1脏读
  • Nonrepeatable Read 不可重复读:同一个事务中多次査询到的数据竞然是不同的

    因为读取到了另一个事务中没有提交的数据(比如隔离级别为 read uncommitted)

    因为读取到了另一个事务中已经提交的数据(比如隔离级别为 read committed)

    将事务隔离级别调高到 repeatable read 即可解决

事务并发冲突_2不可重复读
  • Lost Update 丢失更新1
事务并发冲突_4丢失更新1
  • Lost Update 丢失更新2
事务并发冲突_5丢失更新2
  • Phantom Read 幻读
事务并发冲突_3幻象读

3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值