MySQL基礎學習總結

來源:互聯網
上載者:User

MySQL基礎學習總結
1、MySQL基礎概念

mysql邏輯架構如下:

  每個用戶端串連都會在伺服器中擁有一個線程,這個串連的查詢只會在這個單獨的線程中執行。

  MySQL是分層的架構。上層是伺服器層的服務和查詢執行引擎,下層是儲存引擎。雖然有很多不同作用的外掛程式API,但儲存引擎API還是最重要的。如果能理解MySQL在儲存引擎和服務層之間處理查詢時如何通過API來回互動,就能抓住MySQL的核心基礎架構的精髓。

  資料庫系統實現了各種死結檢測和死結逾時機制,InnoDB目前處理死結的機制是,將持有最少行級排它鎖的事務進行復原。MySQL服務層不管理事務,事務是由下層的儲存引擎實現的。

  注意,SQL語句一般以';'或者'\g'結束。

  • 資料庫(database): 儲存有組織的資料的容器。
  • 表(table): 某種特定類型資料的結構化清單。
  • 列(column): 表中的一個欄位,所有表都是由一個或多個列組成的。
  • 資料類型(datatype): 所容許的資料的類型,每個表列都有相應的資料類型,它限制該類所儲存的類型。
  • 行(row): 是表中的一個記錄。
  • 主鍵(primary key): 是一列(或者一組列),其值能夠唯一區分表中每個行。

 

2、使用MySQL
  • mysql -h host -u username -p 與資料庫建立串連
  • use database_name 選擇資料庫
  • show databases 顯示所有的資料庫
  • show tables 顯示當前資料庫下所有的表
  • show columns from table_name 顯示表的列資訊,作用和desc table_name是一樣的

MySQL支援的其他show語句還有:

  • show status 顯示MySQL伺服器狀態資訊
  • show create database_name和show create table_name 分別顯示建立特定資料庫和資料表的MySQL語句
  • show grants 顯示授予使用者的安全許可權
  • show errors和show warnings 顯示伺服器錯誤或警告資訊

 

3、檢索資料

  SQL語句中最常用的就是select語句了,它用來在一個或多個表中檢索資料,select使用樣本如下:

  • select column_name from table_name 從table_name資料表中檢索column_name列,檢索單個列
  • select column1_name, column2_name from table_name 檢索多個列
  • select * from table_name 檢索所有列

  

  注意,select返回所有匹配的行,但是,如果我們不想每個值都每次出現,怎麼辦呢?例如,想讓中輸出的id唯一,這樣可以再select語句中添加distinct關鍵字,select distinct id from goods,這樣顯示結果如下:

    有時我們想限制輸出的結果,比如返回第一行或前幾行,可使用limit子句,如下所示:

  • select * from goods limit 2 返回前2行結果,注意,當行數不夠時,只能返回資料表中有限的行數
  • select * from goods limit 2, 2 返回從行2開始的2行

  當然,我們也可以使用完全限制來進行資料檢索:

select goods.id, goods.name from goods 輸出goods表中所有記錄

 

4、排序檢索資料

  排序檢索資料主要使用select語句的order by子句,根據需要排序檢索出的資料,select語句預設返回結果是沒有特定順序的,在排序檢索資料時也可以指定排序的方向,比如升序或者降序等,order by子句預設為升序排列。

    (這個是降序配列)

  有時,我們需要對多個列排序怎麼辦呢?這時可以使用如下sql語句來執行,select * from goods order by id desc, name,注意,這裡是對id進行降序排列,如果id相同時,對name進行升序排列。如果想對多個列進行降序排列,需要對每個列指定desc關鍵字。

  使用order by和limit的組合,我們能夠找到一個列中最高或者最低的值,比如這裡還用goods表做測試,先給goods表增加一個num欄位(alter table goods add num int),並添加上對應的值,最後goods表內容為:

 

  找出剩餘數量最多的的水果是:

   注意:select語句的order by子句對檢索出的資料進行排序,這個字句必須出現在select語句中的最後一條子句。至於為什麼,這個我暫時還不知道哈。。。

 

5、過濾資料

  select語句中,資料可以根據where子句指定的過濾條件進行過濾,where子句在表名(from子句)之後給出,比如,select id, name from goods where id = 2,該語句只顯示id為2記錄的id和name。注意:如果同時使用where和order by子句,應該讓order by子句在where之後,否則會產生錯誤。

  where子句操作符如下:

  • =   等於
  • <> 不等於
  • != 不等於
  • <  小於
  • >  大於
  • >= 大於等於
  • between  在指定的兩個值之間(比如select * from goods where id between 1 and 2)

  我們在建立表時,可以指定其中的列是否可以不包含值,在一個列不包含值時,其值為空白值null,select語句有一個特殊的where子句,用來檢測具有null值的列,比如:select * from goods where num is null 就把num是空值得記錄給列印出來。

 

 

