MySQL自己自帶4張表:git
information_schema:數據庫又稱爲信息架構,數據表保存了MySQL服務器全部數據庫的信息。如數據庫名,數據庫的表,表欄的數據類型與訪問權限等。github
performance_schema:數據庫主要用於收集數據庫服務器性能參數,以便優化mysql數據庫性能。sql
mysql:數據庫是存儲着已MySQL運行相關的基本信息等數據管理的數據庫。數據庫
sys:數據庫是mysql5.7增長的,經過這個庫能夠快速的瞭解系統的元數據信息
這個庫能夠方便DBA發現數據庫的不少信息,提供解決性能瓶頸的信息。服務器
mysql -u root -p
而後輸入密碼
或者將密碼明文登錄
mysql -u root -p password
指定服務器-h
mysql -h localhost -u root -p password
架構
-u 以什麼用戶登錄 root即以root用戶登錄
-p 以密碼登錄,有密碼就輸入密碼沒有密碼就回車確認函數
建立
CREATE database 數據庫名
刪除
DROP database 數據庫名
查看全部數據庫
SHOW databases
切換數據庫
use 數據庫名
性能
建立
CREATE TABLE 表名(字段1 數據類型[選項],字段2 數據類型[選項],...)
刪除
DROP TABLE 表名
查看全部表
SHOW TABLES
優化
ALTER TABLE ... MODIFY
ALTER TABLE 表名 MODIFY 列名 數據類型;
ALTER TABLE ... ADD
ALTER TABLE 表名 ADD 列名 數據類型;
ALTER TABLE ... CHANGE
ALTER TABLE ... DROP
ALTER TABLE 表名 DROP 列名
新建表複製已有的表的結構而不須要數據,使用LIKE關鍵字
CREATE TABLE 新表名 LIKE 舊錶名
create table new_user_no_data like user;
新建表複製表的結構和數據
CREATE TABLE 新表名 SELECT * FROM 舊錶名
create table new_user select * from user;
向已有的表中複製另外一張表的數據
INSERT INTO 表名 SELECT * FROM 帶數據的表
nsert into new_user_no_data select * from user;
示例:
#user表建立語句 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL COMMENT '用戶名稱', `birthday` date DEFAULT NULL COMMENT '生日', `sex` char(1) DEFAULT NULL COMMENT '性別', `address` varchar(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8; #建立商品表 CREATE TABLE `items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL COMMENT '商品名稱', `price` float(10,1) NOT NULL COMMENT '商品訂價', `detail` text COMMENT '商品描述', `pic` varchar(64) DEFAULT NULL COMMENT '商品圖片', `createtime` datetime NOT NULL COMMENT '生產日期', PRIMARY KEY (`id`) #<---------------------------指明items的惟一主鍵字段 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #訂單表orders建立語句 CREATE TABLE `orders` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '下單用戶id', `number` varchar(32) NOT NULL COMMENT '訂單號', `createtime` datetime NOT NULL COMMENT '建立訂單時間', `note` varchar(100) DEFAULT NULL COMMENT '備註', PRIMARY KEY (`id`), CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION #<-----建立外鍵約束 ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; #訂單詳情表orderdetail建立語句 CREATE TABLE `orderdetail` ( `id` int(11) NOT NULL AUTO_INCREMENT, `orders_id` int(11) NOT NULL COMMENT '訂單id', `items_id` int(11) NOT NULL COMMENT '商品id', `items_num` int(11) DEFAULT NULL COMMENT '商品購買數量', PRIMARY KEY (`id`), #<--------建立外鍵約束-----------> CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
上面的示例中orders_id 和 items_id 分別的訂單表orders和商品表items的主鍵,像這種屬於其餘表主鍵又存在於orderdetail表中的字段,稱之爲orderdetail的外鍵字段,使用外鍵的好處是可使得兩張表存在關聯,保證數據的一致性和實現一些級聯操做(級聯操做:外鍵關聯的表爲主表,當主表發生改變,設置外鍵的從表也會發生改變,好比修改刪除主表的內容從表也會被刪除,或者當從表添加主表沒有數據的數據時將添加失敗)如每次購物時必須存在相對應的items_id商品數據才能建立訂單詳情的數據,由於沒有商品也沒有所謂的訂單詳情了,而每次可能會購買多種商品,而每種商品也將生成不一樣訂單詳情,而客戶的購買行爲屬一次購買,所以訂單詳情匯聚成一個總體的訂單(orders_id),也就是說一個訂單詳情只能屬於一個訂單,而一個訂單能夠擁有多個訂單詳情。在MySQL中,InnoDB引擎類型的表支持了外鍵約束,而外鍵的使用條件以下:
1.兩個表必須使用InnoDB引擎
2.外鍵列必須創建了索引(關於索引後面分析,主鍵建立時會自動建立索引),MySQL 4.1.2之後的版本在創建外鍵時會自動建立索引
3.外鍵關係的兩個表的列必須是數據類型類似,也就是能夠相互轉換類型的列,好比int和tinyint能夠,但int和char則不能夠;
外鍵語法:
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, …) REFERENCES tbl_name (index_col_name, …) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
注意該語法能夠在 CREATE TABLE 和 ALTER TABLE 時使用,CONSTRAINT symbol,指明瞭約束標識符,在SQL排錯時可能有不錯的表現,若是不指明CONSTRAINT symbol,MYSQL會自動生成一個名字。兩表間的更新刪除時數據的同步可使用ON DELETE、ON UPDATE 來代表相互間刪除和更新事件觸發後的影響,可設參數如下參數(假設主表是orders,從表是orderdetail):
RESTRICT、NO ACTION(默認行爲)
刪除:從表數據記錄不存在時,主表數據記錄才能夠刪除,如當從表orderdetail的數據被刪除後主表的orders的數據才能被刪除,不然沒法刪除。刪除從表數據,主表數據不變
更新:從表記錄數據不存在時,主表數據才能夠更新。當更新從表數據,主表數據不變
CASCADE(級聯)
刪除:刪除主表數據時自動刪除從表數據。刪除從表數據,主表數據不變
更新:更新主表數據時自動更新從表數據。更新從表數據,主表數據不變
SET NULL
刪除:刪除主表數據時自動更新從表對於數據值爲NULL。刪除從表數據,主表數據不變
更新:更新主表數據時自動更新從表數據值爲NULL。更新從表數據數據,主表不變
#insert 插入操做,列名和後面的數據要一一對應,但若是要插入全部的列時能夠忽略列名 INSERT INTO 表名(列名1,列名2,...) VALUES (數據1,數據2...); #update 更新操做 UPDATE 表名 SET 列名1=值1,列名2=值2,...WHERE 條件表達式; #delete 刪除操做 DELETE FROM 表名 WHERE 條件表達式 #select 查詢操做 SELECT 列名1,列名2,... FROM 表名 [條件表達式]
單獨說下查詢,增刪改的操做語法結構相對簡單,但查詢經常會有不少種組合來獲取不一樣的查詢結果
查詢變化主要在where對結果的過濾處理
|運算符 |描述|演示|
|---|---|---|
|= |相等|id = 15
|> |大於|id > 15
|< |小於|id < 15
|>= |大於等於|id >= 15
|<= |小於等於|id <= 15
|<> |不相等| id <> 15
|IS |[NOT] NULL 爲NULL(不爲NULL)| address is NULL
|[NOT]| LIKE |模糊查詢,指向模糊查詢目標 address LIKE '北京%'
|[NOT]| BETWEEN |(不包含)包含在指定範圍內 id BETWEEN 1 AND 15
|[NOT]| IN |包含在指定範圍值內 id in (1,2,15,20)
NULL條件有點須要注意,在使用NULL條件檢索時不能使用=號,必須使用 is 指明查詢條件的值爲空,固然若是是not null 那就是非空數據
mysql> select * from user where birthday is NULL;
關鍵字like主要用於模糊查詢,以下查詢名稱爲‘任’開頭的用戶:
mysql> select username from user where username like '任%';
字符:
% :表示0個以上的全部字符
*:包括0的全部字符
_ :一個字符
BETWEEN 是讓咱們能夠運用一個範圍 (range) 內抓出數據庫中的值
mysql> select * from user where id between 1 and 15 ;
表示某一組指明的數據,在括弧內能夠有一或多個值,而不一樣值之間由逗點分開。值能夠是數目或是文字。
#查詢id爲1,2,3的用戶 mysql> select * from user where id in (1,2,3);
當須要在查詢中使用多個條件組合時,可使用AND 或者 OR ,其中指明兩個條件必須成立,而OR則須要一個條件成當即可。注意:語句查詢時對於AND和OR的使用以及計算順序要特別注意,不然將會獲得非預期的查詢結果
當但願查詢出的數據按照必定的規律排序,此時ORDER BY就是很好的幫手了,如想讓查詢出來的數據按生日排序。
#ASC升序 DESC降序,若是有多個排序則用,隔開前面的排序優於後面的排序
mysql> select username,birthday from user where id > 15 order by birthday ASC, birthday DESC;
經過LIMIT能夠獲取到指定行數的記錄。好比想獲取前3條數據
mysql> select * from user limit 0 , 3;
有時候可能須要依據某個字段進行查詢結果分組,這時GROUP BY就顯得頗有用了,須要注意的是若是列中具備NULL值,則NULL將做爲一個分組返回,若是列中有多個NULL值,它們將分爲一組,而且GROUP BY 子句必須出如今WHERE子句以後,ORDER BY 語句以前。
#根據sex統計分組數量
mysql> select sex ,count(id) from user group by sex;
當須要對分組的數據進行過濾,從而指定包括哪些分組,排除哪些分組,好比根據sex字段進行user查詢分組時想排除sex字段值爲null的數據,此時須要指明一個條件進行過濾,可能咱們已想到where 子語句,遺憾的是where並不能對數據進行分組過濾,由於where更多地是進行行數據的過濾而不是分組數據的過濾,實際上where並無分組的概念。幸運的是,mysql提供另外的子語句having,having與where有點相似,只不過where是進行行數據過濾,而having是進行組數據過濾,即在分組後才進行數據過濾
#使用 having 排除sex爲null的分組
mysql> select sex ,count(id) from user group by sex having sex is not null;
計算字段就經過將原有select要查詢的字段組合計算出來的字段,好比:
select Concat(username,'(',birthday,')') from user where birthday is not null;
+-----------------------------------+ | Concat(username,'(',birthday,')') | +-----------------------------------+ | 張曹宇(1990-08-05) |
mysql> select name , price ,price * 0.8 AS discount_price from items
| name | price | discount_price | <-----------字段的名稱使用AS操做符建立別名 +------------------+---------+----------------+ | MacBook Air | 8298.9 | 6639.1 | | MacBook Pro | 10982.0 | 8785.6 |
文本處理函數 | 描述 |
---|---|
Concat(str1,str2,…) | 鏈接字符串 |
Left(str,len) | 從字符串的左端開始取得len長的子串 |
Right(str,len) | 從字符串的右端開始取得len長的子串 |
Length(str) | 返回串str的長度 |
Lower(str) | str轉爲小寫 |
Upper(str) | str轉爲大寫 |
Trim(str) | 去掉字符串str兩邊的空格 |
SubString(str,pos[,len]) | 取得字符串str中從pos位置開始的len長的子串 |
Replace(t1,t2,t3) | 把t1字符串中的t2換爲t3 |
SubString(t,x,y) | 返回t中始於x的長爲y的字符串 |
數值處理函數 | 描述 |
---|---|
Abs(num) | 返回一個數的絕對值 |
Mod(x,y) | 求x/y餘數 |
Pow(x,n) | x的n次方 |
Rand() | 返回一個隨機數 |
Round(n1,n2) | 返回數n1,它被四捨五入爲n2位小數 |
Sqrt(num) | 返回一個數的平方根 |
Ceiling(num) | 基於num的值的下一個最大的整數 |
Floor(num) | 返回num的整數值 |
Format(n1,n2) | 返回格式化爲一個數的n1,這個數帶有n2位小數,而且每3位之間插入一個逗號 |
日期處理函數 | 描述 |
---|---|
Now | 當前時間(2017-04-08 17:06:45) |
CurDate() | 當前日期(2017-04-08) |
CurTime() | 當前時間(17:06:45) |
DateDiff(d1,d2) | 計算兩個日期差值 |
AddDate() | 添加一個日期(天、周等) |
AddTime() | 添加一個時間(時、分等) |
date_format(d1,format) | 格式化日期 |
Date() | 返回日期時間的日期部分 |
Month() | 返回一個日期的月份部分 |
Year() | 返回一個日期的年份部分 |
Day() | 返回日期的天數部分 |
DayOfWeek() | 對於一個日期返回對於星期幾 |
Hour() | 返回一個時間的小時部分 |
Minute() | 返回一個時間的分鐘部分 |
Second() | 返回一個時間的秒部分 |
有些狀況下咱們可能只是須要查詢結果的彙總數據而不是把每行每列檢索出來,如肯定表中的行數,獲取表中每一個字段的總和等,此時使用mysql提供的聚合函數就可很容易得到預期結果,通常經常使用的聚合函數以下:
日期處理| 描述 | 備註 |示例
|---|---|---| --- |
AVG(列名) |平均值| AVG函數是用來查找各類記錄的一個字段的平均值,計算的字段是必須提供的,並且對於NULL值,AVG()函數將會忽略值爲NULL的行 |select AVG(price) AS avg_price from items;
COUNT(列名) |總數量| COUNT用來統計行數,COUNT(*)對錶中全部行包括null進行統計,COUNT(column)對特定列中的具備值的行進行統計,忽略NULL值 |select COUNT(*) AS count from user;
MAX(列名) |最大值| |select MAX(price) AS max_price ,MIN(price) AS min_price from items;
MIN(列名) |最小值| |` SUM(列名) |合計值| |
select SUM(items_num) AS items_sum_count from orderdetail; `
在實際開發中,單表查詢並不能很好知足預期的需求,而經過多表關聯查詢則能實現預期的需求。
同時使用表關聯,1.對於每一個訂單來講,相同的商品的信息都是同樣的,所以若是把商品信息直接存放到訂單表中,對於不一樣訂單的相同商品的信息的存儲將是重複的,這屬於既浪費時間又浪費存儲空間,徹底沒有必要。2.若是此時商品信息發生變化,對於商品表來講只需改變一次便可,但若是直接把商品信息存儲到訂單表中,那麼重複的商品信息都將要修改,維護成本得不償失呢,這也就是爲何須要關聯表的緣由。
但同時代價就是相對單表查詢,多表聯查的效率會下降。
語法:
SELECT 列名1 ... FROM 表1 INNER JOIN 表2 ON 表1.外鍵 = 表2.外鍵 [WHERE / ORDER BY 語句等]
示例:
#關聯orderdetail和items表查詢出每一個訂單詳情的商品名稱,商品價格,購買數量,購買總價格
select tm.name , tm.price ,od.items_num, (tm.price * od.items_num) AS sum_price from orderdetail AS od inner join items AS tm on od.items_id = tm.id;
+-------------+---------+-----------+-----------+
| name | price | items_num | sum_price |
+-------------+---------+-----------+-----------+
| MacBook Air | 8298.9 | 1 | 8298.9 |
| MacBook Pro | 10982.0 | 3 | 32946.0 |
| 揹包 | 200.0 | 4 | 800.0 |
| MacBook Pro | 10982.0 | 3 | 32946.0 |
+-------------+---------+-----------+-----------+
外關聯,又稱外鏈接,分爲左外鏈接和右外鏈接,實際上還有全外鏈接(左外結果+右外結果),可是mysql並不支持全外鏈接
左聯就是左邊的表顯示全部的信息而不管右邊的表是否有對應的數據
語法:
SELECT 列名1 ... FROM 表1 LEFT [OUTER] JOIN 表2 ON 表1.外鍵 = 表2.外鍵 [WHERE / ORDER BY 語句等]
select u.username , o.number , o.createtime from user as u left join orders as o on u.id = o.user_id;
右外鏈接的做用剛好與左外鏈接相反,即右邊的表老是顯示全部信息,不管左邊的表是否有對應的數據,一樣地,表間的順序將影響查詢結果
語法:
SELECT 列名1 ... FROM 表1 RIGHT [OUTER] JOIN 表2 ON 表1.外鍵 = 表2.外鍵 [WHERE / ORDER BY 語句等]
涉及超過兩張表的關聯查詢
#3張表(orders,orderdetail,items)關聯查詢,number重複的緣由很簡單,每一個訂單會多條訂單詳情的信息
select o.number , tm.name , tm.price , od.items_num from (orders as o inner join orderdetail as od on o.id = od.orders_id ) inner join items as tm on od.items_id = tm.id ;
關聯支持多重嵌套,好比:
select u.username , o.number , tm.name , tm.price , od.items_num from -> ( -> (orders as o inner join orderdetail as od on o.id = od.orders_id ) -> inner join items as tm on od.items_id = tm.id -> ) -> inner join user as u on o.user_id = u.id;
但不要使用太複雜或者過多嵌套的聯結查詢,那會致使效率極低
子查詢就是嵌套在其餘查詢中的查詢,其基本經常使用語法以下(並不限於這種類型,where語句的子查詢比較常見罷了):
SELECT 列名1... FROM 表名 WHERE 列名 比較運算符 (SELECT 命令)
好比:
查詢價格在平均價格之上的商品
select * from items -> where price > (select AVG(price) from items);
查詢尚未下訂單的用戶
select username , address from user where id not in (select user_id from orders);
組合查詢就是把多個select查詢語句的結果相結合,建立組合查詢須要使用UNION操做符。
組合查詢的規則:
-- UNION 必須由兩條或者兩條以上的select語句組成並使用 UNION 進行組合。
-- UNION 中的每一個查詢必須包含相同的列、表達式或者聚合函數,但出現順序沒必要同樣
-- 列數據類型必須兼容,但沒必要徹底相同。
好比:
mysql> select id , name ,price from items where price < 3000 -> union <---union會幫咱們過濾掉重複數據,若是不想過濾重複數據;能夠用union all -> select id , name ,price from items where id in (1,2,3);
本博客爲Swagger-Ranger的筆記分享,文章會持續更新 文中源碼地址: https://github.com/Swagger-Ranger 歡迎交流指正,若有侵權請聯繫做者確認刪除: liufei32@outlook.com