1. 程式人生 > 其它 >Mysql筆記01-安裝和SQL基礎

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)