6、資料過濾

  常用的select子句在過濾資料時使用的是單一的條件,為了進行更強的過濾控制,可以下多個where子句,這些子句有兩種方式:以and子句和or子句的方式使用。

  • select * from goods where id = 2 and num > 10 檢索id為2並且num大於10的記錄
  • select * from goods where id = 3 or num >  15 檢索id為3並且num大於15的記錄

  假如多個and和or語句放在一起,則優先處理and操作符,此時可以使用圓括弧來改變其優先順序。圓括弧還可以指定in操作符的條件範圍,範圍中的每個條件都可以進行匹配。

  where子句中的not操作符只有否定它之後的任何條件這一作用。

 

7、用萬用字元進行過濾

  使用like操作符進行通配搜尋,以便對資料進行複雜過濾。

百分比符號(%)操作符 搜尋中,%表示任何字元出現任意次數。

底線(_)萬用字元,它用來匹配單個字元而不是多個字元。

萬用字元很有用,但這是有代價的,萬用字元的搜尋處理一般比其他搜尋花費時間長,這裡有一些技巧:

  • 不要過度使用萬用字元,如果其他動作符能達到同樣的目的,就應該使用其他動作符。
  • 在確實需要使用萬用字元時,除非絕對必要,否則不要把它們用在搜尋模式的開始處,把萬用字元放在開始處,搜尋起來是最慢的。
  • 注意萬用字元位置,位置不對可能不會返回想要的結果。

 

 8、Regex

  Regex的作用是匹配文本,將一個模式(Regex)與一個文本串進行比較。mysql的where子句對Regex提供了初步支援,允許你指定Regex ,過濾select檢索出的資料。先看一下表記錄:

  • select * from goods where name regexp '香' order by num desc 檢索出name中有'香'的所有記錄
  • select * from goods where name regexp '香.' 檢索出name中有'香'的所有記錄,'.'表示匹配任意一個字元
  • select * from goods where name regexp '香|瓜' 檢索處name中有'香'或者'瓜'的所有記錄

 

  如果記錄匹配Regex,則就會被檢索出來,使用下面Regex重複元字元可以進行更強的控制。

  • *   匹配0個或多個
  • +   匹配1個或多個(等於{1,})
  • ?   匹配0個或1個(等於{0,1})
  • {n} 指定書目的匹配
  • {n,} 不少於指定資料的匹配
  • {n,m} 匹配指定資料的範圍(m不超過255)
  • ^  文本的開始
  • $  文本的結束
  • [[:<:]]  詞的開始
  • [[:>:]]  詞的結束

  注意:regexp和like作用類似,regexp和like不同之處在於,like匹配整個串而regexp匹配子串,利用定位器,通過'^'開始每個運算式,用'$'結束每個運算式,可以使regexp的作用和like一樣。

 

9、建立計算欄位

  拼接將值串連到一起構成單個值,在mysql的select語句中,可使用concat()函數來拼接兩個列。

  從中我們可以看到新的計算資料行的名字只是一個值,我們可以使用別名來使得它更有意義。同時也可以對檢索出的資料進行算術運算,加減乘除都是支援的。

 

 

10、使用資料處理函數

 

常用的文本處理函數

函數 說明
left() 返回串左邊的字
length() 返回串的長度
locate() 找出串的一個子串
lower() 將串轉換為小寫
ltrim() 去掉串左邊的空格
right() 返回串右邊的字元
rtrim() 返回串右邊的字元
soundex() 返回串的soundex值
substring() 返回子串的字元
upper() 將串轉換為大寫

 

11、摘要資料

   經常需要摘要資料而不是把它們檢索出來,為此mysql提供了專門的函數,以便分析和報表產生。常用的例子有:確定表中行數、擷取表中行組的和、找出表列的最大值(最小值或平均值)。聚集合函式運行在行組上,計算和放回單個值得函數,mysql提供了5個聚集合函式,這些函數一般比自己的用戶端應用程式中計算要快得多。

  • AVG()   返回某列的平均值
  • COUNT() 返回某列的行數
  • MAX()   返回某列的最大值
  • MIN()   返回某列的最小值
  • SUM()   返回某列之和

   使用關鍵字distinct使得只選擇不同num的記錄來參與計算。

 

