Mysql笔记01-安装和SQL基础

1.Docker安装Mysql

容器的启动

#拉取镜像(不添加版本,默认latest)
docker pull mysql

cd /home/admin/mysql
docker run -p 3306:3306 --name mysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql

命令解释:

-p 3306:3306 将主机的3306端口映射到容器内部的3306端口
--name mysql 指定运行的容器名为mysql
-v $PWD/conf:/etc/mysql/conf.d 将容器内部的配置目录/etc/mysql/conf.d挂载到主机目录$PWD/conf
-v $PWD/logs:/logs 将容器内部的日志目录/logs挂载到主机目录$PWD/logs
-v $PWD/data:/var/lib/mysql 将容器内部的数据目录/var/lib/mysql挂载到主机目录$PWD/data
-e MYSQL_ROOT_PASSWORD=123456 设置数据库root用户的密码为123456
-d 设置容器在后台运行

权限的控制

​ 新创建的容器默认root权限只有本机登录,即只能在容器内使用,需要更改权限。

use mysql;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;

2.SQL基础

2.1SQL简介

​ SQL是Structure Query Language(结构化查询语句)的缩写,它是使用关系模型的数据库应用语言。

2.2SQL分类

​ SQL语句主要可以划分为以下3个类别。

  • DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象。常用的语句关键字主要包括create、drop、alter等。
  • DML(Data Manipulation Languages)语句:数据操纵语句,用于添加、删除、更新和查询数据记录,并检查数据完整性。常用的语句关键字主要包括insert、delete、update和select等。
  • DCL(Data Control Languages)数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。

2.2.1DDL语句

​ DDL是数据定义语言的缩写,简单说就是对数据库内部的对象进行创建、删除、修改等操作语句。DDL语句更多由数据库管理员(DBA)使用,开发人员一半很少使用。

1.连接数据库

[root@izuf68l8jiwy7fo0zpek0bz ~]# mysql -h127.0.0.1 -uroot -p
Enter password:

在以上命令中,mysql代表客户端的命令,-p表述数据库的地址,-u后面连接的数据库用户名称,-p表示要输入密码。(使用-h代表使用了TCP/IP套接字方式连接,如果不使用表示使用Unix域套接字连接)

拓展补充:https://www.cnblogs.com/wade-luffy/p/6274895.html

2.创建数据库

语法如下:

CREATE DATABASE dbname

mysql> create database test1;
Query OK, 1 row affected (0.01 sec)

其中提示的“Query OK, 1 row affected (0.01 sec)”,这段提示可以分为3部分。

  • ”Query OK“表示上面的命令执行成功,Mysql的特点是所有的DDL和DML操作执行成功后都显示"Query OK",可以理解成执行成功。
  • "1 row affected" 表示操作只影响了数据库中的一行的记录
  • "0.01 sec"则记录了操作执行的时间。

删除数据库

语法如下:

DROP DATABASE dbname

创建表

语法如下:

CREATE TABLE tablename (
column_name_1 column_type_1 constraints,
column_name_2 column_type_2 constraints,
...
column_name_n column_type_n constraints)

column_name 是列的名字;
column_type 是列的数据类型;
Constraints 是这个列的约束条件

举个栗子:

mysql> CREATE TABLE emp(ename varchar(10),hiredate date,sal decimal(10.2),deptno int(2));
Query OK, 0 rows affected, 1 warning (0.02 sec)

查看表的定义如下:

mysql> desc emp;
+----------+---------------+------+-----+---------+-------+
| Field    | Type          | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+-------+
| ename    | varchar(10)   | YES  |     | NULL    |       |
| hiredate | date          | YES  |     | NULL    |       |
| sal      | decimal(10,0) | YES  |     | NULL    |       |
| deptno   | int           | YES  |     | NULL    |       |
+----------+---------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql> show create table emp \G;
*************************** 1. row ***************************
       Table: emp
