學習預覽:
(一)mysql 運維基礎篇(Linux雲計算從入門到精通)
(三)mysql 觸發器、存儲過程和函數(數據庫運維基礎補充)
(五)mysql數據備份—物理備份(完備+lvm快照+xtrabackup)+邏輯備份(mysqldump+導入導出)
(六)mysql複製技術—M-S主從配置(傳統+GTID)+M-M-S-S主從配置(GTID)
(七)mysql中間件mycat配置和部署(基於M-M-S-S)
(八) 數據庫集羣技術—Galera Cluster安裝與配置
(九)數據庫集羣技術Galera+mycat(數據庫運維學習終章)
聲明:
如果我們是從事Linux運維方面的話,學習mysql就必不可少吶,但是我們主要不是做數據庫開發,而主要負責mysql管理上。尤其在Linux雲計算中,主備複製、讀寫分離、HA架構、分佈式數據庫、壓力測試、性能優化、自動化運維就顯得格外重要吶。這篇博客依舊是我的學習筆記,主要介紹數據的基本知識,尤其是SQL語句。這個不僅僅是開發人員關注的,運維人員也要做一定的瞭解。所以,Let's get started .😃
CONTENT
五、數據操縱語言DML(insert,update,delete)
一、 瞭解mysql及安裝mysql8
1.1 認識mysql
先了解下關於數據庫的基本概念哦。
1.1.1 數據的存儲方式
- 1.人工管理階段(顯然效率很低)
- 2.文件系統階段(能存取海量數據,但是讀取數據很慢)
- 3.數據庫系統管理階段(不僅能存取海量數據,還建立了索引,這樣讀取數據非常快)
1.1.2 數據庫技術構成
(1)數據庫系統DBS、數據庫管理系統( DataBase Management System, DBMS ) 、
- SQL(RDS,關係型數據系統):ORACLE、 Oracle MySQL、MariaDB、 Percona server、DB2
- NoSQL(非關係型): Redis、 MongoDB、 Memcache
(2) SQL語言(結構化查詢語言)
- A. DDL語句數據庫定義語言:數據庫、表、視圖、索引、存儲過程、函數,CREATE DROP ALTER //開發人員
- B. DML語句數據庫操縱語言 :插入數據INSERT.刪除數據DELETE、更新數據UPDATE //開發人員關注的
- C. DQL語句數據庫查詢語言 :查詢數據SELECT
- D. DCL語句數據庫控制語言 :例如控制用戶的訪問權限GRANT、REVOKE
(3)數據訪問技術(讓這些php或Java這樣開發語言能夠訪問數據庫,例如我們在部署LAMP時,php-mysql就類似於這種)
- A. ODBC PHP <.php>
- B. JDBC JAVA <.jsp>
1.2 安裝mysql8最新版
安裝方式基本有三種:“二進制rpm-yum repository”、“預編譯-Generic”、和源碼包安裝-source code。 各自包的形式的如下圖,我採用 yum安裝。各種安裝包類型如圖所示,我們選擇的是第一種:
1.2.1 到官網上找到yum倉庫,點擊適合我們系統的linux7 版本
1.2.2 右鍵點擊“No thanks,just start my download”,複製鏈接地址哦!
1.2.3 下面就開始安裝咯,具體步驟看下面咯!
#方便做實驗,我就偷個懶,關掉selinux和防火牆啦
[root@Centos7-host1 ~]# sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config
[root@Centos7-host1 ~]# setenforce 0
setenforce: SELinux is disabled
[root@Centos7-host1 ~]# systemctl stop firewalld
#開始wget 我們剛剛複製的鏈接,然後直接用rpm安裝 ,用md5sum檢查哈希值有沒有問題(與官網上覈對就好了)防止下載有問題吶。yum repolist檢查倉庫裏有沒有mysql哦,有的話就開始漫長的下載過程(400M呢),大家也可以找其他的yum源安裝,網速快就OK。
[root@Centos7-host1 ~]# wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
[root@Centos7-host1 ~]# rpm -ivh mysql80-community-release-el7-3.noarch.rpm
[root@Centos7-host1 ~]# md5sum mysql80-community-release-el7-3.noarch.rpm
893b55d5d885df5c4d4cf7c4f2f6c153 mysql80-community-release-el7-3.noarch.rpm
[root@Centos7-host1 ~]# yum repolist
[root@Centos7-host1 ~]# yum install mysql-community-server.x86_64 -y
#啓動mysql並設置開機自啓動,設置密碼,通過以下方式獲取密碼登錄
[root@Centos7-host1 ~]# systemctl restart mysqld
[root@Centos7-host1 ~]# systemctl enable mysqld
[root@Centos7-host1 ~]# grep 'password' /var/log/mysqld.log
2020-04-05T22:10:55.715318Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: qdqGdjGeu7;T
[root@Centos7-host1 ~]# mysql -uroot -p'qdqGdjGeu7;T'
#登陸上去初始化密碼,密碼要符合要求不能太簡單,不然通不過
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123';
1.3 忘記密碼怎麼辦?
說明下我這是mysql8版本的修改方式,不同版本修改方式不一樣吶,不過沒有關係,上網查一下就知道啦。
#編輯/etc/my.cnf,添加skip-grant-tables
[root@Centos7-host1 ~]# vim /etc/my.cnf
[mysqld]
skip-grant-tables
#然後先重啓mysqld,再用mysql命令登入,跳過密碼吶
[root@Centos7-host1 ~]# systemctl restart mysqld
[root@Centos7-host1 ~]# mysql
#修改root密碼爲空,刷新以下並重設密碼就好了
mysql> update mysql.user set authentication_string='' where User='root';
mysql> flush privileges;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123';
#最後記得回到/etc/my.cnf刪掉或註釋掉skip-grant-tables
#最後退出,編輯/etc/my.cnf,把skip-grant-tables刪掉或註釋掉重新登錄,如下圖就修改好了:
二、數據庫(database)的基本學習
2.1 數據庫基本操作
(1)show databases;(先查看本地的數據庫,可以瞭解其概念)
系統數據庫:
- information_ schema:虛擬庫 ,主要存儲了系統中的一些數據庫對象的信息,例如用戶表信息、列信息、權限信息、字符信息等
- performance_ schema:主要存儲數據庫服務器的性能參數
- mysql :授權庫,主要存儲系統用戶的權限信息
- sys:主要存儲數據庫服務器的性能參數
業務數據庫:就是我們後面所創建的數據庫...
(2)創建業務數據庫DDL
- #創建數據庫格式:CREATE DATABASE 數據庫名;
- #查看數據庫:SHOW DATABASES;
- #選擇數據庫:SELECT database();USE 數據庫名
- #刪除數據庫:DROP DATABASE 數據庫名;
(3)剛開始不知道指令或者忘記指令可藉助help指令哦。
mysql> help
List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
? (\?) Synonym for `help'.
clear (\c) Clear the current input statement.
connect (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit (\e) Edit command with $EDITOR.
ego (\G) Send command to mysql server, display result vertically.
exit (\q) Exit mysql. Same as quit.
…………………………
2.2 MySQL數據類型
在MySQL數據庫管理系統中,可以通過存儲引擎來決定表的類型。同時, MySQL數據庫管理系統也提供了數據類型決定表存儲數據的類型。MySQL數據庫管理系統提供的數據類型(顏色標明的比較常見):
數值類型:
整數類型:TINYINT SMALLINT MEDIUMINT INT BIGINT
浮點數類型:FLOAT DOUBLE
定點數類型:DEC
位類型:BIT
字符串類型:
CHAR系列:CHAR VARCHAR
TEXT系列:TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB系列:TINYBLOB BLOB MEDIUMBLOB LONGBLOB
BINARY系列:BINARY VARBINARY
枚舉類型: ENUM
集合類型: SET
時間和日期類型: DATE TIME DATETIME TIMESTAMP YEAR
2.2.1 整型int學習
大家所看到的別人所創建的int(10),指的是整型的寬度,並不是數值位的限制。所以整型沒有必要指定寬度哦,默認就好了。
--有符號,默認是有符號的,
create database learning; --創建數據庫
use learning; --使用數據庫
create table t1(tinyint_t1 tinyint, int_t1 int); --在數據庫中創建字段
desc t1; --查看錶的結構
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| tinyint_t1 | tinyint | YES | | NULL | |
| int_t1 | int | YES | | NULL | |
+------------+---------+------+-----+---------+-------+
insert into t1 values(111,111); --向表中插入數據
select * from t1; --查看t1中數據
+------------+--------+
| tinyint_t1 | int_t1 |
+------------+--------+
| 111 | 111 |
+------------+--------+
1 row in set (0.00 sec)
--創建無符號的,unsigned,只能存正值。自己插入數據,查看試試。因爲沒有符號,所以數值範圍又大了
create table t2(tinyint_t2 tinyint unsigned, int_t2 int unsigned);
2.2.2 浮點數學習
作用:用於存儲用戶的身高、體重、薪水等
浮點數(float)和定點數(decimal)都可以用類型名稱後加(M,D)的方式來表示,(M,D)表示共顯示M位數字(整數位+小數位) ,其中D位於小數點後面,M和D又稱爲精度和標度。
float和double在不指定精度時,默認會按照實際的精度(由實際的硬件和操作系統決定)來顯示,而decimal在不指定精度時,默認的整數位爲10 ,默認的小數位爲0
定點數在MySQL內部以字符串形式存儲,比浮點數更精確,適合用來表示貨幣等精度高的數據。
float和decimal 如果加(M,D)它們的數值就受到限制了,他們兩主要是精度不一樣,下面可以觀察下,同樣插入一個數據,精度卻不一樣。
create table t4(float_test float(5,2),decimal_test decimal(5,2));
insert into t4 value(10.245,10.245);
desc t4;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| float_test | float(5,2) | YES | | NULL | |
| decimal_test | decimal(5,2) | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
select * from t4;
+------------+--------------+
| float_test | decimal_test |
+------------+--------------+
| 10.24 | 10.25 |
+------------+--------------+
當我們遇到下面warning的提示時,可以通過show warnings 查看警告信息。但在這邊並沒有什麼影響。
2.2.3 時間類型學習
時間和日期類型測試:year. date. time. datetime. timestamp
作用:用於存儲用戶的註冊時間,文章的發佈時間,文章的更新時間,員工的入職時間等
咱們可以創建個表看看他們的區別,我們用now()函數獲取當前的時間:
create table t5(y year,d date,t time,dt datetime);
insert into t5 value(now(),now(),now(),now());
desc t5;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| y | year | YES | | NULL | |
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
select * from t5;
+------+------------+----------+---------------------+
| y | d | t | dt |
+------+------------+----------+---------------------+
| 2020 | 2020-04-06 | 11:35:01 | 2020-04-06 11:35:01 |
+------+------------+----------+---------------------+
但是我們要注意的有:其它的時間, 按要求插入,當插入年份時,儘量使用4位值
插入兩位年份時,如果數值<=69 ,以20開頭,比如65,結果2065;如果>=70,以19開頭,比如82,結果1982
看如下這個例子知道了吧,所以不能偷懶呀,最好輸入四位日期。
create table t6(born_year year);
insert into t6 value(47),(80);
select * from t6;
+-----------+
| born_year |
+-----------+
| 2047 |
| 1980 |
+-----------+
2.2.4 字符串類型學習
字符串類型測試: CHAR、 VARCHAR
作用:用於存儲用戶的姓名、愛好、發佈的文章等(可以限定字符串個數)
CHAR:列的長度固定爲創建表時聲明的長度: 0~ 255
VARCHAR:列中的值爲可變長字符串,長度: 0~ 65535
注:在檢索的時候, CHAR列刪除了尾部的空格,而VARCHAR則保留這些空格
create table t7(ch1 char(4),var1 varchar(4));
insert into t7 value('abcd','abcd');
select * from t7;
2.2.5 枚舉類型和集合類型
ENUM類型即枚舉類型、集合類型SET測試,這個很實用的。
字段的值只能在給定範圍中選擇
常見的是單選按鈕和複選框
enum 單選只能在給定的範圍內選 一個值,如性別sex男male/女female
set 多選在給定的範圍內可以選擇 一個或一個以上的值(愛好1,愛好2,愛好3... )
表 school.student3
姓名 name varchar(50)
性別 sex enum('m','f)
愛好 hobby set('music,'book,'game',disc")
操作下:
create table student_info(name varchar(50),sex enum('man','woman'),hobby set('readding','music','skiing','game'));
desc student_info;
+-------+----------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------------------------------+------+-----+---------+-------+
| name | varchar(50) | YES | | NULL | |
| sex | enum('man','woman') | YES | | NULL | |
| hobby | set('reading','music','skiing','game') | YES | | NULL | |
+-------+----------------------------------------+------+-----+---------+-------+
--通過下面這個命令查看創建表的語句
show create table student_info\G;
*************************** 1. row ***************************
Table: student_info
Create Table: CREATE TABLE `student_info` (
`name` varchar(50) DEFAULT NULL,
`sex` enum('man','woman') DEFAULT NULL,
`hobby` set('reading','music','skiing','game') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
insert into student_info values('Jack','man','game');
insert into student_info values('Jackson','man','reading,music');
select * from student_info;
+---------+------+---------------+
| name | sex | hobby |
+---------+------+---------------+
| Jack | man | game |
| Jackson | man | reading,music |
+---------+------+---------------+
三、表完整性約束
作用:用於保證數據的完整性和一致性
約束條件 說明
- PRIMARY KEY (PK) 標識該字段爲該表的主鍵,可以唯一的標識記錄,不可以爲空 UNIQUE + NOT NULL
- FOREIGN KEY (FK) 標識該字段爲該表的外鍵,實現表與表(父表主鍵/子表1外鍵/子表2外鍵)之間的關聯
- NOT NULL 標識該字段不能爲空
- UNIQUE KEY (UK) 標識該字段的值是唯一的,可以爲空,一個表中可以有多個UNIQUE KEY
- AUTO INCREMENT 標識該字段的值自動增長(整數類型,而且爲主鍵)
- DEFAULT 爲該字段設置默認值
- UNSIGNED 無符號,正數
- ZEROFILL 使用0填充下例如000001
說明:
1.是否允許爲空,默認NULL,可設置NOT NULL ,字段不允許爲空,必須賦值
2.字段是否有默認值,缺省的默認值是NULL ,如果插入記錄時不給字段賦值,此字段使用默認值
sex enum('male',female) not null default 'male'
age int unsigned NOT NULL default 20 必須爲正值(無符號),不允許爲空,默認是20
3.是否是key
主鍵 primary key
外鍵 foreign key
索引 (index,unique...)
熟悉上面的約束條件,下面我們開始學習如何設置單列主鍵,唯一約束(unique),複合主鍵和外鍵(foreign)
3.1 設置單列主鍵(primary key)
首先知道設置成主鍵的字段不允許重複,且不允許爲null,所以說它是(unique+not null)。設置爲unique的字段就不允許重複啦,但可以爲空,咱們看下面這個實例(把前面學習應用一下喲):
create database employment;
use employment;
create table employee(
-> name varchar(20),
-> sex enum('male','female') not null default 'male',
-> age int not null default 18,
-> employ_date date not null,
-> anth_id varchar(18),
-> unique(name),
-> primary key(anth_id)
-> );
--一般我們在最後聲明unique和主鍵,當然也可以在前面就定義好。
--觀察上面的SQL語句在對應下面的表的結構看一下,一目瞭然是不是
desc employee;
+-------------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------+------+-----+---------+-------+
| name | varchar(20) | YES | UNI | NULL | |
| sex | enum('male','female') | NO | | male | |
| age | int | NO | | 18 | |
| employ_date | date | NO | | NULL | |
| anth_id | varchar(18) | NO | PRI | NULL | |
+-------------+-----------------------+------+-----+---------+-------+
--插入兩行數據
insert into employee values('Jack','male',20,20101221,'3342145544'),('alice','femaale',19,20191212,'12367446');
select * from employee;
+-------+--------+-----+-------------+------------+
| name | sex | age | employ_date | anth_id |
+-------+--------+-----+-------------+------------+
| alice | female | 19 | 2019-12-12 | 12367446 |
| Jack | male | 20 | 2010-12-21 | 3342145544 |
+-------+--------+-----+-------------+------------+
--假如插入一個alice同名的怎麼辦,很明顯報錯,因爲已經有alice啦
insert into employee values('alice','female',29,20111012,'1224456636');
ERROR 1062 (23000): Duplicate entry 'alice' for key 'employee.name'
--現在插入一個id爲null的數據也是不可以的,因爲主鍵不能爲空哦
insert into employee values('aee','female',29,20111012,null);
ERROR 1048 (23000): Column 'anth_id' cannot be null
3.2 設置複合主鍵
有時候只用一個主鍵還不能唯一標識行,這就需要兩個主鍵啦,例如下面這種情況只能用兩個字段作爲主鍵咯!
host _ip 存儲主機IP
service_ name 服務名
port 服務對應的端口
allow(Y,N) 服務是否允許訪問
主鍵:host_ip + port = primary key
create table service(
-> ip varchar(15),
-> service varchar(10) not null,
-> port int not null,
-> allow enum('yes','no') default 'no',
-> primary key(ip,port));
desc service;
+---------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| ip | varchar(15) | NO | PRI | NULL | |
| service | varchar(10) | NO | | NULL | |
| port | int | NO | PRI | NULL | |
| allow | enum('yes','no') | YES | | no | |
+---------+------------------+------+-----+---------+-------+
這個很簡單,只要在後面添加primary key( ),括號裏輸入對應的字段名就OK了。我就不插入數據測試咯。
3.3 設置foreign外鍵
這就運用在幾個表有聯繫的情況下啦,咱們看如下例子:
我們是基於5.1例子的基礎上做的吶,然後創建salary表,employee作爲父表,salary子表中name爲外鍵,關聯父表( employees主鍵name ),同步更新,同步刪除。
create table salary(
-> dep_id int not null auto_increment,
-> name varchar(20),
-> salary float(8,2) not null,
-> primary key(dep_id),
-> foreign key(name) references employee(name) on update cascade on delete cascade);
desc salary ;
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| dep_id | int | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | MUL | NULL | |
| salary | float(8,2) | NO | | NULL | |
+--------+-------------+------+-----+---------+----------------+
--在salary表中插入employee中兩個數據,我們只選擇name和salary字段,因爲dep_id默認整數增長
insert into salary(name,salary) values('alice',40000);
insert into salary(name,salary) values( 'Jack',20000);
select * from salary;
+--------+-------+----------+
| dep_id | name | salary |
+--------+-------+----------+
| 1 | alice | 40000.00 |
| 2 | Jack | 20000.00 |
+--------+-------+----------+
--下面我們開始測試父表和字表之間的連接問題啦,更新一下名字試試
update employee set name='Jackson' where name='Jack';
select * from salary;
+--------+---------+----------+
| dep_id | name | salary |
+--------+---------+----------+
| 1 | alice | 40000.00 |
| 2 | Jackson | 20000.00 |
+--------+---------+----------+
--刪除用戶Alice試試
delete from employee where name='alice';
select * from salary;
+--------+---------+----------+
| dep_id | name | salary |
+--------+---------+----------+
| 2 | Jackson | 20000.00 |
+--------+---------+----------+
四、修改表 ALTER TABLE
語法:
- 1.修改表名 ALTER TABLE 表名 RENAME 新表名;
- 2.增加字段
ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條..] //默認添加在後面
ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件..] FIRST;
ALTER TABLE 表名 ADD 字段名 數據類型 [完整性約束條件..] AFTER 字段名;
- 3.刪除字段 ALTER TABLE 表名 DROP 字段名;
- 4.修改字段 ALTER TABLE 表名 MODIFY 字段名 數據類型 [完整性約束條件..];
示例:
1.修改存儲引擎
mysq|> alter table service engine=innodb; //engine=myisam|memoryl...
2.添加字段
mysql> create table student10 (id int);
mysq|> alter table student10
-> add name varchar(20) not null,
-> add age int not null default 22;
mysql> alter table student10
-> add stu_num int not null after name; //添加name字段之後
mysql> alter table student10
-> add sex enum('male','female') default 'male' first; //添加到最前面
3.刪除字段
mysql> alter table student10 drop sex;
mysql> alter table service drop mac;
4.修改字段類型modify
mysql> alter table student10
-> modify age tinyint;
mysql> alter table student10
-> modify id int not null primary key; //修改字段類型、約束、主鍵
5.增加約束(針對已有的主鍵增加auto_ increment )
mysql> alter table student10 modify id int not null primary key auto_ increment; //錯誤,該字段已經是primary,
ERROR 1068 (42000): Multiple primary key defined
mysql> alter table student10 modify id int not null auto_ increment; //正確這樣寫,省去primary key6.增加複合主鍵
mysql> alter table service
-> add primary key(host_ip,port);
7.增加主鍵
mysql> alter table student1
-> add primary key(id);
8.增加主鍵和自動增長
mysql> alter table student1
-> modify id int not null primary key auto_increment;
9.刪除主鍵[ primary key, 如果存在auto_increment]
a.先刪除自增約束
mysql> alter table student10 modify id int not null;
b.刪除主鍵
mysql> alter table student10
-> drop primary key;
另外複製表和刪除表也在這說一下:
複製表
- 複製表結構+記錄( key不會複製:主鍵、外鍵和索引): mysql> create table new_service select * from service;
- 只複製表結構:mysql> create table new1_ service select * from service where 1=2; //條件爲假,查不到任何記錄
- 複製表結構,包括Key: mysql> create table t4 like employees;
刪除表 DROP TABLE 表名;
五、數據操縱語言DML(insert,update,delete)
5.1 插入數據INSERT
1.插入完整數據(順序插入) INSERT INTO 表名 VALUES (值1,值2,值3...值n);
2.指定字段插入數據 INSERT INTO表名(字段2,字段... VALUES (值2,3值...);
3.插入多條記錄
INSERT INTO 表名 VALUES
(值1,值2,值3...值n),
(值1,值2,值3...值n),
(值1,值2,值3...值n);
4.插入查詢結果
INSERT INTO 表1(字段1,字段2,字段...字段n) SELECT (字段1,字段2,字段3...字段n) FROM 表2 WHERE [條件]
5.2 更新數據
UPDATE 表名 SET 字段1=值1,字段2=值2 WHERE [CONDITION];
還記得我們密碼忘記怎麼修改的了嘛,就是利用更新操作吶。
5.3 刪除數據DELETE
記得加上條件,不然全部都刪掉咯
DELETE FROM 表名 WHERE CONITION;
六、mysql查詢語句
方便我們後面學習,可以利用下面SQL語句直接參創建employee表
create database company;
create table company.employee( id int primary key AUTO_INCREMENT not null, name varchar(30) not null, sex enum('male','female') default 'male' not null, hire_date date not null, post varchar(50) not null, job_description varchar(100), salary double(15,2) not null, office int, dep_id int);
insert into company.employee(name,sex,hire_date,post,job_description,salary,office,dep_id) values ('jack','male','20180202','instructor','teach',5000,501,100), ('tom','male','20180203','instructor','teach',5500,501,100), ('robin','male','20180202','instructor','teach',8000,501,100), ('alice','female','20180202','instructor','teach',7200,501,100), ('tianyun','male','20180202','hr','hrcc',600,502,101), ('harry','male','20180202','hr',NULL,6000,502,101), ('emma','female','20180206','sale','salecc',20000,503,102), ('christine','female','20180205','sale','salecc',2200,503,102), ('zhuzhu','male','20180205','sale',NULL,2200,503,102), ('gougou','male','20180205','sale','',2200,503,102);
6.1單表查詢
6.1.1 簡單查詢
(1)簡單查詢
select * from employee;
SELECT name, salary, dep_id FROM employee;
(2)避免重複 DISTINCT
SELECT post FROM employee;
SELECT DISTINCT post FROM employee;
注:不能部分使用DISTINCT ,通常僅用於某一字段。
(3)通過四則運算查詢
SELECT name, salary, salary*14 FROM employee;
SELECT name, salary, salary*14 AS 'Annual salary' FROM employee;
SELECT name, salary, salary*14 'Annual salary' FROM employee;
(4)定義顯示格式
CONCAT()函數用於連接字符串
SELECT CONCAT(name, ' annual salary: ', salary*14) AS 'Annual salary' FROM employee;
6.1.2 條件查詢
(1)單條件查詢
select name,post from employee where post='hr';
(2)多條件查詢
select name,salary from employee where post='hr' and salary>1000;
(3)關鍵詞 between and
select name,salary from employee where salary between 5000 and 15000;
select name,salary from employee where salary not between 5000 and 15000;
(4)關鍵詞 is null
select name,post from employee where job_description is null;
select name,post from employee where job_description is not null;
(5)關鍵字in集合查詢
select name,salary from employee where salary =4000 or salary =5000 or salary = 6000;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| harry | 6000.00 |
+-------+---------+
select name,salary from employee where salary in(4000,5000,6000);
select name,salary from employee where salary not in(4000,5000,6000);
(6)關鍵字like模糊查詢
select * from employee where name like 'ali%'; --%代表任多個字符,相當於Linux下的*
select * from employee where name like 'ali__'; --_一個下劃線代表任意一個字符
6.1.3 查詢排序
(1)單列排序
select * from employee order by salary ; --默認升序
select name ,salary from employee order by salary asc;
select name ,salary from employee order by salary desc; --降序
(2)多列排序(按照入職時間降序,再按薪水升序)
select * from employee order by hire_date desc,salary asc;
6.1.4 限制查詢的記錄數(limit)
select * from employee order by salary desc limit 5; --默認初始位置爲0
select * from employee order by salary desc limit 0,5; --
select * from employee order by salary desc limit 4,5; --從第四條開始顯示5條
6.1.5 使用集合函數查詢
select count(*) from employee; --計數
select count(*) from employee where dep_id = 101;
select max(salary) from employee; --求薪資最高的
select min(salary) from employee; --薪資最低
select avg(salary) from employee; --平均值
select sum(salary) from employee; --求和
select sum(salary) from employee where dep_id =101; --101部門的薪資和
select name,sex,hire_date,post,salary,dep_id from employee where salary=(select max(salary) from employee); --查詢薪資最高的人的相關信息
+------+--------+------------+------+----------+--------+
| name | sex | hire_date | post | salary | dep_id |
+------+--------+------------+------+----------+--------+
| emma | female | 2018-02-06 | sale | 20000.00 | 102 |
+------+--------+------------+------+----------+--------+
6.1.6 分組查詢
(1)group by 和group_concat()函數一起使用,實現效果可看下面。
select dep_id ,group_concat(name) from employee group by dep_id ;
+--------+------------------------------+
| dep_id | group_concat(name) |
+--------+------------------------------+
| 100 | jack,tom,robin,alice |
| 101 | tianyun,harry |
| 102 | emma,christine,zhuzhu,gougou |
+--------+------------------------------+
select dep_id ,group_concat(name) as 'employ_members' from employee group by dep_id ;
+--------+------------------------------+
| dep_id | employ_members |
+--------+------------------------------+
| 100 | jack,tom,robin,alice |
| 101 | tianyun,harry |
| 102 | emma,christine,zhuzhu,gougou |
+--------+------------------------------+
select dep_id ,group_concat(salary) as 'employ_members' from employee group by depp_id ;
+--------+----------------------------------+
| dep_id | employ_members |
+--------+----------------------------------+
| 100 | 5000.00,5500.00,8000.00,7200.00 |
| 101 | 600.00,6000.00 |
| 102 | 20000.00,2200.00,2200.00,2200.00 |
+--------+----------------------------------+
(2)group by函數與集合函數一起使用
select dep_id ,sum(salary ) from employee group by dep_id ; --按部門號分組計算每組工資總和
+--------+--------------+
| dep_id | sum(salary ) |
+--------+--------------+
| 100 | 25700.00 |
| 101 | 6600.00 |
| 102 | 26600.00 |
+--------+--------------+
select dep_id ,avg(salary) from employee group by dep_id ;
+--------+-------------+
| dep_id | avg(salary) |
+--------+-------------+
| 100 | 6425.000000 |
| 101 | 3300.000000 |
| 102 | 6650.000000 |
+--------+-------------+
6.1.7 使用正則表達式查詢
select * from employee where name regexp '^ali'; --找出以ali開頭的
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 8 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+---
select * from employee where name regexp 'yun$'; --找出yun結尾的
+----+---------+------+------------+------+-----------------+--------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+---------+------+------------+------+-----------------+--------+--------+--------+
| 9 | tianyun | male | 2018-02-02 | hr | hrcc | 600.00 | 502 | 101 |
+----+---------+------+------------+------+-----------------+--------+--------+--------+
select * from employee where name regexp 'm{2}'; --找出m出現兩次的
+----+------+--------+------------+------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+------+--------+------------+------+-----------------+----------+--------+--------+
| 11 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
+----+------+--------+------------+------+-----------------+----------+--------+--------+
總結:對字符串匹配的方式
- WHERE name = 'tom'; //精確查詢,記不清的話用下面的這兩種模糊查詢哦
- WHERE name LIKE 'to%';
- WHERE name REGEXP 'yun$';
6.2 多表查詢
- 多表連接查詢
- 複合條件連接查詢
- 子查詢
準備兩張表,employee1和department1,分別插入數據。可以直接複製我的,我們主要學習多表查詢,創建表就複製下好嘞。
--employee1表
create table company.employee1(
-> emp_id int auto_increment primary key not null,
-> emp_name varchar(50),
-> age int,
-> dept_id int );
insert into employee1(emp_name,age,dept_id) values
-> ('tianyun',19,200),
-> ('Tom',29,201),
-> ('Jack',30,201),
-> ('Alice',24,202),
-> ('robin',40,200),
-> ('natasha',28,204);
--department1表
create table company.department1(dept_id int,dept_name varchar(50));
insert into department1 values (200,'hr'), (201,'it'), (202,'sale'), (203,'fd');
6.2.1 交叉連接(笛卡爾積,不使用任何匹配條件)
select employee1.emp_name,employee1.age,employee1.dept_id,department1.dept_id,department1.dept_name from employee1,department1;
+----------+------+---------+---------+-----------+
| emp_name | age | dept_id | dept_id | dept_name |
+----------+------+---------+---------+-----------+
| tianyun | 19 | 200 | 203 | fd |
| tianyun | 19 | 200 | 202 | sale |
| tianyun | 19 | 200 | 201 | it |
| tianyun | 19 | 200 | 200 | hr |
| Tom | 29 | 201 | 203 | fd |
| Tom | 29 | 201 | 202 | sale |
| Tom | 29 | 201 | 201 | it |
| Tom | 29 | 201 | 200 | hr |
| Jack | 30 | 201 | 203 | fd |
| Jack | 30 | 201 | 202 | sale |
| Jack | 30 | 201 | 201 | it |
| Jack | 30 | 201 | 200 | hr |
| Alice | 24 | 202 | 203 | fd |
| Alice | 24 | 202 | 202 | sale |
| Alice | 24 | 202 | 201 | it |
| Alice | 24 | 202 | 200 | hr |
| robin | 40 | 200 | 203 | fd |
| robin | 40 | 200 | 202 | sale |
| robin | 40 | 200 | 201 | it |
| robin | 40 | 200 | 200 | hr |
| natasha | 28 | 204 | 203 | fd |
| natasha | 28 | 204 | 202 | sale |
| natasha | 28 | 204 | 201 | it |
| natasha | 28 | 204 | 200 | hr |
+----------+------+---------+---------+-----------+
6.2.2 內連接(只連接匹配的行)
比如只找出有部門的員工(部門表沒有natasha所在的部門)
select emp_name,age,employee1.dept_id,dept_name from employee1,department1 where employee1.dept_id=department1.dept_id;
+----------+------+---------+-----------+
| emp_name | age | dept_id | dept_name |
+----------+------+---------+-----------+
| tianyun | 19 | 200 | hr |
| Tom | 29 | 201 | it |
| Jack | 30 | 201 | it |
| Alice | 24 | 202 | sale |
| robin | 40 | 200 | hr |
+----------+------+---------+-----------+
6.2.3 外連接
語法:
(1)外連接(左連接)
例如找出所有員工及其所屬的部門,包括沒有部門的員工
select emp_name,age,dept_name from employee1 left join department1 on employee1.dept_id=department1.dept_id;
+----------+------+-----------+
| emp_name | age | dept_name |
+----------+------+-----------+
| tianyun | 19 | hr |
| robin | 40 | hr |
| Tom | 29 | it |
| Jack | 30 | it |
| Alice | 24 | sale |
| natasha | 28 | NULL |
+----------+------+-----------+
(2)外連接(右連接)
例如找出所有部門包含的員工,包括空部門
select emp_name,age,dept_name from employee1 right join department1 on employee1.ddept_id=department1.dept_id;
+----------+------+-----------+
| emp_name | age | dept_name |
+----------+------+-----------+
| tianyun | 19 | hr |
| Tom | 29 | it |
| Jack | 30 | it |
| Alice | 24 | sale |
| robin | 40 | hr |
| NULL | NULL | fd |
+----------+------+-----------+
6.2.4 子查詢
- 子查詢是將一個查詢語句嵌套在另一個查詢語句中。內層查詢語句的查詢結果,可以爲外層查詢語句提供查詢條件。
- 子查詢中可以包含: IN、NOT IN、ANY、ALL、EXISTS和NOT EXISTS等關鍵字
- 還可以包含比較運算符: =、!=、>、<等
(1)帶IN關鍵字的子查詢
查詢employee表,但dept_id必須在department表中出現過
select * from employee1
-> where dept_id in (select dept_id from department1);
+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | tianyun | 19 | 200 |
| 2 | Tom | 29 | 201 |
| 3 | Jack | 30 | 201 |
| 4 | Alice | 24 | 202 |
| 5 | robin | 40 | 200 |
+--------+----------+------+---------+
5 rows in set (0.00 sec)
(2)帶比較運算符的子查詢 =、!=、>、 .>=、 <、<=、<> .
查詢年齡大於等於25歲員工所在部門(查詢老齡化的部門)
select dept_id,dept_name from department1
-> where dept_id in
-> (select distinct dept_id from employee1 where age >= 25);
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 201 | it |
| 200 | hr |
+---------+-----------+
2 rows in set (0.00 sec)
(3)帶EXISTS關鍵字的子查詢
EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄,而是返回一個真假值。
當返回Ture時,外層查詢語句將進行查詢;當返回值爲False時,外層查詢語句不進行查詢
department表中存在dept_id=203 , Ture
select * from employee1
-> where exists (select * from department1 where dept_id=203);
+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | tianyun | 19 | 200 |
| 2 | Tom | 29 | 201 |
| 3 | Jack | 30 | 201 |
| 4 | Alice | 24 | 202 |
| 5 | robin | 40 | 200 |
| 6 | natasha | 28 | 204 |
+--------+----------+------+---------+
6 rows in set (0.00 sec)
--輸入部門爲205時,不存在,false
select * from employee1 where exists (select * from department1 where dept_id=205);
Empty set (0.00 sec)
結束語:
到現在Linux雲計算之mysql運維基礎篇就結束啦,後面我還會整理數據庫的索引、視圖,數據備份,mysql中間件和集羣技術等。有興趣的童鞋可以點贊收藏下,期待我的下一次創作吧。😃