12、分組資料

  sql聚集合函式可以用來摘要資料,這使得我們能夠對行計數、計算平均值、擷取最大最小值不用檢索所有資料。而建立分組允許把資料分為多個邏輯組,以便對每個組進行聚集計算。其涉及到group by子句和having子句。

 

 在使用group by子句前,需要知道一些重要的規定:

  • group by子句可以包含任意數目的列,這使得能對分組進行嵌套,為資料分組提供更細緻的控制。
  • 如果在group by子句中嵌套了分組,資料將在最後規定的分組上匯總。換句話說,在建立分組時,指定的所有列都一起計算。
  • group by子句中列出的每個列都必須是檢索列或有效運算式,但不能是聚集合函式。 
  • 如果分組列中具有null值,則將null作為一個分組返回,如果有多個null值,它們將分為一組。
  • group by子句必須出現在where子句後,order by子句前。 

  除了能用group by分組資料外,mysql還允許過濾分組,規定包括哪些分組,排除哪些分組。過濾分組需使用having子句,因為where過濾的是行而不是分組。注意:where是在資料分組前進行過濾,having是在資料分組後進行過濾。

  group by和order by經常完成相同的工作,但是二者是非常不同的:

order by group by
排序產生的輸出 分組行,但輸出可能不是分組的順序
任意列都可以使用(甚至非選擇的列) 只可能使用選擇列或運算式列,而且必須使用每個挑選清單達式
不一定需要 如果與聚集合函式一起使用列(或運算式),則必須使用

  下面是select語句中子句的順序,以在select中使用時必須遵循的次序為順序。

子句 說明 是否必須使用
select 要返回的列或運算式
from 從中檢索資料的表 僅再從表選擇資料時使用
where 行級過濾
group by 分組說明 僅在按組計算聚集時使用
having 組級過濾
order by 輸出排序次序
limit 要檢索的行數

 

13、使用子查詢

  什麼是子查詢呢?子查詢就是嵌套在其他查詢中的查詢, 在where子句中使用子查詢,應該保證select語句具有和where子句中相同數目的列,通常,子查詢將返回單個列並且與單個列匹配。

 

14、連接表

  外鍵為某一個表中的一列,它包含另一個表的主索引值,定義了兩個表的關係。如果資料存放區在多個表中,使用串連可用單條select語句檢索出需要的資料。應該保證所有的連連接都有where子句,否則mysql將返回比想要的多的多的資料,因為此時檢索出的行數目是第一個表行數乘以第二個表行數。

  連接是SQL中最重要最強大的特性。關係表的設計就是要保證把資訊分解成多個表,一類資料一個表。各表通過某些常用的值(即關係設計中的關係relational)互相關聯。

SELECT vend_name, prod_name, prod_price FROM vecdors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name; 建立串連表

      使用WHERE子句作為過濾條件,它只包含匹配給定給定條件的行。沒有WHERE子句,第一個表中的每個行將於第二個表中的每個行配對,而不管它們邏輯上是否可以配對在一起。SQL對一條SELECT語句中可以連接的表的數目沒有限制。

      基於兩個表之間相等測試的聯結稱為內部聯結。其實,對於這種連接可以使用稍微不同的文法來明確指定連接的類型,下面的SELECT語句返回與前面例子完全相同的資料。

SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;

 

15、建立進階連接

  除了可以給列名和計算欄位其別名外,還可以給表起別名。

  除了使用內部聯結(或稱為等值聯結)的簡單連結,還可以使用自連接、自然連接、外部連結。

  • 自連接:可以在單條SELECT語句中不止一次引用相同的表。
  • 自然連接:無論何時對錶進行連接,應該至少有一個列出現在不止一個表中(被連接的列),標準的連接(內部聯結)返回所有資料,甚至相同的列多次出現。自然連接排除多次出現,使每個列只返回一次。
  • 外部連接:許多連接將一個表中的行與另一個表中的行相關聯,但有時候會需要包含沒有關聯線的那些行。

 

  • select * from persion as haha; 使用表別名
  • select proid_id, prod_name FROM products WHERE vend_id = (SELECT vend_id FROM products WHERE prod_id = ‘DTNTR’); 找到生產ID為DTNTR的物品的供應商,然後找到這個供應商生產的其他物品。這種方式使用了子查詢,下面是使用自連接的操作:
  • SELECT p1.prod_id, p1.prod_name FROM products AS p1, products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = ‘DTNTR’;
  • SELECT customers.cust_id, orders.order_num FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id; 這是內部聯結方式,下面是外部連接方式
  • SELECT customers.cust_id, orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;

 

