MySQL基礎

數據庫管理軟件分類

  • 關係型:如sqllite,db2,oracle,access,sql server,MySQL,注意:sql語句通用
  • 非關係型:mongodb,redis,memcache
  • 能夠簡單的理解爲:關係型數據庫須要有表結構,非關係型數據庫是key-value存儲的,沒有表結構

mysql軟件安裝

1、Window版本

1.安裝步驟

  • 步驟1:下載:MySQL Community Server 5.7.16 下載
  • 步驟2:解壓:若是想要讓MySQL安裝在指定目錄,那麼就將解壓後的文件夾移動到指定目錄,如:C:\mysql-5.7.16-winx64
  • 步驟3:添加環境變量:【右鍵計算機】--》【屬性】--》【高級系統設置】--》【高級】--》【環境變量】--》【在第二個內容框中找到 變量名爲Path 的一行,雙擊】 --> 【將MySQL的bin目錄路徑追加到變值值中,用 ; 分割】
  • 步驟4:初始化:mysqld --initialize-insecure
  • 步驟5:啓動MySQL服務:mysqld # 啓動MySQL服務
  • 步驟6:啓動MySQL客戶端並鏈接MySQL服務:mysql -u root -p # 鏈接MySQL服務器

2.製做MySQL的Windows服務

  • 製做MySQL的Windows服務,在終端執行此命令:"c:\mysql-5.7.16-winx64\bin\mysqld" --install 注意:--install前,必須用絕對路徑
  • 移除MySQL的Windows服務,在終端執行此命令:"c:\mysql-5.7.16-winx64\bin\mysqld" --remove
  • 註冊成服務以後,之後再啓動和關閉MySQL服務時,僅需執行以下命令:
  • 啓動MySQL服務:net start mysql 關閉MySQL服務:net stop mysql

mysql軟件基本管理

1、windows平臺下

1.忘記密碼

  • 關閉mysql服務
  • 在cmd中執行:mysqld --skip-grant-tables
  • 在cmd中執行:mysql
  • 執行以下sql:
  • update mysql.user set authentication_string=password('') where user = 'root';
  • flush privileges;
  • 殺死mysqld: tskill mysqld
  • 重啓mysql服務

2.配置文件my.ini

  • 強調:配置文件中的註釋能夠有中文,可是配置項中不能出現中文

3.統一字符編碼

?
1
2
3
4
5
6
7
8
9
10
11
12
#1. 修改配置文件
[mysqld]
character - set - server = utf8
collation - server = utf8_general_ci
[client]
default - character - set = utf8
[mysql]
default - character - set = utf8
 
#2. 重啓服務
#3. 查看修改結果:
#show variables like '%char%'

存儲引擎

  • 存儲引擎就是表的類型
  • 查看MySQL支持的存儲引擎show engines;
  • 指定表類型/存儲引擎:
  • create table t1(id int)engine=innodb; #通常用這個
  • create table t2(id int)engine=memory;
  • create table t3(id int)engine=blackhole;
  • create table t4(id int)engine=myisam;

操做庫

1、基礎操做

一、增

  • create database db1 charset utf8;

二、刪

  • drop database db1;

三、改

  • alter database db1 charset utf8;

四、查

  • show databases;
  • show create database db1;
  • select database();

2、導入導出

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1 、導出數據庫數據:
#語法:
# mysqldump -h 服務器 -u用戶名 -p密碼 數據庫名 > 備份文件.sql
 
#示例:
#單庫備份
mysqldump - uroot - p123 db1 > db1.sql
mysqldump - uroot - p123 db1 table1 table2 > db1 - table1 - table2.sql
 
#多庫備份
mysqldump - uroot - p123 - - databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql
 
#備份全部庫
mysqldump - uroot - p123 - - all - databases > all .sql
 
2 、導入數據庫數據:
mysqldump - u root - p密碼  數據庫名稱 < 文件路徑
#方法一:
[root@bubu backup] # mysql -uroot -p123 < /backup/all.sql
 
#方法二:
mysql> use db1;
mysql> SET SQL_LOG_BIN = 0 ;
mysql> source / root / db1.sql
 
#注:若是備份/恢復單個庫時,能夠修改sql文件
DROP database if exists school;
create database school;
use school;
 
3 、執行導入文件:
create database db5
mysqldump - u root - p - d db5 < db1.sql

