(一)mysql 運維基礎篇(Linux雲計算從入門到精通)

學習預覽:

(一)mysql 運維基礎篇(Linux雲計算從入門到精通)

(二)mysql 索引和視圖(數據庫運維基礎補充)

(三)mysql 觸發器、存儲過程和函數(數據庫運維基礎補充)

(四)MySQL安全機制和日誌管理(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

一、 瞭解mysql及安裝mysql8

1.1 認識mysql

1.2 安裝mysql8最新版

1.3 忘記密碼怎麼辦?

二、數據庫(database)的基本學習

2.1 數據庫基本操作

2.2 MySQL數據類型

2.2.1 整型int學習

2.2.2 浮點數學習

2.2.3 時間類型學習

2.2.4 字符串類型學習

2.2.5 枚舉類型和集合類型

三、表完整性約束

3.1 設置單列主鍵(primary key)

3.2 設置複合主鍵

3.3 設置foreign外鍵

四、修改表 ALTER TABLE

五、數據操縱語言DML(insert,update,delete)

5.1 插入數據INSERT

5.2 更新數據

5.3 刪除數據DELETE

六、mysql查詢語句

6.1單表查詢

6.1.1 簡單查詢

6.1.2 條件查詢

6.1.3 查詢排序

6.1.4 限制查詢的記錄數(limit)

6.1.5 使用集合函數查詢

6.1.6 分組查詢

6.1.7 使用正則表達式查詢

6.2 多表查詢

6.2.1 交叉連接(笛卡爾積,不使用任何匹配條件)

6.2.2 內連接(只連接匹配的行)

6.2.3 外連接

6.2.4 子查詢

結束語:


一、 瞭解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 key

6.增加複合主鍵
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中間件和集羣技術等。有興趣的童鞋可以點贊收藏下,期待我的下一次創作吧。😃




 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章