#拉取镜像(不添加版本,默认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;
SQL是Structure Query Language(结构化查询语句)的缩写,它是使用关系模型的数据库应用语言。
SQL语句主要可以划分为以下3个类别。
DDL是数据定义语言的缩写,简单说就是对数据库内部的对象进行创建、删除、修改等操作语句。DDL语句更多由数据库管理员(DBA)使用,开发人员一半很少使用。
[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
语法如下:
CREATE DATABASE dbname
mysql> create database test1; Query OK, 1 row affected (0.01 sec)
其中提示的“Query OK, 1 row affected (0.01 sec)”,这段提示可以分为3部分。
语法如下:
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;
DML操作是指对数据库中表记录的操作,主要包括表记录的插入(insert)、更新(update)、删除(delete)和查询(select),是开发人员日常使用最频繁的操作。
语法格式:
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);
语法格式:
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…]
查询最简单的方式是将记录全部取出。其中'*'表示要将所有的记录都选出来,也可以用逗号分隔的所有字符串来代替。
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)
有时需要将表中的记录去掉重复后显示出来,可以使用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)
在很多情况下,用户并不需要查询所有的记录,而只是需要根据限定条件来查询一部分数据,用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)
关键字: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 后面可以跟多个不同的排序字段,如果排序字段的值一样,则按照第二个排序字段进行排序,以此类推。如果只有一个排序字段,则这些字段相同的记录将会无序排序。
如果只希望显示一部分,而不是全部,可以用关键字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)
一般情况下,用户都需要进行一些汇总操作,比如统计人数等,这时就要用到SQL的聚合操作。语法如下:
SELECT [field1,field2,....] func_name FROM tablename [WHERE where_contition] [GROUP BY field1,field2,...] [WHTH ROLLUP] [HAVING where_contition]
对其参数进行以下说明:
注意: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)
当需要同时显示多个表中的字段时,就可以使用表连接来实现这样的功能。从大类上分,表连接分为内连接和外连接。
他们之间的最主要区别是,内连接仅选出两张表中互相匹配的记录,而外连接会选出其他不匹配的记录。
内连接例子:
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)
某些情况下,当进行查询时,需要的条件是另外一个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)