3、其餘操做

  • use db1 #選擇數據庫

操做表

1、基礎操做

一、增

?
1
2
3
4
5
6
create table 表名(
字段名 1 類型[(寬度) 約束條件],
字段名 2 類型[(寬度) 約束條件],
字段名 3 類型[(寬度) 約束條件]
)engine = innodb default charset = utf8;
#注意:表中的最後一個字段不要加逗號

二、刪

  • drop table t1; #刪表
  • delete from t1;#清空表 #對於自增的字段,在用delete刪除後,再插入值,該字段仍按照刪除前的位置繼續增加
  • truncate t1 #應該用truncate清空表,比起delete一條一條地刪除記錄,truncate是直接清空表,在刪除大表時用它

三、改

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
語法:
1. 修改表名
       alter table 表名
                           rename 新表名;
 
2. 增長字段
       alter table 表名
                           add 字段名  數據類型 [完整性約束條件…],
                           add 字段名  數據類型 [完整性約束條件…];
       alter table 表名
                           add 字段名  數據類型 [完整性約束條件…]  FIRST;
       alter table 表名
                           add 字段名  數據類型 [完整性約束條件…]  AFTER 字段名;
                             
3. 刪除字段
       alter table 表名
                           drop 字段名;
 
4. 修改字段
       alter table 表名
                           modify  字段名 數據類型 [完整性約束條件…];
       alter table 表名
                           change 舊字段名 新字段名 舊數據類型 [完整性約束條件…];
       alter table 表名
                           change 舊字段名 新字段名 新數據類型 [完整性約束條件…];
示例:
1. 修改存儲引擎
mysql> alter table t1
     - > engine = innodb;
 
2. 添加字段
mysql> alter table t1
     - > add name varchar( 20 ) not null,
     - > add age int ( 3 ) not null default 22 ;
     
mysql> alter table t1
     - > add stu_num varchar( 10 ) not null after name;                / / 添加name字段以後
 
mysql> alter table t1                       
     - > add sex enum( 'male' , 'female' ) default 'male' first;          / / 添加到最前面
 
3. 刪除字段
mysql> alter table t1
     - > drop sex;
 
mysql> alter table t1
     - > drop mac;
 
4. 修改字段類型modify
mysql> alter table t1
     - > modify age int ( 3 );
mysql> alter table t1
     - > modify id int ( 11 ) not null primary key auto_increment;    / / 修改成主鍵
 
5. 增長約束(針對已有的主鍵增長auto_increment)
mysql> alter table t1 modify id int ( 11 ) not null primary key auto_increment;
ERROR 1068 ( 42000 ): Multiple primary key defined
 
