1、老規矩,先簡單介紹一下MySQL數據庫(當然,還是百科~)
MySQL是一個關係型數據庫管理系統,由瑞典MySQL AB 公司開發,目前屬於 Oracle 旗下產品。MySQL 是最流行的關係型數據庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關係數據庫管理系統) 應用軟件。
MySQL是一種關係數據庫管理系統,關係數據庫將數據保存在不同的表中,而不是將所有數據放在一個大倉庫內,這樣就增加了速度並提高了靈活性。
MySQL所使用的 SQL 語言是用於訪問數據庫的最常用標準化語言。MySQL 軟件採用了雙授權政策,分爲社區版和商業版,由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇 MySQL 作爲網站數據庫。
由於其社區版的性能卓越,搭配 PHP 和 Apache 可組成良好的開發環境。
Oracle數據庫更加重量級,但我們的MySQL與之相比並不差很多,最最最重要的是——MySQL是免費噠~
2、簡單操作
爲了安裝方便,我直接使用了集成的xmapp,可以在這下載https://www.apachefriends.org/index.html,雖然是用於php編寫的,但是可以把apache、mysql、tomcat這些東西一塊給裝了,而且更改配置也很方便。
數據庫操作
1.創建一個庫
create database 庫名;
create database 庫名 character set 編碼;
2.刪除一個庫
drop database 庫名;
3.使用庫
use 庫名;
4.查看當前正在操作的庫
select database();
5.查看所有庫
show databases;
數據庫表操作
1.創建一張表
create table 表名(
字段名 類型(長度) [約束],
字段名 類型(長度) [約束],
字段名 類型(長度) [約束]
);
2.查看數據庫表
show tables;
3.查看錶結構
desc 表名;
4.刪除表
drop table 表名;
5.添加一列
alter table 表名 add 字段名 類型(長度) [約束];
6.修改列的類型、長度、約束等
alter table 表名 modify 要修改的字段名 類型(長度) [約束];
7.修改列名
alter table 表名 change 舊列名 新列名 類型(長度) [約束];
8.刪除列
alter table 表名 drop 列名;
9.修改表名
rename table 表名 to 新表名;
10.修改表的字符集
alter table 表名 character set 編碼;
11.查看錶當前編碼格式
show create table 表名;
修改數據庫表記錄
1.插入
insert into 表名(列名1,列名2,列名3……) values(值1,值2,值3……);
insert into 表名 values(值1,值2,值3……);
2.修改
update 表名 set 字段名=值, 字段名=值, 字段名=值……; 它會將該列的所有記錄都更改
update 表名 set字段名=值, 字段名=值, 字段名=值…… where 條件; 僅修改選中的列
3.刪除
delete from 表名 where 條件;
delete from 表名;
truncate table 表名;
ps:delete刪除的時候是一條一條的刪除記錄,它配合事務,使用rollback可以將刪除的數據找回。truncate刪除,它是將整個表摧毀,然後再創建一張一模一樣的表,它刪除的數據無法找回。
4.查詢
select * from 表名; 查詢所有
select 屬性, 屬性... from product; 查詢所選列
select * from 表名 as 別名; 使用別名輸出表的所有內容,其中as可以省略,同樣,所選列也可以使用別名
select distinct(屬性) from 表名; 去除重複值
select * from 表名 where 屬性=值; 按條件查詢,可以使用and、or以及not查詢多個條件
select * from 表名 order by asc(desc); 按升序(降序)排列查詢結果
5.聚合函數
select sum(屬性) from 表名; 查詢表中所選屬性的總和,sum也可以更改爲avg、count等,分別表示平均值、個數
6.分組
select * from 表名 group by 屬性; 根據屬性進行分組展示
小結:
select 一般在的後面的內容都是要查詢的字段
from 要查詢到表
where
group by
having 分組後帶有條件只能使用having
order by 它必須放到最後面
3、高級操作
外鍵
在說明外鍵之前,先簡單說一下表與表之間的關係。
1.一對多關係
常見實例:客戶和訂單、分類和商品、部門和員工等
建表原則:在從表(多方)創建一個字段,字段作爲外鍵指向主表(一方)的主鍵
2.多對多關係
常見實例:學生和課程、商品和訂單、人和角色
建表原則:需要建立第三張表作爲中間表,中間表至少有兩個字段,分別作爲外鍵指向各自多方的主鍵,即將多對多拆分爲兩個一對多
3.一對一關係(瞭解,在生產中不常見)
建表原則(擇其一):
- 外鍵唯一:主表的主鍵和從表的外鍵(唯一),形成主外鍵關係,外鍵唯一以unique修飾
- 外鍵是主鍵:主表的主鍵和從表的主鍵直接形成主外鍵關係
外鍵的使用sql代碼如下:
alter table 從表 add [constraint] [外鍵名稱] foreign key (從表外鍵字段名) references 主表 (主表的主鍵)
[外鍵名稱] 會在刪除外鍵約束時使用,一般使用:字段名_fk
使用外鍵是爲了保證數據的完整性!!!
當兩張表沒有建立任何關係的時候,那麼可以隨意刪除其中任何一張表中的任何記錄,但是一旦把兩張表建立了關係(主外鍵約束)之後,那麼不能刪除主表中的數據(這些數據內容在從表中有關聯關係的數據),只想執行刪除(更新操作),那麼就會出現下圖中的錯誤。
要想刪除主表中與從表有關聯關係的數據,可以這麼做:
- 解除主從表的約束關係
- 先刪除從表中與主表有關係的數據,再刪除主表中的數據。(需要先把p003和P004的數據刪除了,再刪除分類表中c002的數據。)
另外,從表也不能添加主表中不存在的數據!
子查詢
帶有ANY或ALL謂詞的子查詢
子查詢返回單值時可以用比較運算符,而使用ANY或ALL謂詞時則必須同時使用比較運算符,其語義爲:
>ANY 大於子查詢結果的某個值
>ALL 大於子查詢結果中的所有值
<ANY 小於子查詢結果中的某個值
<ALL 小於子查詢結果中的所有值
>=ANY 大於等於子查詢結果中的某個值
>=ALL 大於等於子查詢結果中的所有值
<=ANY 小於等於子查詢結果中的某個值
<=ALL 小於等於子查詢結果中的所有值
=ANY 等於子查詢結果中的某個值
=ALL 等於子查詢結果中的所有值(通常沒有實際意義)
!=(或<>)ANY 不等於子查詢結果中的某個值
!=(或<>)ALL 不等於子查詢結果中的任何一個值
例:查詢其他系中比信息系某一學生年齡小的學生姓名和年齡
SELECT Sname,Sage
FROM Student
WHERE Sage<ANY(SELECT Sage
FROM Student
WHERE Sdept='IS')
AND Sdept<>'IS'
結果如下:
Sname Sage
-------------------------------------
王敏 18
DBMS執行此查詢時,首先處理子查詢,找出IS系中所有學生的年齡,構成一個集合(19,18)。然後處理父查詢,找所有不是IS系且年齡小於19或18的學生。
本查詢可以用集函數來實現,首先用子查詢找出IS系中最大年齡(19),然後在父查詢中查所有非IS系且年齡小於19歲的學生姓名及年齡,SQL語句如下:
SELECT Sname,Sage
FROM Student
WHERE Sage<
(SELECT MAX(Sage)
FROM Student
WHERE Sdept='IS')
AND Sdept<>'IS'
例二:查詢其他系中比信息系所有學生年齡都小的學生姓名及年齡。
SELECT Sname,Sage
FROM Student
WHERE Sage<ALL
(
SELECT Sage
FROM Student
WHERE Sdept='IS'
)
AND Sdept<>'IS'
查詢結果爲空表,本查詢同樣也可以用集函數來實現,SQL語句如下:
SELECT Sname,Sage
FROM Student
WHERE Sage<
(SELECT MIN(Sage)
FROM Student
WHERE Sdept='IS'
)
AND Sdept<>'IS'
事實上,用集函數來實現子查詢通常比直接用ANY或ALL查詢效率要高,ANY與ALL與
集函數的對應關係如下所示
|
= |
<>或!= |
< |
<= |
> |
>= |
ANY |
IN |
- |
<MAX |
<=MAX |
>MIN |
>=MIN |
ALL |
-- |
NOT IN |
<MIN |
<=MIN |
>MAX |
>=MAX |
分頁查詢
分頁查詢使用的是limit關鍵字進行查詢。它後面有兩個參數。第一個參數是起始的位置(取值爲:(需要查看第幾頁-1)乘以第二個參數),第二個參數是每頁需要顯示的條目數。
舉例:商品表中有10條記錄,現在需要進行分頁顯示,每頁顯示3條數據。現在需要查看第二頁的數據。那麼應該使用的sql語句是:
select * from product limit 3,3;
執行分頁查詢語句後,顯示的結果如下:
內連接與外連接
1.概述
內聯接(典型的聯接運算,使用像 = 或 <> 之類的比較運算符)。包括相等聯接和自然聯接。
內聯接使用比較運算符根據每個表共有的列的值匹配兩個表中的行。例如,檢索 students和courses表中學生標識號相同的所有行。
外聯接。外聯接可以是左向外聯接、右向外聯接或完整外部聯接。
在 FROM子句中指定外聯接時,可以由下列幾組關鍵字中的一組指定:
1)LEFT JOIN或LEFT OUTER JOIN
左向外聯接的結果集包括 LEFT OUTER子句中指定的左表的所有行,而不僅僅是聯接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的所有選擇列表列均爲空值。
2)RIGHT JOIN 或 RIGHT OUTER JOIN
右向外聯接是左向外聯接的反向聯接。將返回右表的所有行。如果右表的某行在左表中沒有匹配行,則將爲左表返回空值。
3)FULL JOIN 或 FULL OUTER JOIN
完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據值。
2.內連接(INNER JOIN)
內連接(INNER JOIN):有兩種,顯式的和隱式的,返回連接表中符合連接條件和查詢條件的數據行。(所謂的鏈接表就是數據庫在做查詢形成的中間表)。
例如:下面的語句3和語句4的結果是相同的。
語句1:隱式的內連接,沒有INNER JOIN,形成的中間表爲兩個表的笛卡爾積。
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME
FROM CUSTOMERS C,ORDERS O
WHERE C.ID=O.CUSTOMER_ID;
語句2:顯示的內連接,一般稱爲內連接,有INNER JOIN,形成的中間表爲兩個表經過ON條件過濾後的笛卡爾積。
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME
FROM CUSTOMERS C INNER JOIN ORDERS O ON C.ID=O.CUSTOMER_ID;
注意:內連接查詢結果與表的順序無關
(當然順序可能會發生變化,但是對應關係絕對不會錯亂!!!)
內連接有幾種,下面一一進行展示:
⑴交叉連接(cross join)
當然,他還有其他的名字,比如:笛卡爾積,交叉積,還有最奇怪的名字“沒有連接”(no join)
使用下列命令同時查詢玩具表的toy列和男孩表的boy列,得到的結果就是交叉連接
SELECT t.toy, b.boy FROM toys AS t CROSS JOIN boys AS b;
其中,CROSS JOIN可以省略,簡寫爲
SELECT t.toy,b.boy FROM toys AS t, boys AS b;
交叉連接回把第一張表的每個值與第二張表的每個值進行匹配,結果如下
交叉連接是內連接的一種,你又可以把內連接看作是通過查詢限制條件後去除某些結果數據行之後的交叉連接。
⑵相等連接
我們假設每個男孩子都又一個玩具,表之間是一對一的關係,toy_id是外鍵,數據庫表如下圖
我們想找到每個男孩兒擁有什麼玩具,只需要將boys表中的toy_id和toys中的主鍵進行比對,就會得到結果
SELECT boys.boy, toys.toy FROM boys INNER JOIN toys ON boys.toy_id=toys.toy_id;
⑶不等連接
我們繼續沿用1.2中的表結構,如果我們想找到每個男孩兒沒有的玩具,這時候我們可以使用不等連接(說白了就是=換成<>,其他沒有什麼區別)
SELECT boys.boy, toys.toy FROM boys INNER JOIN toys ON boys.toy_id<>toys.toy_id ORDER BY boys.boy;
⑷自然連接
繼續沿用1.2的表結構。。。。。
注意:自然連接只有在連接的列在兩張表中的名稱都相同時纔會有用
其實,自然連接就是自動識別相同列的相等連接
SELECT boys.boy, toys.toy FROM boys NATURAL JOIN toys ORDER BY boys.boy;
得到的結果和1.2中的結果完全一樣(順序可能不同)
3.外連接(OUTER JOIN):
外連不但返回符合連接和查詢條件的數據行,還返回不符合條件的一些行。外連接分三類:左外連接(LEFT OUTER JOIN)、右外連接(RIGHT OUTER JOIN)和全外連接(FULL OUTER JOIN)。
三者的共同點是都返回符合連接條件和查詢條件(即:內連接)的數據行。不同點如下:
左外連接還返回左表中不符合連接條件單符合查詢條件的數據行。
右外連接還返回右表中不符合連接條件單符合查詢條件的數據行。
全外連接還返回左表中不符合連接條件單符合查詢條件的數據行,並且還返回右表中不符合連接條件單符合查詢條件的數據行。全外連接實際是上左外連接和右外連接的數學合集(去掉重複),即“全外=左外 UNION 右外”。
說明:左表就是在“(LEFT OUTER JOIN)”關鍵字左邊的表。右表當然就是右邊的了。在三種類型的外連接中,OUTER 關鍵字是可省略的。
下面舉例說明:
語句3:左外連接(LEFT OUTER JOIN)
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
語句4:右外連接(RIGHT OUTER JOIN)
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
注意:WHERE條件放在ON後面查詢的結果是不一樣的。例如:
語句5:WHERE條件獨立。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
WHERE O.ORDER_NUMBER<>'MIKE_ORDER001';
語句6:將語句5中的WHERE條件放到ON後面。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID AND O.ORDER_NUMBER<>'MIKE_ORDER001';
從語句5和語句6查詢的結果來看,顯然是不相同的,語句6顯示的結果是難以理解的。因此,推薦在寫連接查詢的時候,ON後面只跟連接條件,而對中間表限制的條件都寫到WHERE子句中。
語句7:全外連接(FULL OUTER JOIN)。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O FULL OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
注意:MySQL是不支持全外的連接的,這裏給出的寫法適合Oracle和DB2。但是可以通過左外和右外求合集來獲取全外連接的查詢結果。
語句8:左外和右外的合集,實際上查詢結果和語句7是相同的。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
UNION
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
下面通過圖示來更清楚的展示一下:
⑴左外連接
LEFT OUTER JOIN(左外連接)接收左表的所有行,並用這些行與右表進行匹配
當左表與右表具有一對多的關係時,左外連接特別有用。我們仍然使用之前的表結構
現在我們利用左外連接找出每個男孩擁有的玩具
SELECT b.boy, t.toy FROM boys b LEFT OUTER JOIN toys t ON b.toy_id=t.toy_id;
我們的查詢結果和使用內連接時一樣,難道說內連接和外連接沒區別嗎?怎麼可能!!!接下來我們改變一下左表boys的表結構
我們向boys中新添加了一個Andy,把他的toy_id設置爲6,注意,6在toys表中沒有對應的玩具,接下來再次運行上述程序
我們發現居然出現了一個NULL,NULL的出現是要告訴我們右表toys中沒有與左表boys中的Andy相匹配的行,也就是說:
外連接一定會提供數據行,無論還行能否在另一個表中找出相匹配的行
接着做個實驗,我們調換左表和右表的順序
SELECT b.boy, t.toy FROM toys t LEFT OUTER JOIN boys b ON b.toy_id=t.toy_id;
因此我們可以得出結論:出現NULL的列總是右表中的列
⑵右外連接
與左外連接完全相同,只不過是用右表來評價左表
此外:RIGHT OUTER JOIN左側的表爲右表!!!!!
在實際使用中我們只要掌握一種方式,另一種做了解即可。
另外要說的兩件事情!!!
①對於外連接, 也可以使用“(+) ”來表示。 關於使用(+)的一些注意事項:
1.(+)操作符只能出現在where子句中,並且不能與outer join語法同時使用。
2. 當使用(+)操作符執行外連接時,如果在where子句中包含有多個條件,則必須在所有條件中都包含(+)操作符
3.(+)操作符只適用於列,而不能用在表達式上。
4.(+)操作符不能與or和in操作符一起使用。
5.(+)操作符只能用於實現左外連接和右外連接
左連接
用(+)來實現, 這個+號可以這樣來理解:+ 表示補充,即哪個表有加號,這個表就是匹配表。所以加號寫在右表,左表就是全部顯示,故是左連接。
SQL> Select * from dave a,bl b where a.id=b.id(+); -- 注意: 用(+) 就要用關鍵字where
右連接
用(+)來實現, 這個+號可以這樣來理解:+ 表示補充,即哪個表有加號,這個表就是匹配表。所以加號寫在左表,右表就是全部顯示,故是右連接。
SQL> Select * from dave a,bl b where a.id(+)=b.id;
②on與where的區別
數據庫在通過連接兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給用戶。
在使用left jion時,on和where條件的區別如下:
1、on條件是在生成臨時表時使用的條件,它不管on中的條件是否爲真,都會返回左邊表中的記錄。
2、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須返回左邊表的記錄)了,條件不爲真的就全部過濾掉。
假設有兩張表:
表1:tab2 id size
1 10
2 20
3 30
表2:tab2 size name
10 AAA
20 BBB
20 CCC
兩條SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.sizeand tab2.name=’AAA’)
第一條SQL的過程:
1、中間表
on條件:
tab1.size = tab2.size tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 20 BBB
2 20 20 CCC
3 30 (null) (null)
2、再對中間表過濾
where 條件:
tab2.name=’AAA’
tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
第二條SQL的過程:
1、中間表
on條件:
tab1.size = tab2.size and tab2.name=’AAA’
(條件不爲真也會返回左表中的記錄) tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 (null) (null)
3 30 (null) (null)
其實以上結果的關鍵原因就是left join,right join,full join的特殊性,不管on上的條件是否爲真都會返回left或right表中的記錄,full則具有left和right的特性的並集。而inner jion沒這個特殊性,則條件放在on中和where中,返回的結果集是相同的。
外鏈接匹配,內連接過濾,外鏈接即匹配又過濾用on和where搭配
內連接與外連接部分的內容參考了以下博客,在此表示感謝!
https://blog.csdn.net/qq877507054/article/details/52328017
https://blog.csdn.net/chanmufeng/article/details/78234654
最後,奉上一份修改MySQL的root用戶密碼的祕籍一份,關注發送:mysqlroot 獲取~~
有任何需要請在後臺回覆,我們會及時查看的~