16、組合查詢

  利用union操作符和組合多條SQL查詢,讓給出的多條select語句結果組合成單個結果集。注意,union必須有2條或者2條以上的select語句組成,union中每個查詢必須包含相同的列、運算式或聚集合函式(不過每個列不需要以相同的次序列出)。union會自動去除重複的行,這個是預設的行為,如果不想這樣,使用union all而不是使用union。

  如何對union語句的輸出進行排序呢?使用order by子句時,必須放在union最後一條select語句之後,對於結果集,只能有一種定序,所以不允許使用功能多條order by子句。

 

17、插入資料

  插入語句insert一般會有產生輸出,一般只會列印影響的行數。insert時如果不提供列名,則必須給每個表列提供一個值,如果提供列名,則必須對每個列出的列給出一個值,否則報錯。

插入一個完整的行:

 

插入多個行:

 

18、更新和刪除資料

  分別使用update語句和delete語句來進行更新和刪除資料操作。先把goods表中資料清除掉一部分,goods表資料如下:

  • update goods set num = 1 where name = '蘋果'; 此時對應蘋果的num變為1
  • delete from goods where num = 7; 刪除num為7的記錄,也就是name為橘子的記錄。

注意,這裡有一些使用update和delete語句的一些注意事項:

  • 除非確實打算更新和刪除每一行,否則絕對不要使用不帶where子句的update或delete語句。
  • 保證每個表都有主鍵,儘可能像where子句那樣使用它。
  • 在對update或delete語句使用where子句前,應該先用select進行測試,保證過濾的是正確的記錄,以防止編寫的where子句不正確。
  • mysql沒有撤銷功能,應小心使用update或delete功能。

 

19、建立和操縱表

   利用create table建立表,必須給出表的名字,在關鍵字create table只有給出;表列的名字和定義,用逗號隔開。

create table vendors (    vend_id int not null auto_increment,    vend_name char(50) not null,    vend_address char(50) null default '*',    vend_city char(40) null,    primary key (vend_id)) engine=InnoDB;

  這條語句建立一個vendors表,vend_id和vend_name是必須的,指定為not null,其他的為非必須的,指定為null,null為預設設定。auto_increment關鍵字告訴mysql,本列每當增加一行時自動增量,可以保證該列值唯一。每個表只允許有一個auto_increment列,而且它必須被索引(如,通過使它為主鍵)。default為預設值。

  注意,主鍵必須唯一,表中的每個行必須具有唯一的主鍵,如果主鍵使用單個列,則它的值必須唯一;如果使用多個列,則這些列的組合必須唯一。外鍵不能垮跨越引擎。mysql內部打包了多種引擎,以下幾個是需要知道的引擎:

  • InnoDB是一個可靠的交易處理引擎,它不支援全文本搜尋。
  • MEMORY在功能等同於MyISAM,但由於資料存放區在記憶體,所有速度很快(特別適合用暫存資料表)。
  • MyISAMysql是一個效能極高的引擎,它支援全文本搜尋,但不支援交易處理。

  使用alter table語句更新表結構。

 

  刪除表(不是其內容,而是整個表)使用drop語句即可。drop table table_name; 這條語句刪除table_name表,只要它存在,注意,刪除表時沒有確認,也不能撤銷。

  使用rename table語句重新命名表。

 

20、視圖

  視圖是虛擬表,與包含資料的表不一樣,視圖只包含使用時動態檢索資料的查詢。視圖僅僅是用來查看儲存在別處資料的一種設施,視圖本身不包含資料,因此它們返回的資料是從其他表中檢索出來的。視圖提供了一種MySQL的SELECT語句層次的封裝,可用來簡化資料處理以及重新格式化基礎資料或保護基礎資料。

使用視圖的常見應用:

  • 重用SQL語句
  • 簡化複雜的SQL操作,在編寫查詢後,可以方便地重用它而不必知道具體的查詢細節
  • 使用表的組成部分而不是整個表
  • 保護資料,授予客戶表的特定部分存取權限而不是全部
  • 更改資料格式和表示,視圖可返回與底層表的表示和格式不同的資料

  使用視圖簡化複雜的連接,視圖使用create view語句來建立,使用show create view viewname來查看建立視圖的語句;用drop刪除視圖,文法為drop view viewname。

 

 

  通常,視圖是可更新的(可以對它們使用insert、update和delete),更新一個視圖將更新其基表,因為視圖本身是沒有任何資料的。但是,並非所有的視圖是可更新的,如果mysql不能正確的確定被更新的基資料,則不能被更新,即如果有一下操作,視圖不允許更新:分組、連接、子查詢、並、聚集合函式、distinct等。

參考

  1、MySQL必知必會 

  2、高效能MySQL 

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.