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)