mysql> alter table t1 modify id int ( 11 ) not null auto_increment;
Query OK, 0 rows affected ( 0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
6. 對已經存在的表增長複合主鍵
mysql> alter table t1
     - > add primary key(host_ip,port);       
 
7. 增長主鍵
mysql> alter table t1
     - > modify name varchar( 10 ) not null primary key;
 
8. 增長主鍵和自動增加
mysql> alter table t1
     - > modify id int not null primary key auto_increment;
 
9. 刪除主鍵
a. 刪除自增約束
mysql> alter table t1 modify id int ( 11 ) not null;
 
b. 刪除主鍵
mysql> alter table t1                                
     - > drop primary key;

四、查

  • desc t1; #查看錶結構
  • show create table t1\G; #查看錶詳細結構,可加\G
  • show tables;

2、其餘操做

1.複製表

  • 複製表結構+記錄 (key不會複製: 主鍵、外鍵和索引): create table new_service select * from service;
  • 只複製表結構: create table new1_service select * from service where 1=2;
  • create table t4 like t1;

3、數據類型

一、整數類型

  • 整數類型:TINYINT SMALLINT MEDIUMINT INT BIGINT
  • 做用:存儲年齡,等級,id,各類號碼等
  • 注意:爲該類型指定寬度時,僅僅只是指定查詢結果的顯示寬度,與存儲範圍無關。其實沒有必要指定顯示寬度,使用默認的就ok

二、浮點型

  • 定點數類型 DEC等同於DECIMAL
  • 浮點類型:FLOAT DOUBLE
  • 做用:存儲薪資、身高、體重、體質參數等

三、日期類型

  • DATE TIME DATETIME TIMESTAMP YEAR
  • DATETIME的日期範圍是1001——9999年,TIMESTAMP的時間範圍是1970——2038年。
  • 做用:存儲用戶註冊時間,文章發佈時間,員工入職時間,出生時間,過時時間等
  • create table t1(x datetime not null default now()); # 須要指定傳入空值時默認取當前時間
  • create table t2(x timestamp); # 無需任何設置,在傳空值的狀況下自動傳入當前時間

四、字符串類型

  • 官網:查看
  • 注意:char和varchar括號內的參數指的都是字符的長度
  • char類型:定長,簡單粗暴,浪費空間,存取速度快
  • varchar類型:變長,精準,節省空間,存取速度慢
  • text類型:用於保存變長的大字符串
  • length:查看字節數,char_length:查看字符數

五、枚舉類型與集合類型

  • 字段的值只能在給定範圍中選擇,如單選框,多選框
  • enum 單選 只能在給定的範圍內選一個值,如性別 sex 男male/女female sex enum('male','female','保密'), #在指定範圍內,多選一
  • set 多選 在給定的範圍內能夠選擇一個或一個以上的值(愛好1,愛好2,愛好3...) hobby set('play','music','read','study') #在指定範圍內,多選多

4、表完整性約束

約束條件與數據類型的寬度同樣,都是可選參數,做用:用於保證數據的完整性和一致性html

  • 是不是key: 主鍵: primary key 外鍵: foreign key 索引:(index,) 惟一:unique key (uk)
  • 是否容許爲空,默認null,可設置not null,字段不容許爲空,必須賦值,或者也能夠自動添加默認值 not null defalut 2
  • 無符號unsigned
  • 使用0填充 zerofill

一、unsigned

  • age int unsigned NOT NULL default 20,

二、not null與default

  • age int not null defalut 18,
  • age int not null,

三、unique

  • #方法1:在某一個字段後用unique: name varchar(20) unique,
  • #方法2:在全部字段後單獨定義unique: constraint uk_name unique(name) #建立惟一併爲其命名uk_name
  • #聯合惟一:在全部字段後單獨定義unique: unique(host,port)

四、primary key

  • #方法1:not null+unique: id int not null unique, #主鍵
  • #方法2:在某一個字段後用primary key : id int primary key, #主鍵
  • #方法3:在全部字段後單獨定義primary key: constraint pk_name primary key(id); #建立主鍵併爲其命名pk_name
  • #多列作主鍵:在全部字段後單獨定義primary key: primary key(ip,port)

五、auto_increment

  • 約束字段爲自動增加,被約束的字段必須同時被key約束
  • id int primary key auto_increment,#primary key auto_increment通常一塊兒使用

六、foreign key

  • 多對一:關聯方式:foreign key
  • 多對多:關聯方式:foreign key + 一張新的表
  • 一對一:關聯方式:foreign key+unique
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""
多對一:關聯方式:foreign key
多對多:關聯方式:foreign key + 一張新的表
一對一:關聯方式:foreign key+unique
 
=====================多對一=====================
create table press(
id int primary key auto_increment,
name varchar(20)
);
 
create table book(
id int primary key auto_increment,
name varchar(20),
press_id int not null,
foreign key(press_id) references press(id) on delete cascade on update cascade  #一個出版社能夠出版多本書
);
 
=====================多對多=====================
create table author(
id int primary key auto_increment,
name varchar(20)
);
 
create table book(
id int primary key auto_increment,
name varchar(20),
);
 
#這張表就存放做者表與書表的關係,即查詢兩者的關係查這表就能夠了
create table author2book(
id int not null unique auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key(author_id) references author(id) on delete cascade on update cascade,  #===多對多====
constraint fk_book foreign key(book_id) references book(id) on delete cascade on update cascade,        #===多對多====
primary key(author_id,book_id)
);
 
=====================一對一=====================
create table customer(
id int primary key auto_increment,
name varchar(20) not null,
qq varchar(10) not null,
phone char(16) not null
);
 
create table student(
id int primary key auto_increment,
class_name varchar(20) not null,
customer_id int unique, #該字段必定要是惟一的
foreign key(customer_id) references customer(id) #外鍵的字段必定要保證unique
on delete cascade
on update cascade
);
 
"""

操做記錄

1、基礎操做

一、增

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. 插入完整數據(順序插入)
     語法一:
     INSERT INTO 表名(字段 1 ,字段 2 ,字段 3 …字段n) VALUES(值 1 ,值 2 ,值 3 …值n);
 
     語法二:
     INSERT INTO 表名 VALUES (值 1 ,值 2 ,值 3 …值n);
 
2. 指定字段插入數據
     語法:
     INSERT INTO 表名(字段 1 ,字段 2 ,字段 3 …) VALUES (值 1 ,值 2 ,值 3 …);
 
3. 插入多條記錄
     語法:
     INSERT INTO 表名 VALUES
         (值 1 ,值 2 ,值 3 …值n),
         (值 1 ,值 2 ,值 3 …值n),
         (值 1 ,值 2 ,值 3 …值n);
         
4. 插入查詢結果
     語法:
     INSERT INTO 表名(字段 1 ,字段 2 ,字段 3 …字段n)
                     SELECT (字段 1 ,字段 2 ,字段 3 …字段n) FROM 表 2
                     WHERE …;

二、刪

?
1
2
3
4
5
6
7
語法:
     DELETE FROM 表名
         WHERE CONITION;
 
示例:
     DELETE FROM mysql.user
         WHERE password = ’’;

三、改

?
1
2
3
4
5
6
7
8
9
語法:
     UPDATE 表名 SET
         字段 1 = 1 ,
         字段 2 = 2 ,
         WHERE CONDITION;
 
示例:
     UPDATE mysql.user SET password = password(‘ 123 ’)
         where user = ’root’ and host = ’localhost’;

四、查

①單表

1):單表查詢的語法

?
1
2
3
4
5
6
SELECT  DISTINCT 字段 1 ,字段 2. .. FROM 表名
                   WHERE 條件
                   GROUP BY field
                   HAVING 篩選
                   ORDER BY field
                   LIMIT 限制條數

2):關鍵字的執行優先級

  • -> from -> where -> group by-> having-> select-> distinct-> order by-> limit
  • 1.找到表:from
    • 連表的狀況
    • 1.1 on 執行on過濾
    • 1.2 join 添加外部行
  • 2.拿着where指定的約束條件,去文件/表中取出一條條記錄
  • 3.將取出的一條條記錄進行分組group by,若是沒有group by,則總體做爲一組
  • 4.將分組的結果進行having過濾
  • 5.執行select
  • 6.去重distinct
  • 7.將結果按條件排序:order by
  • 8.限制結果的顯示條數

3):簡單查詢

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
company.employee
     員工 id      id                  int            
     姓名        emp_name            varchar
     性別        sex                 enum
     年齡        age                 int
     入職日期     hire_date           date
     崗位        post                varchar
     職位描述     post_comment        varchar
     薪水        salary              double
     辦公室       office              int
     部門編號     depart_id           int
 
 
 
#建立表
create table employee(
id int not null unique auto_increment,
name varchar( 20 ) not null,
sex enum( 'male' , 'female' ) not null default 'male' , #大部分是男的
age int ( 3 ) unsigned not null default 28 ,
hire_date date not null,
post varchar( 50 ),
post_comment varchar( 100 ),
salary double( 15 , 2 ),
office int , #一個部門一個屋子
depart_id int
);
 
 
#查看錶結構
mysql> desc employee;
+ - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - +
| Field        | Type                  | Null | Key | Default | Extra          |
+ - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - +
| id           | int ( 11 )               | NO   | PRI | NULL    | auto_increment |
| name         | varchar( 20 )           | NO   |     | NULL    |                |
| sex          | enum( 'male' , 'female' ) | NO   |     | male    |                |
| age          | int ( 3 ) unsigned       | NO   |     | 28      |                |
| hire_date    | date                  | NO   |     | NULL    |                |
| post         | varchar( 50 )           | YES  |     | NULL    |                |
| post_comment | varchar( 100 )          | YES  |     | NULL    |                |
| salary       | double( 15 , 2 )          | YES  |     | NULL    |                |
| office       | int ( 11 )               | YES  |     | NULL    |                |
| depart_id    | int ( 11 )               | YES  |     | NULL    |                |
+ - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - +
 
#插入記錄
#三個部門:教學,銷售,運營
insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values
( 'egon' , 'male' , 18 , '20170301' , '老男孩駐沙河辦事處外交大使' , 7300.33 , 401 , 1 ), #如下是教學部
( 'alex' , 'male' , 78 , '20150302' , 'teacher' , 1000000.31 , 401 , 1 ),
( 'wupeiqi' , 'male' , 81 , '20130305' , 'teacher' , 8300 , 401 , 1 ),
( 'yuanhao' , 'male' , 73 , '20140701' , 'teacher' , 3500 , 401 , 1 ),
( 'liwenzhou' , 'male' , 28 , '20121101' , 'teacher' , 2100 , 401 , 1 ),
( 'jingliyang' , 'female' , 18 , '20110211' , 'teacher' , 9000 , 401 , 1 ),
( 'jinxin' , 'male' , 18 , '19000301' , 'teacher' , 30000 , 401 , 1 ),
( '成龍' , 'male' , 48 , '20101111' , 'teacher' , 10000 , 401 , 1 ),
 
( '歪歪' , 'female' , 48 , '20150311' , 'sale' , 3000.13 , 402 , 2 ), #如下是銷售部門
( '丫丫' , 'female' , 38 , '20101101' , 'sale' , 2000.35 , 402 , 2 ),
( '丁丁' , 'female' , 18 , '20110312' , 'sale' , 1000.37 , 402 , 2 ),
( '星星' , 'female' , 18 , '20160513' , 'sale' , 3000.29 , 402 , 2 ),
( '格格' , 'female' , 28 , '20170127' , 'sale' , 4000.33 , 402 , 2 ),
 
( '張野' , 'male' , 28 , '20160311' , 'operation' , 10000.13 , 403 , 3 ), #如下是運營部門
( '程咬金' , 'male' , 18 , '19970312' , 'operation' , 20000 , 403 , 3 ),
( '程咬銀' , 'female' , 18 , '20130311' , 'operation' , 19000 , 403 , 3 ),
( '程咬銅' , 'male' , 18 , '20150411' , 'operation' , 18000 , 403 , 3 ),
( '程咬鐵' , 'female' , 18 , '20140512' , 'operation' , 17000 , 403 , 3 )
;
 
#ps:若是在windows系統中,插入中文字符,select的結果爲空白,能夠將全部字符編碼統一設置成gbk
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#簡單查詢
     SELECT id ,name,sex,age,hire_date,post,post_comment,salary,office,depart_id
     FROM employee;
 
     SELECT * FROM employee;
 
     SELECT name,salary FROM employee;
 
#避免重複DISTINCT
     SELECT DISTINCT post FROM employee;   
 
#經過四則運算查詢
     SELECT name, salary * 12 FROM employee;
     SELECT name, salary * 12 AS Annual_salary FROM employee;
     SELECT name, salary * 12 Annual_salary FROM employee;
 
#定義顯示格式
    CONCAT() 函數用於鏈接字符串
    SELECT CONCAT( '姓名: ' ,name, '  年薪: ' , salary * 12 )  AS Annual_salary
    FROM employee;
    
    CONCAT_WS() 第一個參數爲分隔符
    SELECT CONCAT_WS( ':' ,name,salary * 12 )  AS Annual_salary
    FROM employee;
 
    結合CASE語句:
    SELECT
        (
            CASE
            WHEN NAME = 'tom' THEN
                NAME
            WHEN NAME = 'rose' THEN
                CONCAT(name, '_VIP' )
            ELSE
                concat(NAME, 'COMMON' )
            END
        ) as new_name
    FROM
        emp;

4):WHERE約束

  • where字句中可使用:
  • 1. 比較運算符:> < >= <= <> !=
  • 2. between 80 and 100 值在10到20之間
  • 3. in(80,90,100) 值是10或20或30
  • 4. like 'egon%' pattern能夠是%或_, %表示任意多字符 , _表示一個字符
  • 5. 邏輯運算符:在多個條件直接可使用邏輯運算符 and or not
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#1:單條件查詢
     SELECT name FROM employee
         WHERE post = 'sale' ;
         
#2:多條件查詢
     SELECT name,salary FROM employee
         WHERE post = 'teacher' AND salary> 10000 ;
 
#3:關鍵字BETWEEN AND
     SELECT name,salary FROM employee
         WHERE salary BETWEEN 10000 AND 20000 ;
 
     SELECT name,salary FROM employee
         WHERE salary NOT BETWEEN 10000 AND 20000 ;
     
#4:關鍵字IS NULL(判斷某個字段是否爲NULL不能用等號,須要用IS)
     SELECT name,post_comment FROM employee
         WHERE post_comment IS NULL;
 
     SELECT name,post_comment FROM employee
         WHERE post_comment IS NOT NULL;
         
     SELECT name,post_comment FROM employee
         WHERE post_comment = ' '; 注意' '是空字符串,不是null
     ps:
         執行
         update employee set post_comment = '' where id = 2 ;
         再用上條查看,就會有結果了
 
#5:關鍵字IN集合查詢
     SELECT name,salary FROM employee
         WHERE salary = 3000 OR salary = 3500 OR salary = 4000 OR salary = 9000 ;
     
     SELECT name,salary FROM employee
         WHERE salary IN ( 3000 , 3500 , 4000 , 9000 ) ;
 
     SELECT name,salary FROM employee
         WHERE salary NOT IN ( 3000 , 3500 , 4000 , 9000 ) ;
 
#6:關鍵字LIKE模糊查詢
     通配符’ %
     SELECT * FROM employee
             WHERE name LIKE 'eg%' ;
 
     通配符’_’
     SELECT * FROM employee
             WHERE name LIKE 'al__' ;

5):分組查詢:GROUP BY

  • 一、首先明確一點:分組發生在where以後,即分組是基於where以後獲得的記錄而進行的
  • 二、分組指的是:將全部記錄按照某個相同字段進行歸類,好比針對員工信息表的職位分組,或者按照性別進行分組等
  • 三、爲什麼要分組呢?取每一個部門的最高工資?取每一個部門的員工數?取男人數和女人數?
  • 小竅門:‘每’這個字後面的字段,就是咱們分組的依據
  • 四、大前提:能夠按照任意字段分組,可是分組完畢後,好比group by post,只能查看post字段,若是想查看組內信息,須要藉助於聚合函數
  • 5. 聚合函數 sum avg min max count
  • 6. GROUP BY關鍵字和GROUP_CONCAT()函數一塊兒使用
  • 7. 若是咱們用unique的字段做爲分組的依據,則每一條記錄自成一組,這種分組沒有意義
  • 8:ONLY_FULL_GROUP_BY #設置成功後,必定要退出,而後從新登陸方可生效
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#查看MySQL 5.7默認的sql_mode以下:
mysql> select @@ global .sql_mode;
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 
#!!!注意
ONLY_FULL_GROUP_BY的語義就是肯定select target list 中的全部列的值都是明確語義,簡單的說來,在ONLY_FULL_GROUP_BY模式下,target list 中的值要麼是來自於彙集函數的結果,要麼是來自於group by list 中的表達式的值。
 
 
#設置sql_mole以下操做(咱們能夠去掉ONLY_FULL_GROUP_BY模式):
mysql> set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
查詢崗位名以及崗位包含的全部員工名字
select post,group_concat(name) from employee group by post;
 
查詢崗位名以及各崗位內包含的員工個數
select post,count( id ) from employee group by post;
 
查詢公司內男員工和女員工的個數
select sex,count( id ) from employee group by sex;
 
查詢崗位名以及各崗位的平均薪資
select post,avg(salary) from employee group by post;
 
查詢崗位名以及各崗位的最高薪資
select post, max (salary) from employee group by post;
 
查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資
select sex,avg(salary) from employee group by sex;

6):HAVING過濾

  • 一、!!!執行優先級從高到低:where > group by > having
  • 二、Where 發生在分組group by以前,於是Where中能夠有任意字段,可是絕對不能使用聚合函數。
  • 三、Having發生在分組group by以後,於是Having中可使用分組的字段,沒法直接取到其餘字段,可使用聚合函數
?
1
2
3
4
5
6
7
8
查詢各崗位內包含的員工個數小於 2 的崗位名、崗位內包含員工名字、個數
select post,group_concat(name),count( id ) from employee group by post having count( id ) < 2 ;
 
查詢各崗位平均薪資大於 10000 的崗位名、平均工資
select post,avg(salary) from employee group by post having avg(salary) > 10000 ;
 
查詢各崗位平均薪資大於 10000 且小於 20000 的崗位名、平均工資
select post,avg(salary) from employee group by post having avg(salary) > 10000 and avg(salary) < 20000 ;

7):查詢排序:ORDER BY

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
按單列排序
     SELECT * FROM employee ORDER BY salary;
     SELECT * FROM employee ORDER BY salary ASC;   #升序
     SELECT * FROM employee ORDER BY salary DESC;  #降序
 
按多列排序:先按照age排序,若是年紀相同,則按照薪資排序
     SELECT * from employee
         ORDER BY age,
         salary DESC;
查詢全部員工信息,先按照age升序排序,若是age相同則按照hire_date降序排序
select * from employee ORDER BY age asc,hire_date desc;
 
查詢各崗位平均薪資大於 10000 的崗位名、平均工資,結果按平均薪資升序排列
select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) asc;
 
查詢各崗位平均薪資大於 10000 的崗位名、平均工資,結果按平均薪資降序排列
select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc;

8):限制查詢的記錄數:LIMIT

?
1
2
3
4
5
6
7
8
SELECT * FROM employee ORDER BY salary DESC
     LIMIT 3 ;                    #默認初始位置爲0
 
SELECT * FROM employee ORDER BY salary DESC
     LIMIT 0 , 5 ; #從第0開始,即先查詢出第一條,而後包含這一條在內日後查5條
 
SELECT * FROM employee ORDER BY salary DESC
     LIMIT 5 , 5 ; #從第5開始,即先查詢出第6條,而後包含這一條在內日後查5條

9):使用正則表達式查詢

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT * FROM employee WHERE name REGEXP '^ale' ;
 
SELECT * FROM employee WHERE name REGEXP 'on$' ;
 
SELECT * FROM employee WHERE name REGEXP 'm{2}' ;
 
 
小結:對字符串匹配的方式
WHERE name = 'egon' ;
WHERE name LIKE 'yua%' ;
WHERE name REGEXP 'on$' ;
 
查看全部員工中名字是jin開頭,n或者g結果的員工信息
select * from employee where name regexp '^jin.*[gn]$' ;

10):練習

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
查詢每一個部門最新入職的那位員工
#鏈表方式:
SELECT
     *
FROM
     employee AS t1
INNER JOIN (
     SELECT
         post,
         max (hire_date) max_date
     FROM
         employee
     GROUP BY
         post
) AS t2 ON t1.post = t2.post
WHERE
     t1.hire_date = t2.max_date;

②多表

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#建表
create table department(
id int ,
name varchar( 20 )
);
 
create table employee(
id int primary key auto_increment,
name varchar( 20 ),
sex enum( 'male' , 'female' ) not null default 'male' ,
age int ,
dep_id int
);
 
#插入數據
insert into department values
( 200 , '技術' ),
( 201 , '人力資源' ),
( 202 , '銷售' ),
( 203 , '運營' );
 
insert into employee(name,sex,age,dep_id) values
( 'egon' , 'male' , 18 , 200 ),
( 'alex' , 'female' , 48 , 201 ),
( 'wupeiqi' , 'male' , 38 , 201 ),
( 'yuanhao' , 'female' , 28 , 202 ),
( 'liwenzhou' , 'male' , 18 , 200 ),
( 'jingliyang' , 'female' , 18 , 204 )
;
 
 
#查看錶結構和數據
mysql> desc department;
 
mysql> desc employee;
 
mysql> select * from department;
 
mysql> select * from employee;

1):多表鏈接查詢

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#重點:
 
SELECT 字段列表
     FROM 表 1 INNER|LEFT|RIGHT JOIN 表 2
     ON 表 1. 字段 = 2. 字段;
#示例1:之內鏈接的方式查詢employee和department表,而且employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門
select employee.name,department.name from employee inner join department
     on employee.dep_id = department. id
     where age > 25 ;
 
#示例2:
select employee. id ,employee.name,employee.age,department.name from employee,department
     where employee.dep_id = department. id
     and age > 25
     order by age asc;

2):交叉鏈接

  • 不適用任何匹配條件。生成笛卡爾積
  • select * from employee,department;

3):內鏈接只鏈接匹配的行inner join

  • 找兩張表共有的部分,至關於利用條件從笛卡爾積結果中篩選出了正確的結果
  • select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id; #推薦這樣寫
  • select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id;#效果同樣

4):外連接之左鏈接:優先顯示左表所有記錄left join

  • 以左表爲準
  • 本質就是:在內鏈接的基礎上增長左邊有右邊沒有的結果
  • select employee.id,employee.name,department.name as depart_name from employee left join department on employee.dep_id=department.id;

5):外連接之右鏈接:優先顯示右表所有記錄right join

  • 以右表爲準
  • 本質就是:在內鏈接的基礎上增長右邊有左邊沒有的結果
  • select employee.id,employee.name,department.name as depart_name from employee right join department on employee.dep_id=department.id;

6):全外鏈接:顯示左右兩個表所有記錄

  • 全外鏈接:在內鏈接的基礎上增長左邊有右邊沒有的和右邊有左邊沒有的結果
  • 注意:mysql不支持全外鏈接 full JOIN
  • 強調:mysql可使用此種方式間接實現全外鏈接
  • select * from employee left join department on employee.dep_id = department.id union select * from employee right join department on employee.dep_id = department.id;
  • #注意 union與union all的區別:union會去掉相同的紀錄

7):子查詢

  • 1:子查詢是將一個查詢語句嵌套在另外一個查詢語句中。
  • 2:內層查詢語句的查詢結果,能夠爲外層查詢語句提供查詢條件。
  • 3:子查詢中能夠包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
  • 4:還能夠包含比較運算符:= 、 !=、> 、< 等
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#查詢平均年齡在25歲以上的部門名
select id ,name from department
     where id in
         (select dep_id from employee group by dep_id having avg(age) > 25 );
 
#查看技術部員工姓名
select name from employee
     where dep_id in
         (select id from department where name = '技術' );
 
#查看不足1人的部門名(子查詢獲得的是有人的部門id)
select name from department where id not in (select distinct dep_id from employee);
#比較運算符:=、!=、>、>=、<、<=、<>
#查詢大於全部人平均年齡的員工名與年齡
select name,age from emp where age > (select avg(age) from emp);
#查詢大於部門內平均年齡的員工名、年齡
select t1.name,t1.age from emp t1
inner join
(select dep_id,avg(age) avg_age from emp group by dep_id) t2
on t1.dep_id = t2.dep_id
where t1.age > t2.avg_age;
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
8 ):補充EXISTS
 
EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。 而是返回一個真假值。 True False 當返回 True 時,外層查詢語句將進行查詢;當返回值爲 False 時,外層查詢語句不進行查詢
 
#department表中存在dept_id=203,Ture
mysql> select * from employee
     - >     where exists
     - >         (select id from department where id = 200 );
 
#department表中存在dept_id=205,False
mysql> select * from employee
     - >     where exists
     - >         (select id from department where id = 204 );
Empty set ( 0.00 sec)

2、權限管理

一、受權表;

  • user 針對:全部數據,全部庫下全部表,以及表下的全部字段
  • db 針對:某一數據庫,該數據庫下的全部表,以及表下的全部字段
  • tables_priv 針對:某一張表,以及該表下的全部字段
  • columns_priv 針對:某一個字段

二、受權(對庫,對錶,對字段);

  • 查看幫助:help grant
  • 經常使用權限有:select,update,alter,delete
  • all能夠表明除了grant以外的全部權限
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
grant select,insert,update on db1. * to 'tom' @ '%' ;
grant select,insert,update on db1.t1 to 'tom' @ '%' ;
grant all privileges on db1.t1 to 'tom' @ '%' ;
 
#針對全部庫的受權:*.*
grant select on * . * to 'tom' @ 'localhost' identified by '123' ; #只在user表中能夠查到tom用戶的select權限被設置爲Y
#針對某一數據庫:db1.*
grant select on db1. * to 'tom' @ '%' identified by '123' ; #只在db表中能夠查到tom用戶的select權限被設置爲Y
#針對某一個表:db1.t1
grant select on db1.t1 to 'tom' @ '%' identified by '123' #只在tables_priv表中能夠查到tom用戶的select權限
#針對某一個字段:
grant select ( id ,name),update (age) on db1.t3 to 'tom' @ 'localhost' identified by '123' ;
 
#能夠在tables_priv和columns_priv中看到相應的權限
select * from tables_priv where user = 'tom' \G
select * from columns_priv where user = 'tom' \G
#查看權限
show grants for 'tom' @ '%' ;
 
#刪除權限
revoke all privileges on db1.t1 from 'tom' @ '%' ;
revoke select on db1. * from 'tom' @ '%' ;         
相關文章
相關標籤/搜索