mysql数据库——思维导图
學完mysql后,自己弄得的思維導圖。原圖30.6MB,太大了放不上來,這里就放個鏈接吧。
歡迎大家去看,如果有需要改正的地方,請告訴我,謝謝。
鏈接:https://www.zhixi.com/view/718f3805
密碼:6522
下面是MarkDown形式的的內容,但是缺少一些圖片。完整的在思維導圖上。
mysql數據庫
使用DOS命令行窗口連接MySQL數據庫
連接到mysql數據服務(mysql數據庫)的指令:
mysql -h 主機IP -P 端口名 -u 用戶名 -p密碼
【注意事項】:
1、-p密碼 之間不要有空格。
2、-p后面如果沒有寫密碼,回車之后會要求輸入密碼。
3、如果沒有寫 -h 主機,則默認就是本機。
4、如果沒有寫 -P 端口名,則默認就是3306。
5、在實際工作中,為保證安全,一般會將3306改為其他端口號。
啟動數據庫 的常用方式
net start mysql服務名
net stop mysql服務名
安裝圖形化MySQL管理軟件
Navicat
SQLyog
數據庫的三層結構
1、所謂的安裝mysql數據庫,就是在主機安裝一個“數據庫管理系統(DBMS)”,這個管理程序可以管理多個數據庫。
DBMS(Database manage system)
2、一個數據庫可以創建多個表,以保存數據(信息)
3、數據庫管理系統,數據庫 和 表的關系。如上圖所示
4、mysql數據庫 – 普通表的本質仍然是文件。表的一行(row)稱之為一條記錄,在 Java 程序中,一行記錄往往使用“對象”來表示。
SQL語句的分類
DDL:數據定義語句【create 表,庫…】
DML:數據操作語句【增加 insert,修改 update,刪除 delete】
DQL:數據查詢語句【select】
DCL:數據控制語句【管理數據庫:例如用戶權限(grant,revoke)】
對數據庫的增、刪、查
創建數據庫
create datebase [if not exists] 數據庫名 [default] character set 字符集名 [default] collate 校對規則名;
顯示數據庫語句
show databases;
顯示數據庫創建(定義信息)語句
show create database 數據庫名;
刪除數據庫
drop database [if exists] 數據庫名;
備份恢復數據庫
備份數據庫(在DOS命令行)
mysqldump -u 用戶名 -p -B 數據庫1 數據庫2 數據庫n > 文件名.sql
恢復數據庫(進入mysql命令行,然后執行)
source 文件名.sql
例如:source d:\bak.sql ;
直接將 bak.sql 的內容放到查詢編輯器中,執行。
備份恢復數據庫的“表”
備份庫的表
mysqldump -u 用戶名 -p密碼 數據庫1 表1 表2 表n > d:\文件名.sql
創建表
field: 指定列名
datatype: 指定列類型(字段類型)
character set: 如果不指定,則為所在數據庫的字符集
collate: 如果不指定,則為所在數據庫的校對規則
engine: 存儲引擎
mysql表類型 和 存儲引擎
基本介紹
- 1、mysql的表類型由存儲引擎(storage engines)決定,主要包括:MyISAM、innodb、Memory 等。
2、MySQL數據表主要支持 6種類型,分別是:CSV、Memory、ARCHIVE、MGR MYISAM、MYISAM、InnoDB。
3、這六種又分為2類:一類是“事務安全型”(transaction-safe),比如:innodb ;
其余都屬于第二類,稱為“非事務安全”型(non-transaction-safe)【myisam 和 memory】
主要的 存儲引擎/表 類型特點
細節說明
- 1、MyISAM不支持事務,也不支持外鍵,但是其訪問速度快,對事物的完整性沒有要求。
2、InnoDB存儲引擎提供了具有 提交、回滾和崩潰恢復能力的事務安全。但是比起MyISAM存儲引擎,InnoDB寫的處理效率差一些,并且會占用更多的磁盤空間,以保留數據和索引。
3、Memory存儲引擎使用“存在內存中的內容”來創建表。每個Memory 表只實際對應一個磁盤文件。Memory類型訪問非常得快,因為它的數據是存儲在內存中的,并且還使用Hash索引。但是一旦 MySQL服務關閉,表中的數據就會丟失掉,但是“表的結構”還在。
如何使用MyISAM、InnoDB、Memory三種存儲引擎 ?
-
– 查看所有的存儲引擎
SHOW ENGINES; -
– innodb存儲引擎是前面使用過的。
/* 1、支持事務;2、支持外鍵;3、支持行級鎖 */
如何選擇表的存儲引擎
- 1、如果你的應用不需要事務,處理的只是基本的CRUD操作,那么MylSAM
是不二選擇,速度快
2、如果需要支持事務,選擇lnnoDB。
3.、Memory存儲引擎就是將數據存儲在內存中,由于沒有磁盤I./O的等待,
速度極快。但由于是內存存儲引擎,所做的任何修改在服務器重啟后都將消失。(經典用法:用戶的在線狀態)
修改存儲引擎
- ALTER TABLE 表名 ENGINE = 存儲引擎 ;
約束
primary key(主鍵)
用于唯一的標示表行的數據,當定義主鍵約束后,該列不能重復
【細節說明】:
1、primary key 不能重復,而且不能為null。
2、一張表最多只能有一個主鍵,但可以是復合主鍵。
3、主鍵的指定方式有兩種
(1)在創建表時,直接在字段名后指定:字段名 字段類型 primary key
(2)在表定義的最后一行填寫,此時還在()內部:primary key(列名),
4、使用 desc 表名 可以看到 primary key 的情況。
5、在實際開發中,每個表往往都會設計一個主鍵。
【舉例】
CREATE TABLE t17(
id INT PRIMARY KEY, – 表示 id 列是主鍵
name VARCHAR(32),
email VARCHAR(32)
);
復合主鍵
-
一張表最多 只能有一個主鍵,但是可以是復合主鍵(那也只能有1個)。
CREATE TABLE t18(
id INT PRIMARY KEY,
name VARCHAR(32) PRIMARY KEY,-- 錯誤
email VARCHAR(32)
); -
/* 演示復合主鍵的使用(id和name做成復合主鍵) */
CREATE TABLE t18(
id INT,
name VARCHAR(32),
email VARCHAR(32),
PRIMARY KEY (id,name) – 這里就是復合主鍵,以后添加數據時,只有id和name同時發生重復時,才會報錯。
);
not null(非空)
如果在列上定義了not null,那么插入數據時,必須為列提供數據。
字段名 字段類型 not null
自增長
基本介紹
- 在某張表中,存在一個id列(整數),我們希望在添加記錄的時候,該列從 1 開始,自動增長。
使用細節
- 1、一般來說,自增長和 primary key 配合使用。
2、自增長也可以單獨使用(但是需要配合一個 unique)
3、自增長修飾的字段為整數型的。(雖然小數也可以但是很少這樣使用)
4、自增長默認從1開始,也可以通過下列命令來修改
alter table 表名 auto_increment = 新的開始值 ;
5、如果添加數據時,給自增長字段(列)指定的有值,則以指定的值為準。如果指定了自增長,就按照自增長的規則來添加數據。
添加 自增長的的字段方式
- (1)insert into xxx(字段1,字段2,…) values(null,‘值’,…) ;
– null對應字段1,如果字段1是自增長的,那么添加之后就是1,之后2,3。
- (2)insert into xxx(字段2,…) values(‘值1’,‘值2’,…) ;
– 直接從字段2開始寫,值1對應字段2,…不給字段1賦值,它會自己從1開始增長。
- (3)insert into xxx values(null, ‘值1’,…)
– 前面直接什么都不寫,然后把所有數據的值都寫清楚,它會自動的添加。
舉例
-
創建表
-
測試自增長的使用
- INSERT INTO t24
VALUES(NULL, ‘tom@qq.com’,‘tom’);
- INSERT INTO t24
這里的null給的是id,因為id是自增長的,所以雖然寫的是null,但是實際上給的是1。再執行一次,給tom分配的id為2。
* 執行一次,給hsp分配的id為3INSERT INTO t24
(email,name) VALUES(‘hsp@123.com’,‘hsp’);
-
修改默認的自增長開始值
unique(唯一)
在定義了唯一約束后,該列的值是不能重復的。
字段名 字段類型 unique
【細節】:
1、如果沒有指定 not null,則unique字段可以有多個 null。
2、一張表可以有多個 unique字段。
3、unique not null 使用效果類似 primary key
foreign key(外鍵)
用于定義 主表 和 從表 之間的關系:
1、外鍵約束要定義在“從表”上,“主表”則必須要有“主鍵約束”或者“unique”約束。這樣形成的外鍵約束關系才是唯一的。
2、當定義外鍵約束后,要求外鍵列數據必須在主表的主鍵列存在或是為null。
【舉例】學生表(從表,即:外鍵所在的表) 班級表(主表)
id, name, class_id id, class_name1、學生表的class_id為300的,在班級表中并不存在,所以就會添加失敗,這叫外鍵約束.
2、如果學生表的jack和班級表已建立聯系再刪除班級表的id就會失敗,得先刪除學生表的jack才行,也叫外鍵約束
【基本語法】
foreign key(本表字段名) references 主表名(主鍵名或者unique字段名)
【細節說明】
1、外鍵指向的主表的字段,必須是primary key 或者 unique;
2、表的類型(存儲引擎)是“innodb”,這樣的表才支持外鍵
3、外鍵字段的類型和關聯的主鍵字段的類型要一致,長度可以不一樣。
4、外鍵字段的值,必須在主鍵字段中出現過,或者為“null”【前提是:外鍵字段允許為null】
5、一旦建立了 主鍵、外鍵的關系,數據就不能隨意刪除了。
6、刪除主表的記錄能否成功,要看是否有從表的外鍵指向它。如果有,則把從表中的相關記錄全部刪掉,然后再刪主表的記錄
check
check:用于強制行數據必須滿足的條件。
假定在sal列上,定義了check約束,并要求sal列的值在1000~2000之間。如果不在這個范圍內就會報錯。 【老韓提示】oracle和sql server均支持check,但是MySQL5.7 目前還不支持check,只做語法校驗,但不會生效。即:語法上支持,但運行不會生效, 如果不滿足check的條件,語句也會執行。【基本語法】:列名 類型 check (check的條件)
【舉例】
CREATE TABLE t23(
id INT PRIMARY KEY,
name VARCHAR(32),
sex VARCHAR(6) CHECK (sex IN (‘man’,‘woman’)),
sal DOUBLE CHECK (sal>1000 AND sal<2000)
);
mysql常用的的“數據類型”(列類型)
數值型(整數)的基本使用
使用規范:在滿足需求的情況下,盡量選擇占用空間小的。
#1. 如果沒有指定 unsinged , 則 Ttinyint 就是有符號
#2. 如果指定 unsinged , 則 tinyint 就是無符號 0-255
【舉例】
create table t01(id tinyint); # 有符號的
create table t01(id tinyint unsigned); # 無符號的
數值型(bit)的基本使用
【說明】
1、bit(m) m在1~64。8是一個字節,64是8個字節。
2、添加數據 范圍按照你給的位數來確定。8位一個字節來控制,比如m=8,表示一個字節0~255
3、顯示按照bit位的方式來顯示。【0是0,1是1,2是10,3是11,255是1111 1111】
4、查詢時仍然可以按照 數 來查詢。
【舉例】
CREATE TABLE t05 (num BIT(8));
INSERT INTO t05 VALUES(2);
數值型(小數)的基本使用
float/double [unsigned]
float–單精度,double–雙精度
decimal[M,D] [unsigned]
(1)可以支持更加精確地小數位。M是小數位數(精度)的總數,D是小數點(標度)后面的位數。
如:decimal(5,3):一共是5位數,其中小數有3位。(2)如果D是0,則值沒有小數點或分數部分。M最大是65,D最大是30。
【如果D被省略,默認是0;M被省略,默認是10】
(3)【建議】如果希望小數的精度高,推薦使用decimal。
字符串 的基本使用
char(size) 固定長度字符串,最大255字符
varchar(size) 0~65535字節 :可變長度字符串,最大65532字節【utf8編碼最大21844字符,1-3個字節用于記錄大小】
【utf8編碼最大21844字符,每個漢字3個字節,所以65532/3 = 21844】
【gbk編碼,每個漢字2個字節,65532/2 = 32766個 字符】
【使用細節】
細節一
char(4) // 這個4表示字符數(最大255),不是字節數,不管是中文還是英文字母都是放4個,按字符計算。
varchar(4) //這個4表示字符數,不管是中文還是字母都是以定好的表的編碼來存放數據。不管是中文還是英文,都最多存放4個,是按照字符來存放的。
細節二
char(4) 是定長(固定大小),就是說:即使插入的是‘aa’,也會占用分配的4個字符的空間。
varchar(4) 是變長(變化的大小),就是說,即使插入了‘aa’,實際占用空間大小并不是4個字符,而是按照實際占用空間來分配。
- varchar本身還需要1-3個字符來記錄存放內容的長度。L (實際數據大小) +(1-3)字節
細節三
什么時候用char?什么時候用varchar?
-
如果數據是定長,推薦使用char。比如:md5的密碼,郵編,手機號,身份證號等。
-
如果一個字段的長度不確定,我們使用varchar,比如:留言,文章
-
查詢速度:char > varchar
細節四
存放文本時,可以使用text數據類型。可以將 TEXT列 視為 VARCHAR列。
注意text不能有默認值,大小0~2^16字節。
如果希望存放更多的字符,可以選擇 mediumtext 0~2^24
或者 longtext 0~2^32
日期類型 的基本使用
需要在 timestamp數據類型后添加的代碼為:
NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
刪除表
drop table 表名 ;
修改表
基本介紹
使用 alter table 語句追加,修改或刪除列的語法
添加列
alter table 表名
add (column datatype [dafault expr]
[, column datatype]…
);
【舉例】
(1)員工表 emp 的上增加一個 image 列,varchar 類型(要求在 resume 后面)
ALTER TABLE emp
ADD image VARCHAR(50) NOT NULL DEFAULT ‘’
AFTER resume ;
刪除列
alter table 表名 drop (column) ;
修改列
alter table 表名
modify (column datatype [dafault expr]
[, column datatype]…
);
查看表的結構
desc 表名 ;
修改表名
rename table 表名 to 新表名
修改表的字符集
alter table 表名 character set 字符集 ;
修改列名
【舉例】修改列名name為user_name
ALTER TABLE employee
CHANGE name user_name VARCHAR(32) NOT NULL DEFAULT ‘’ ;
刪除列
alter table 表名 drop 列名 ;
數據庫的CRUD語句
C[create]
R[read]
U[update]
D[delete]
insert語句
基本語法
insert into 表名 [(列名 [, 列名, …])]
values (value [, value, ...]) ;使用細節
1、插入的數據應與字段的數據類型相同。
2、數據的長度要在列的規定范圍內。
3、在values中列出的數據位置,必須與被加入的列的排列位置對應。
4、字符和日期型數據應該包含在單引號中。
5、列可以插入空值(前提是該字段允許為空) insert into table value(null)
6、insert into 表名(列名…) value(), (), () 的形式添加多條記錄。
7、如果是給表中的所有字段添加數據,可以不寫前面的字段名稱。
8、默認值的使用:
(1)當不給某個字段值時,如果有默認值就添加默認值,否則就報錯。
(2)如果某個列沒有指定 not null,那么當添加數據時,沒有給定值,則默認會給null。
(3)如果我們希望指定某個列的默認值,可以在創建表時指定。
舉例
INSERT INTO goods (id, goods_name, price)
VALUES(50, ‘三星手機’, 2300),(60, ‘海爾手機’, 1800);
INSERT INTO goods VALUES(70, ‘IBM 手機’, 5000);
CREATE TABLE dept( /部門表/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, dname VARCHAR(20) NOT NULL DEFAULT '', loc VARCHAR(13) NOT NULL DEFAULT "");
update語句
使用update語句修改表中的數據
基本語法
update 表名
set 列名2 = 新的值 [,列名2 = 新的值 , ...][where 條件語句] ;使用細節
1、update語法可以用新值更新原有表行中的各列。
2、set子句指示要修改哪些,要給予哪些值。
3、where子句指定 應該更新哪些行。如果沒有where子句,則更新所有的行(記錄),所以一定要小心。
4、如果需要修改多個字段,可以通過 set 字段1 = 值1, 字段2 = 值2 …
5、在set子句中,不存在 += 或 -= 之類的情況。老老實實的用 num = num +1 這樣的語句形式。
delete語句
使用delete語句刪除表中的數據(按行)
基本語法:
delete from 表名
[where 條件語句] ;刪除表中的所有記錄
delete from 表名 ;
使用細節:
1、如果不使用 where子句,將會刪除表中的所有數據。
2、delete語句不能夠刪除某一列的值。(可以使用update 設為 null 或者 ‘’)
3、使用delete語句僅能夠刪除表中的記錄,不刪除表本身。如要刪除表,使用drop語句。 drop table 表名 ;
查詢表select
單表查詢
基本語法
select [distinct] * | {列名1, 列名2, …}
from 表名 ;注意事項
1、select 指定查詢哪些列的數據。
2、select * 表示查詢所有的列
select emp.* 表示查詢emp表的所有列。
3、from 指定查詢哪張表。
4、distinct 可選,指顯示結果時,是否去掉重復數據。
使用表達式,對查詢的列進行運算
語法:
select * | {列名1 | 表達式1, 列名2 | 表達式2… }
from 表名 ;
【舉例】
SELECT name,(chinese + english + math + 10) FROM student;
在select語句中使用 as 語句給列名起一個別名
語法:
select 列名 as 別名 from 表名 ;
【舉例】
SELECT name AS ‘姓名’, (chinese + english + math + 10) AS total_score FROM student;
在where子句中經常使用的運算符
between … and … 是閉區間
使用where子句,進行過濾查詢
使用 order by 子句排序查詢結果
基本語法
select 列名1, 列名2, 列名3…
from 表名order by 列名 asc | desc使用細節
1、order by 指定排序的列,排序的列既可以是表中的列名,也可以是select語句后指定的列名。
2、asc – 升序
desc -- 降序3、order by 子句應該位于select 語句的結尾。
加強查詢
在 mysql 中,日期類型可以直接比較, 需要注意格式
SELECT * FROM emp
WHERE hiredate > ‘1992-01-01’ ;
like操作符
% 表示 0~多個任意字符
_ 表示單個任意字符
如何顯示第三個字符為大寫 O 的所有員工的姓名和工資 ?
SELECT ename, sal FROM emp
WHERE ename LIKE ‘__O%’ ;
order by 子句(多個排序條件)
按照部門號升序而雇員的工資降序排列 , 顯示雇員信息
SELECT * FROM emp
ORDER BY deptno ASC , sal DESC ;
分頁查詢
基本語法:
select … limit start, rows
表示 從 start+1 行開始取,取出 rows行,start從 0 開始計算
推導公式
select * from 表名
order by 列名
limit 每頁顯示記錄數 * (第幾頁-1), 每頁顯示記錄數
使用分組函數和分組語句 group by
SELECT COUNT(*),COUNT(IF(comm IS NULL,1,NULL)) ;
如果comm列為空,如果是空的就返回1,如果不為空就返回null。
FROM emp;顯示管理者的總人數
SELECT COUNT(*) FROM emp WHERE job = ‘MANAGER’;
或者
SELECT COUNT(DISTINCT mgr ) FROM emp; #distinct —— 去重
數據分組的總結
如果select語句中同時含有group by,having,limit,order by。那么它們的順序是:group by,having,order by,limit。
/*
select 列名1,列名2,列名3,… from 表名
group by 列名
having 條件
order by 列名
limit start,rows ;
如果順序寫錯,語法不會通過。
*/
【應用案例】
請統計各部門的平均工資,并且是大于1000的,而且按照平均工資從高到低排序,取出前兩行記錄。
SELECT deptno,AVG(sal) AS ‘平均工資’
FROM emp
GROUP BY deptno
HAVING 平均工資>1000
ORDER BY 平均工資 DESC # 【分組 --> 過濾 --> 排序】
LIMIT 0,2;
多表查詢
多表查詢指的是:基于2張或者2張以上的表進行的查詢
當我們需要指定顯示某個表的列是,需要 表.列表
舉例
SELECT ename,sal,dname,emp.deptno FROM emp,dept #ok
WHERE emp.deptno = dept.deptno;– ?如何顯示部門號為10的部門名、員工名和工資
SELECT dname,ename,sal,emp.deptno
FROM emp,dept
WHERE emp.deptno = dept.deptno AND emp.deptno = 10 ;
注意事項
在默認情況下:當兩個表進行查詢時,規則:
1、從第一張表中,取出1行和第二張表的每一行進行組合,返回多個結果。【含有兩張表的所有列,全部都包含在里面】
2、一共返回的記錄數:第一張表的行數第二張表的行數。【134=52】
3、這樣的多表查詢默認處理的返回結果,稱為“笛卡爾集”。
4、解決多表的關鍵:在where中 寫出正確的過濾條件。這需要程序員進行正確的分析。
– 老韓小技巧:多表查詢的條件不能少于表的個數-1,否則會出現笛卡爾集
自連接
定義
在同一張表的連接查詢【將同一張表看作兩張表】
特點
1、把同一張表當做兩張表使用
2、需要給表取別名 表名 表別名
3、列名不明確,可以指定列的別名 列名 as 列的別名
舉例
SELECT worker.ename AS ‘職員名’ , boss.ename AS ‘上級名’
FROM emp worker, emp boss
WHERE worker.mgr
注意事項
給表取別名,那么這個別名可以在查詢語句的 select 部分中使用,但是也只能在這個查詢語句中使用!
子查詢
定義
嵌入在其他sql語句中的select語句,也叫“嵌套查詢”
單行子查詢
只返回一行數據的子查詢語句
【舉例】
【Question】如何顯示與smith同一部門的員工?
1、先查詢smith在哪個部門,部門號是什么?
SELECT deptno
FROM emp
WHERE ename=‘SMITH’;
2、把上面的select語句當做一個子查詢使用。
SELECT * FROM EMP
WHERE DEPTNO=(
SELECT deptno
FROM emp
WHERE ename=‘SMITH’
);
多行子查詢
返回多行的子查詢語句,使用關鍵字in
【舉例】
如何查詢和部門 10 的工作相同的雇員的 名字、崗位、工資、部門號, 但是不含 10 號部門自己的雇員。
1、查詢到10號部門有哪些工作SELECT DISTINCT job
FROM emp
WHERE deptno = 10
SELECT ename, job, sal, deptno
FROM emp
WHERE job IN ( # 多行子查詢要使用in
SELECT DISTINCT job
FROM emp WHERE deptno = 10
) AND deptno <> 10;
子查詢當做臨時表使用
把子查詢的語句用括號括起來,放在from 子句中,并在括號后面 對臨時表取別名tmp
- 【舉例】
查詢每個部門的信息(包括:部門名,編號,地址)和人員數量
SELECT tmp.* , dname, loc
FROM dept, (
SELECT COUNT(*) AS per_num, deptno
FROM emp
GROUP BY deptno
) tmp
WHERE tmp.deptno = dept.deptno ;
在多行子查詢中使用 all / any
all
- – 請思考:顯示工資比部門30的所有員工的工資高的員工的姓名、工資和部門號。
SELECT ename,sal,deptno
FROM emp
WHERE sal>ALL(
SELECT sal
FROM emp
WHERE deptno = 30
);
any
- – 請思考:顯示工資比部門30的其中一個(任意一個)員工的工資高的員工的姓名、工資和部門號。
在多行查詢中使用any操作符
SELECT ename,sal,deptno
FROM emp
WHERE sal>ANY(
SELECT sal
FROM emp
WHERE deptno = 30
);
多列子查詢
指的是:返回多個列的子查詢語句
基本語法
(字段1,字段2…) = (select 字段1,字段2 from…) ;
字段1與字段1匹配,字段2與字段2匹配。
舉例
【問題】查詢與allen的部門、崗位完全相同的所有雇員(并且不含smith本人)。
– 分析:1、得到allen的部門、崗位
SELECT deptno, job
FROM emp WHERE ename = ‘ALLEN’;
– 2、把上面的查詢當做子查詢使用,并且使用多列子查詢的語法來進行匹配
SELECT * FROM emp
WHERE (deptno,job) = (
SELECT deptno, job
FROM emp WHERE ename = ‘ALLEN’
)AND ename <> ‘ALLEN’;
表的自我復制(蠕蟲復制)
目的:為了對某個 sql 語句進行效率測試,我們需要海量數據時,可以使用此法為表創建海量數據。
復制步驟
1、先把emp表的記錄復制(遷移)到 my_tab01
【先查找數據,然后把查找的數據 列對列 的放入新的表中】
INSERT INTO my_tab01
(id, name, sal, job, deptno)
SELECT empno, ename, sal, job, deptno FROM emp;
2、自我復制
INSERT INTO my_tab01
SELECT * FROM my_tab01;【提問】如何刪除掉一張表中的重復記錄?
1、先創建一張臨時表 my_temp, 該表的結構和my_tab02一樣。
CREATE TABLE my_temp LIKE my_tab02;
這個語句把my_tab02表的結構(列)等信息,不包含數據,復制到my_temp
2、把my_temp 的記錄,通過distinct 關鍵字處理后,把記錄復制到my_temp。
INSERT INTO my_temp SELECT DISTINCT * FROM my_tab02;
DISTINCT去重
3、清除掉 my_tab02 的所有記錄。(不是刪掉 表my_tab02 本身)
DELETE FROM my_tab02;
4、把my_temp表的記錄復制到my_tab02。【可以把my_tab02刪掉drop后,再把my_temp表改名為my_tab02】
– 改表名:rename old_name to new_name;
INSERT INTO my_tab02 SELECT * FROM my_temp;
5、drop掉 臨時表my_temp。
DROP TABLE my_temp;
合并查詢
目的
有時在實際應用中,為了合并多個select語句的結果,可以使用 集合操作符號 union,union all。
union all
– union all 就是將查詢結果合并 (取并集),不會去重
SELECT ename,sal,job FROM emp WHERE sal>2500
UNION ALL
SELECT ename,sal,job FROM emp WHERE job=‘MANAGER’; – 8條記錄
union
– union 該操作與union all相似,但是會“自動去掉”結果集合中的“重復行”。
SELECT ename,sal,job FROM emp WHERE sal>2500
UNION
SELECT ename,sal,job FROM emp WHERE job=‘MANAGER’; – 6條記錄
表外鏈接
左外連接
如果左側的表完全顯示,我們就說是“左外連接”。即使左邊的表和右邊的表如果沒有匹配的,那他也會把左邊的表全部顯示出來
基本語法
select … from 表1(左表) left join 表2(右表) on 條件;
右外連接
如果右側的表完全顯示,我們就說是“右外連接”
基本語法
select … from 表1(左表) right join 表2(右表) on 條件;
函數
合并/統計函數
count
返回行的總數
基本語法
select count(*) | count(列名)
from 表名
[where 條件語句] ;
count(*) 和 count(列) 的區別
count(*) – 返回滿足條件的記錄的行數。
count(列) – 統計滿足條件的某列有多少個,但是會排除 為null的情況。
sum
基本語法
select sum(列名1) [, sum(列名2) ]
from 表名
[where 條件語句] ;
注意事項
1、sum()僅對 數值起作用。
2、對多列求和," , "號不能少。
舉例
統計一個班級語文、英語、數學的成績總和
SELECT SUM(math + english + chinese) FROM student;
avg
返回滿足where條件的一列的平均值
基本語法
select avg(列名1) [, avg(列名2) ]
from 表名
[where 條件語句] ;
max/min
max():返回滿足where條件的一列的 最大值
min():返回滿足where條件的一列的 最小值
【舉例】
求班級最高分和最低分(數值范圍在統計中特別有用)
SELECT MAX(math + english + chinese), MIN(math + english + chinese)
FROM student;
group by
對列進行分組
基本語法
select 列名1, 列名2, 列名3, …
from 表名
group by 列名 ;
having
對分組后的結果進行過濾
基本語法
select 列名1, 列名2, 列名3, …
from 表名
group by 列名 having … ;
having一般與group by 連用
其中 group by用于對查詢結果進行統計,
having 子句用于限制 分組顯示結果。
字符串相關函數
charset (str)
返回字符串str的字符集
concat (string2 [, …])
連接字符串,將多個列拼接成一列
instr (string, substring)
返回 substring在string中出現的位置,沒有的話,就返回0
ucase (string2)
轉換成大寫, 本身是大寫的,還是大寫。
lcase (string2)
轉換成小寫
left (string2, length)
從String2中的左邊起,獲取length個字符
right (string2, length)
從String2中的右邊起,獲取length個字符
length (string)
string的長度【按照字節】
SELECT LENGTH(‘韓順平’) FROM DUAL ; # 9,按照字節返回,utf8編碼一個漢字占3個字節。如果是字符的話,會返回3.
replace (str, search_str, repalce_str)
在str中用replace_str替換search_str
strcmp (string1, string2)
逐個字符比較2個字符串的大小(根據ascll碼),看這兩個string是否相等。
SELECT STRCMP(‘hanshunping’,‘hanxianchu’)FROM DUAL;返回-1,跟表本身是否區分大小寫有關。
SELECT STRCMP(‘hanshunping’,‘hanshunping’)FROM DUAL;返回0。
substring (str, position [, length])
從str的position開始【從1開始計算】,取length個字符
ltrim (string2)
去除前端空格
SELECT LTRIM(’ 韓順平教育’) FROM DUAL;
rtrim (string2)
去除后端空格
SELECT RTRIM('韓順平教育 ') FROM DUAL;
trim (string2)
把左右兩端的空格都去掉
SELECT TRIM(’ 韓順平教育! ') FROM DUAL;
數學相關函數
abs (num)
絕對值
bin (decimal_number)
十進制轉換成二進制
ceiling (number)
向上取整,得到比number2大的最小整數
conv (number2, from_base, to_base)
進制轉換 convert:轉換
SELECT CONV(8,10,2) FROM DUAL;
把數字8當做十進制來對待,讓它轉換成二進制。
floor (number2)
向下取整,得到小于number2的最大整數
format (number, decimal_places)
保留小數位數(四舍五入)
SELECT FORMAT(78.325386,2) FROM DUAL;
保留2位小數
hex (DecimalNumber)
轉十六進制
least (number, number2 [, …])
求最小值
mod (numerator, denominator)
求余數
rand ([seed])
返回一個隨機數,其范圍是0 <= v <= 1.0
加入數字seed后,返回的隨機數不再改變。每次更換seed的值,查詢結果都會改變。
如果已經產生一個整數N,則它被用作種子值,用來產生重復序列。
時間日期相關函數
current_date ()
當前日期
current_time ()
當前時間
current_timestamp ()
當前時間戳
SELECT CURRENT_TIMESTAMP() FROM DUAL;
- 返回結果:2022-06-19 20:49:24
date (datetime)
返回datetime的日期部分
date_add (date2, interval d_value d_type)
在date2上面加上日期/時間
SELECT *
FROM mes WHERE DATE_ADD(sendtime,INTERVAL 10 MINUTE) >= NOW();INTERVAL 時間間隔
date_sub (date2, interval d_value d_type)
在date2上減去一個時間
datediff (date1, date2)
兩個日期差(單位是天,而且是date1-date2)
請在mysql的sql語句中求出2011-11-11與1990-1-1相差多少天?
SELECT DATEDIFF(‘2011-11-11’,‘1990-01-01’)/365 FROM DUAL;
timediff (date1, date2)
兩個時間差(時分秒,而且是date1-date2)
SELECT TIMEDIFF(‘13:13:13’,‘10:10:10’) FROM DUAL;
now()
當前時間
SELECT NOW() FROM DUAL;
year (datetime)
返回datetime里的的年份
SELECT YEAR(NOW()) FROM DUAL;
month (datetime)
返回datetime里的的月份
SELECT MONTH(NOW()) FROM DUAL;
day (datetime)
返回datetime里的的天數
SELECT DAY(NOW()) FROM DUAL;
date(datetime)
返回datetime里的日期部分(年月日)
SELECT DATE(NOW()) FROM DUAL;
unix_timestamp()
返回的是從1970-1-1到現在的秒數,不是毫秒數。
SELECT UNIX_TIMESTAMP() FROM DUAL;
from_unixtime()
可以把一個unix_timestamp的秒數(時間戳),轉成指定格式的日期。
%Y-$m-%d 表示:年月日,這是規定好的格式。
%Y-%m-%d %H:%i:%s 表示: 年月日時分秒(默認格式)
SELECT FROM_UNIXTIME(1655028638)FROM DUAL
SELECT FROM_UNIXTIME(1655028638,‘%Y-%m-%d’)FROM DUAL
SELECT FROM_UNIXTIME(1655028638,‘%Y-%m-%d %H:%i:%s’)FROM DUAL
# 意義:在開發中,我們可以把一個數值當做一個時間來記錄,然后通過from_unixtime()方法來進行轉換。
加密和系統函數
user ()
查詢用戶
database()
數據庫名稱
MD5(str)
為字符串str算出一個MD5 32的字符串,常用來(用戶密碼)加密
root的密碼是:123456 -> md5加密 -> 在數據庫中存放的是加密后的密碼。
SELECT MD5(‘123456’) FROM DUAL;
SELECT LENGTH(MD5(‘123456’)) FROM DUAL; # 32位。
password (str)
加密函數。從原文密碼str計算并返回密碼字符串,通常用于連接對mysql數據庫的用戶密碼加密。
SELECT PASSWORD(‘sdyu’) FROM DUAL;
在MySQL數據庫的密碼就是用這個函數加密的。
select * from mysql.user \G
mysql.user表示: 數據庫.表 的含義。
SELECT * FROM mysql.user ;
這樣不用切換數據庫,就可以查詢到其他數據庫的表。
流程控制函數
if (expr1, expe2, expr3 )
如果expr1為true,則返回expr2的值,否則返回expr3的值。
ifnull(expr1, expr2)
如果expr1不為null,則返回expr1,否則返回expr2
select case
when expr1 then expr2
when expr3 then expr4
else expr5
end ;
– select case
– when expr1 then expr2 如果expr1為True,就返回expr2,然后結束。如果expr1為false,就執行下個when代碼
– when expr3 then expr4 如果expr3為true,就返回expr4,然后結束。
– else expr5 如果expr3為false,就返回expr5,然后結束。
– end; 【感覺 類似于多重分支語句】
SELECT CASE
WHEN TRUE THEN 'jack' -- jack WHEN FALSE THEN 'tom' -- 執行else語句,返回mary。 ELSE 'mary' END;如果emp表的job是clerk,則顯示 職員;如果是 manager,則顯示 經理;如果是salesman,則顯示 銷售人員,其他的正常顯示。
SELECT ename, (SELECT CASE
WHEN job = ‘CLERK’ THEN ‘職員’ – jack
WHEN job = ‘MANAGER’ THEN ‘經理’ – 執行else語句,返回mary。
WHEN job = ‘SALESMAN’ THEN ‘銷售人員’
ELSE job
END
)AS ‘job’ FROM emp ;
索引
提高數據庫的性能,加快查詢速度(不用加內存,不用改程序,不用調sql)
原理
如果沒有索引
會進行全表掃描。因為找到一個結果后,不確定在表的其他位置是否還有符合條件的結果。所以要全表掃描,這樣一來會浪費很多時間。
如果有索引
會形成一個索引的數據結構,例如二叉樹索引,B+樹索引等。查詢效率會增加。
類型
主鍵索引:主鍵自動的為主索引,類型 primary key
唯一索引:類型unique
普通索引:index
全文索引:fulltext,適用于MyISAM
一般開發不適用mysql自帶的全文索引,而是使用:全文搜索 Solr 和 ElasticSearch(ES)
使用
1、查詢表是否有索引
show indexses from 表名 ;
2、添加索引
基本語法
【法一】
- create [unique] index 索引名稱 on 表名(列名[(length)]) [asc|desc],…) ;
【法二】
- alter table 表名 add index [索引名] (表的列名) ;
添加唯一索引
create unique index 索引名稱 on 表名 (列名) ;
添加普通索引
create index 索引名 on 表名(列名) ;
alter table 表名 add index 索引名(表的列名) ;
如何選擇 ?
如果某一列的值是不會重復的,則優先考慮使用unique索引,否則使用普通索引。
添加主鍵索引
在使用 create創建完表后,使用
alter table 表名 add primary key(表的列名) ;
3、刪除索引
刪除索引
drop index 索引名 on 表名 ;
刪除主鍵索引(比較特別)
alter table 表名 drop primary key ;
4、修改索引
先刪除 原索引,然后添加 新的索引。
5、查詢索引
【方式1】 show index from 表名 ;
【方式2】show indexes from 表名 ;
【方式3】show keys from 表名 ;
【方式4】desc 表名 ;
小結
【哪些列上適合使用索引 ?】
1、較頻繁的作為查詢條件的字段,應該創建索引。
2、唯一性太差的字段不適合單獨創建索引,即使頻繁作為查詢條件。(例如:男女性別)
3、更新非常頻繁的字段,不適合創建索引。(例如:用戶登陸次數 會頻繁改變)
4、不會出現在“where子句”中的字段不該創建索引。
事務
什么是“事務”?
事務用于保證數據的一致性,由一組相關的dml語句組成,該組的dml語句要么全部成功,要么全部失敗。(例如:轉賬要用事務來處理,用以保證數據的一致性)
事務和鎖
在執行事務操作時(dml語句),mysql語句會在表上加鎖,防止其他用戶更改表的數據。這對于用戶來講十分重要。
mysql控制臺事務的幾個重要操作
start transaction 開始一個事務
savepoint 保存點名,設置保存點
rollback to 保存點名,回滾事務至某一個保存點
rollback 回滾全部事務至事務開始時的樣子
cmmit 提交事務,同時也會刪除從 start transaction 開始的所有保存點,所有的操作生效,不能回退。
回退事務 rollback
執行回退事務時,,通過指定保存點可以回退到指定的點。
提交事務 commit
使用commit語句可以提交事務。當執行了commit語句后,會確認事務的變化、結束事務、刪除該事務定義的所有保存點、釋放鎖、數據生效。當使用 commit語句結束事務后,其他會話(其他連接)可以查看到 事務變化后的新數據 。【所有數據就正式生效】
事務細節討論
1、如果不開始事務,默認情況下,dml操作是自動提交的,不能回滾。
2、如果開始一個事務,而我們又沒有創建保存點,可以執行 rollback ,默認退回到該事務開始時的狀態。
3、當事務還沒有提交時,可以在事務中創建多個保存點。
(比如:savepoint aaa ; 執行dml,savepoint bbb ;)
4、可以在事務沒有提交前,選擇退回到哪個保存點。
5、mysql 的事務機制需要 innodb 的存儲引擎 才可以使用,MyISAM 不好使。
6、開啟一個事務有2種方式
(1)start transaction
(2)set autocommit=off
事務的隔離級別
多個連接開啟各自事務操作數據庫中的數據時,數據庫系統要負責隔離操作,以保證各個連接在獲取數據時的準確性。
如果不考慮隔離性,可能會引發:臟讀、不可重復讀、幻讀 3種問題。
臟讀(dirty read)
當一個事物讀取到另外一個事務“尚未提交的改變(update,insert,delete)”時,產生臟讀。
不可重復讀(nonrepeatable read)
同一查詢在同一事物中多次進行,由于“其他提交事物所做的 修改 和 刪除”,每次都會返回不同的結果集,此時發生不可重復讀。
幻讀(phantom read)
同一查詢在同一事物中多次進行,由于“其他提交事務所做的 插入 ”操作,每次返回不同的結果集,此時發生幻讀。
事務的隔離級別
MySQL的隔離級別定義了“事務與事務之間的隔離程度”。
設置事務的隔離級別
1、查看當前會話的隔離級別(指某一個用戶的)
SELECT @@tx_isolation ;2、查看系統當前的隔離級別(即:所有用戶登陸時的隔離級別)
SELECT @@global.tx_isolation ;3、設置當前會話的隔離級別
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;READ UNCOMMITTED 是4個隔離級別之一
4、設置系統的當前隔離級別
SET GLOBAL TRANSACTION ISOLATION LEVEL [你設置的級別] ;– mysql默認的事務隔離界別是 repeatable read, 一般情況下,沒有特殊的要求,沒有必要修改
– (因為該級別可以滿足絕大部分項目的需求)
事務的ACID
1、原子性(Atomicity)
事務是一個不可分割的工作單位,事務中的操作要么都發生,要么都不發生。2、一致性(Consistency)
事務必須使數據庫從一個一致性狀態轉變為另一個一致性狀態。
(事務一旦提交了,就會進行一個整體性的改變。這樣事務就結束,然后就再開啟一個新的事務)
3、隔離性(Isolation)
多個用戶并發訪問數據庫時,數據庫為每一個用戶開啟的事務,不能被其他事務的 操作數據所干擾,多個并發事務之間一定要相互隔離。
4、持久性(Durability)
一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障,也不會對其有任何影響。
視圖
什么是視圖 ?什么是基表 ?
視圖是一個虛擬表,其內容由查詢定義。同真實的表一樣,視圖包含列,其數據來自對應的真實表(基表)。
視圖與基表的關系
【對視圖的總結】
1、視圖是根據基表(可以是多個基表)來創建的,視圖是虛擬的表。
2、視圖也有列,數據來自基表
3、通過視圖可以修改基表的數據
4、基表的改變,也會影響到視圖的數據。
視圖的基本使用
基本語法
1、create view 視圖名 as select 語句
2、alter view 視圖名 as select 語句
3、show view 視圖名 as select 語句
4、drop view 視圖名1, 視圖名2
select語句是 根據 基表 來進行選擇。
舉例
使用細節
1、創建視圖后,到數據庫去看,對應視圖只有一個視圖結構文件。(文件形式:視圖名.frm)
2、視圖的數據變化會影響到基表,基表的數據變化也會影響到視圖(insert update delete)
3、視圖中可以再使用視圖,數據仍來自于基表。
舉例
視圖的最佳實踐
mysql管理
mysql用戶
使用原因:
當我們做項目開發是時,可以根據不同的開發人員,賦給他相應的mysql操作權限
所以MySQL數據庫管理人員根據需要創建不同的用戶,賦給相應的權限,供人員使用。
mysql中的用戶,都存儲在 系統數據庫mysql里的user表中。
創建用戶,同時指定密碼
create user ‘用戶名’ @‘允許登陸位置’ identified by ‘密碼’ ;
刪除用戶
drop user ‘用戶名’ @‘允許登陸位置’ ;
用戶修改密碼
修改自己的密碼
set password = password(‘新密碼’) ;
修改他人的密碼(需要有修改他人密碼的權限)
set password for ‘用戶名’@‘登錄位置’ = password(‘密碼’) ;
登錄
不同的數據庫用戶,登錄到DBMS后,根據相應的權限,可以操作的數據庫和數據對象(表、視圖、觸發器)不一樣
mysql中的權限
給用戶授權
基本語法
grant 權限列表 on 庫.對象名 to ‘用戶名’@‘登錄位置’ [identified by ‘密碼’] ;
說明
1、權限列表,多個權限用逗號分隔開
grant select on …
grant select, delete, create on …
grant all [privileges] on … //表示賦予該用戶在該對象上的所有權限。
2、特別說明
. :代表本系統中的所有數據庫的所有對象(表、視圖、存儲過程等)
庫.* :表示某個數據庫中的所有數據對象(表、視圖、存儲過程等)
3、identified by 可以省略,也可以寫出
(1)如果用戶存在,就是修改用戶的密碼
(2)如果該用戶不存在,就是創建該用戶!
回收用戶授權
基本語法
revoke 權限列表 on 庫.對象名 from ‘用戶名’@‘登錄位置’ ;
舉例
權限生效指令
如果權限沒有生效,就執行下面的指令:
【基礎語法】
flush privileges ;
細節說明
1、在創建用戶時,如果不指定主機Host,則為 % 。
% 表示所有的IP都有連接權限。
create user xxx ;
2、也可以這樣指定
create user ‘xxx’@‘192.168.1.%’ ; —— 表示 xxx用戶在192.168.1.*的ip可以登錄mysql
3、在刪除數據庫的時候,如果host 不是 %,就需要明確指定 ‘用戶’@‘host值’
CREATE TABLE customer(
customer_id CHAR(8) PRIMARY KEY, -- 程序員自己決定`name` VARCHAR(64) NOT NULL DEFAULT '', address VARCHAR(64) NOT NULL DEFAULT '', email VARCHAR(64) UNIQUE NOT NULL, sex ENUM('男','女') NOT NULL , -- 這里使用的枚舉類型, 是生效card_Id CHAR(18));
總結
以上是生活随笔為你收集整理的mysql数据库——思维导图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django的View(视图)
- 下一篇: mysql 开发进阶篇系列 41 mys