Create Table: CREATE TABLE `emp` (
  `ename` varchar(10) DEFAULT NULL,
  `hiredate` date DEFAULT NULL,
  `sal` decimal(10,0) DEFAULT NULL,
  `deptno` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

ERROR:
No query specified

注:"\G"选项的含义是使得记录能够按照字段竖向排序,已变更好地展示内容较长的记录。

修改表

语法如下:

ALTER TABLE tablename MODIFY [COLUMN] column_definition[FIRST|AFTER col_name]

举个栗子:

--增加表字段age
alter table emp add column age int(3);
--删除表字段age
alter table emp drop column age;
--字段改名ename
alter table emp change ename vname varchar(20);
--新增字段,添加在ename之后
alter table emp add id int(10) after vname;
--修改某字段的位置
alter table emp modify id int first;

修改表名:

语法如下:

ALTER TABLE tablename RENAME [TO] new_tablename

alter table emp rename emp1;

2.2.2DML语句

​ DML操作是指对数据库中表记录的操作,主要包括表记录的插入(insert)、更新(update)、删除(delete)和查询(select),是开发人员日常使用最频繁的操作。

1.插入记录

语法格式:

INSERT INTO tablename (field1, field2,...fieldn) VALUES(value1,value2,...valuen);

INSERT INTO tablename VALUES(value1,value2,...valuen)

可以不用指定字段名称,但是values后面的顺序应该和字段的排列顺序一致。

insert into emp (ename,sal,deptno) values ('zhangsan',2222,333);
insert into emp values('jiangfeng','2021-06-17',2,2);

2. 更新记录

语法格式:

UPDATE tablename SET field1=value1,field2=value2,...[WHERE CONDITION]

例子:

update emp SET  hiredate='2020-01-01' where sal=2222;

删除记录

语法格式:

DELETE FROM tablename [WHERE CONDITION]

查询记录

数据插入到数据库中后,就可以用SELECT命令进行各种各样的查询,使得输出的结果符合用户的要求。

语法格式:

SELECT[ALL|DISTINCT|DISTINCTROW|TOP]
{|talbe.|[table.]field1[AS alias1][,[table.]field2[AS alias2][,…]]}
FROM tableexpression[,…][IN externaldatabase]
[WHERE…]
[GROUP BY…]
[HAVING…]
[ORDER BY…]

(0)最简单的查询

查询最简单的方式是将记录全部取出。其中'*'表示要将所有的记录都选出来,也可以用逗号分隔的所有字符串来代替。

mysql> select * from emp;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| zhangsan  | 2020-01-01 | 2222 |    333 |
+-----------+------------+------+--------+
2 rows in set (0.00 sec)

(1)查询不重复的记录

有时需要将表中的记录去掉重复后显示出来,可以使用distinct关键字来实现。

mysql> select * from emp;;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| zhangsan  | 2020-01-01 | 2222 |    333 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | NULL       |  333 |    444 |
| zhangsan  | NULL       |  333 |    444 |
+-----------+------------+------+--------+
5 rows in set (0.00 sec)

ERROR:
No query specified

mysql> select distinct * from emp;;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| zhangsan  | 2020-01-01 | 2222 |    333 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | NULL       |  333 |    444 |
+-----------+------------+------+--------+
4 rows in set (0.00 sec)

mysql> select distinct ename from emp;
+-----------+
| ename     |
+-----------+
| jiangfeng |
| zhangsan  |
+-----------+
2 rows in set (0.01 sec)

(2)条件查询

​ 在很多情况下,用户并不需要查询所有的记录,而只是需要根据限定条件来查询一部分数据,用where关键字可以实现这样的操作。

mysql> select  * from emp where ename='jiangfeng';
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| jiangfeng | NULL       |  333 |    444 |
+-----------+------------+------+--------+
2 rows in set (0.00 sec)

上面的例子中,where后面的条件时一个字段的'='比较,除了'='外,还可以使用>、<、>=、<=、!= 等比较运算符;多个条件之间还可以使用or、and等逻辑运算符进行多条件联合查询。

mysql> select  * from emp where ename='jiangfeng' and sal >100;
+-----------+----------+------+--------+
| ename     | hiredate | sal  | deptno |
+-----------+----------+------+--------+
| jiangfeng | NULL     |  333 |    444 |
+-----------+----------+------+--------+
1 row in set (0.00 sec)

(3)排序

关键字:ORDER BY

例子:

mysql> select * from emp order by sal;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | NULL       |  333 |    444 |
| zhangsan  | NULL       |  333 |    444 |
| zhangsan  | 2020-01-01 | 2222 |    333 |
+-----------+------------+------+--------+
5 rows in set (0.00 sec)

mysql> select * from emp order by sal desc;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| zhangsan  | 2020-01-01 | 2222 |    333 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | NULL       |  333 |    444 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | 2021-06-17 |    2 |      2 |
+-----------+------------+------+--------+
5 rows in set (0.00 sec)

其中DESC和ASC是排序顺序关键字,DESC表示按照字段进行降序排序,ASC表示升序,如果不写默认升序。
ORDER BY 后面可以跟多个不同的排序字段,如果排序字段的值一样,则按照第二个排序字段进行排序,以此类推。如果只有一个排序字段,则这些字段相同的记录将会无序排序。

(4)限制

​ 如果只希望显示一部分,而不是全部,可以用关键字LIMIT来实现。LIMIT的语法如下:

SELECT ...[LIMIT offset_start,row_count]

其中offset_start表示记录的偏移量,row_count表示显示的行数。
默认情况下,起始偏移量为0,只需要写记录行数就可以。

举例:

mysql> select * from emp limit 3;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| zhangsan  | 2020-01-01 | 2222 |    333 |
| zhangsan  | NULL       |  333 |    444 |
+-----------+------------+------+--------+
3 rows in set (0.00 sec)

mysql> select * from emp limit 1,3;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| zhangsan  | 2020-01-01 | 2222 |    333 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | NULL       |  333 |    444 |
+-----------+------------+------+--------+
3 rows in set (0.00 sec)

(5)聚合

​ 一般情况下,用户都需要进行一些汇总操作,比如统计人数等,这时就要用到SQL的聚合操作。语法如下:

SELECT [field1,field2,....] func_name
FROM tablename
[WHERE where_contition]
[GROUP BY field1,field2,...]
[WHTH ROLLUP]
[HAVING where_contition]

对其参数进行以下说明:

  • func_name 表示要做的聚合操作,也就是聚合函数,常用的有sum\count\max\min.
  • GROUP BY关键字表示要进行分类聚合的字段,比如要按照部门分类统计员工数量,部门就应该写在group by后面。
  • WITH ROLLUP时可选语法,表明是否对分类聚合后的结果进行再汇总。
  • HAVING 关键字表示对分类后的结果再进行条件的过滤。

注意:having和where的区别在于,having是对聚合后的结果进行条件的过滤,而where是在聚合前就对记录进行过滤。如果逻辑允许,尽可能用where先过滤记录,这样因为结果集减少,将对聚合的效率大大提高,最后再根据逻辑看是否用having进行再过滤。

mysql> select deptno,count(1) from emp group by deptno;
+--------+----------+
| deptno | count(1) |
+--------+----------+
|      2 |        1 |
|    333 |        1 |
|    444 |        3 |
+--------+----------+
3 rows in set (0.00 sec)

mysql> select deptno,count(1) from emp where ename='jiangfeng' group by deptno;
+--------+----------+
| deptno | count(1) |
+--------+----------+
|      2 |        1 |
|    444 |        1 |
+--------+----------+
2 rows in set (0.00 sec)

(6)表连接

​ 当需要同时显示多个表中的字段时,就可以使用表连接来实现这样的功能。从大类上分,表连接分为内连接和外连接。
​ 他们之间的最主要区别是,内连接仅选出两张表中互相匹配的记录,而外连接会选出其他不匹配的记录。

内连接例子:

mysql> select * from emp;
+-----------+------------+------+--------+
| ename     | hiredate   | sal  | deptno |
+-----------+------------+------+--------+
| jiangfeng | 2021-06-17 |    2 |      2 |
| zhangsan  | 2020-01-01 | 2222 |    333 |
| zhangsan  | NULL       |  333 |    444 |
| jiangfeng | NULL       |  333 |    444 |
| zhangsan  | NULL       |  333 |    444 |
+-----------+------------+------+--------+
5 rows in set (0.00 sec)

mysql> select * from emp1;
+--------+------------+------+--------+
| ename  | hiredate   | sal  | deptno |
+--------+------------+------+--------+
| zzz    | 2020-01-01 | 2000 |      1 |
| lisa   | 2003-02-01 | 4000 |      2 |
| bjguan | 2004-04-01 | 5000 |      1 |
| bzshen | 2005-04-01 | 4000 |      3 |
+--------+------------+------+--------+
4 rows in set (0.00 sec)

mysql> select * from dept;
+--------+----------+
| deptno | deptname |
+--------+----------+
|      1 | tech     |
|      2 | sale     |
|      3 | hr       |
+--------+----------+
3 rows in set (0.00 sec)

mysql> select ename,deptname from emp1,dept where emp1.deptno=dept.deptno;
+--------+----------+
| ename  | deptname |
+--------+----------+
| zzz    | tech     |
| lisa   | sale     |
| bjguan | tech     |
| bzshen | hr       |
+--------+----------+
4 rows in set (0.00 sec)

mysql> select ename,deptname from emp,dept where emp.deptno=dept.deptno;
+-----------+----------+
| ename     | deptname |
+-----------+----------+
| jiangfeng | sale     |
+-----------+----------+
1 row in set (0.00 sec)

外连接又分为左连接和又连接,具体定义如下:

  • 左连接:包含所有的左边表中的记录甚至右边表中没有和他匹配的记录。
  • 右连接:包含所有的又边表中的记录甚至右边表中没有和他匹配的记录。
mysql> select ename,deptname from emp left join dept on emp.deptno=dept.deptno;
+-----------+----------+
| ename     | deptname |
+-----------+----------+
| jiangfeng | sale     |
| zhangsan  | NULL     |
| zhangsan  | NULL     |
| jiangfeng | NULL     |
| zhangsan  | NULL     |
+-----------+----------+
5 rows in set (0.00 sec)

(7)子查询

某些情况下,当进行查询时,需要的条件是另外一个select语句的结果,这个时候,就要用到子查询。用于子查询的关键字主要包括in、not in、=、!=、exists、no t exists等。

mysql> select * from emp1 where deptno in(select deptno from dept);
+--------+------------+------+--------+
| ename  | hiredate   | sal  | deptno |
+--------+------------+------+--------+
| zzz    | 2020-01-01 | 2000 |      1 |
| lisa   | 2003-02-01 | 4000 |      2 |
| bjguan | 2004-04-01 | 5000 |      1 |
| bzshen | 2005-04-01 | 4000 |      3 |
+--------+------------+------+--------+
4 rows in set (0.01 sec)
posted @ 2021-06-17 18:50  better_feng  阅读(152)  评论(0编辑  收藏  举报