MySQL 必知必會讀書筆記 (1)

想更一進步的支持我,請掃描下方的二維碼,你懂的~
圖片描述mysql

基本術語

  • 數據庫 database: 一個以某種有組織的方式存儲的數據集合。理解數據庫最簡單的方法是想象成一個文件櫃。
  • 表 table:某種特定類型數據的結構化清單。表能夠保存顧客清單、產品目錄或者其餘信息清單。
    特定類型 表示存儲在表中的數據是一種類型的數據或一個清單,功能專注。決不該該把兩種類型的表混合在一塊兒。
  • 模式 schema:關於數據庫和表的佈局及特性的信息。好比表存儲什麼樣的數據,數據如何分解,各部分信息如何命名等等。
  • 列 column:表由列組成。列是表中的一個字段。全部表都是由一個或多個列組成的。
  • 行 row:表中的一個記錄。
  • 主鍵 primary key:一列(或者一組列)其值可以惟一區分表中的每一個行
    表中任意列均可以做爲主鍵,只要知足以下條件:

    • 任意兩行都不具備相同的主鍵值
    • 每一行都必須有一個主鍵值(即不準是NULL)
  • SQL 結構化查詢語言

mysql 命令行

進入

mysql

或者git

mysql -u username -p

而後輸入密碼正則表達式

use

建立庫:算法

create database dbname;

刪除庫sql

drop database dbname;

選擇數據庫,使用use關鍵字;如數據庫

use kvseg;

show

  • 顯示可用的數據庫列表
SHOW DATABASES

返回可用的數據庫的一個列表。segmentfault

  • 顯示一個數據庫內的表的列表,使用
SHOW TABLES

clipboard.png

  • 顯示錶列
SHOW COLUMNS FROM customers

clipboard.png

導入導出

  • 從Linux系統導入
    先在mysql建立一個數據表,選擇進去,而後導入外部數據庫進入表。
create database dbname;
use dbname;
source dir

dir是.sql文件的路徑。若是不清楚路徑能夠輸入pwd指令查看當前路徑安全

clipboard.png

  • 從mysql導出到系統
mysqldump -u root -p news > news.sql

檢索數據

select語句

select 子句順序svg

子句    說明                     
select    要返回的列或表達式        
from      從中檢索數據的表          
where     行級過濾
group by  分組說明
having    組級過濾
order by  輸出排序順序
limit     要檢索的行數

爲了使用select檢索表數據,必須至少給兩條信息 -- 想選擇什麼(哪一列),以及從什麼地方(數據庫)選擇函數

  • 檢索單個列
    好比檢索cust_name字段(列),若是沒有明確排序查詢結果,則獲得未排序的數據。
select cust_name from customers;

clipboard.png

  • 檢索多個列
    好比從customers 檢索cust_id,cust_name兩列;
select cust_id,cust_name from customers;

clipboard.png

  • 檢索全部列
select * from products;
  • 檢索不一樣的行(去重)
select distinct vend_id from products;

clipboard.png

  • 限制結果
    select 返回匹配的全部行,也能夠返回第一行或者前幾行,可以使用LIMIT關鍵字
    好比返回很少於5行;
select prod_name from products limit 5;

好比從行5開始的5行

select prod_name from products limit 55;

clipboard.png


order by

排序檢索數據
使用select語句的order by 子句,根據須要排序檢索出數據。

  • 按單個列排序
select *
from products
order by 列名(keyword for sorting)

clipboard.png
order by 子句取一個或多個列的名字,據此對輸出進行排序。

  • 按多個列排序

clipboard.png

按照多個列排序時,排序徹底按照所規定的順序進行。換句話說,對於上述中的輸出,僅僅在多個行具備相同的segk(第一關鍵字)值時纔對按照randnum(第二關鍵字)排序。

  • 升序?降序?
    默認是升序,降序是DESC

clipboard.png

還能夠實現按照第一個關鍵字降序,第二個關鍵字升序

clipboard.png
DESC只用到直接位於其前面的列明。若是想在多個列上進行降序排列,必須對每一個列指定DESC關鍵字。

IN A CONCLUSION: order by子句必須是select語句的最後一條子句。

where

op descriptions
= 等於
<> 不等於
!= 不等於
< / > 小於 / 大於
<= / >= 小於等於/ 大於等於
Between 在指定的兩個值之間
is NULL 空值檢查

  • 過濾數據
    使用where過濾數據:從大量數據中檢索出根據搜索條件/過濾條件過濾出來的數據。
mysqlselect * from products
 where prod_price = 55;

clipboard.png

  • 過濾不匹配
mysqlselect * from products
 where prod_price <> 55;
  • 範圍檢測
mysqlselect * from products
 where prod_price between 30 and 60;

clipboard.png

  • 空值
mysqlselect * from products
 where prod_price is Null;
  • 多條件,組合 and / or
    > 組合where子句(使用操做符and/or):更高級的search criteria. MYsql 容許給出多個WHERE子句。 這些子句以兩種方式使用:Not and In。

clipboard.png


計算次序問題: 使用圓括號明確的分組相應的操做符。
好比選擇segk 爲118 或者 120的行,而且隨機數小於等於2;
由於sql對and進行優先級處理。

任什麼時候候後使用具備and 和 or操做符的where子句,都應該使用圓括號明確的分組操做符,不要過度依賴默認的計算次序。使用圓括號來消除歧義。

  • IN操做符
    IN操做符用來指定範圍。(等同於or)

clipboard.png

  • NOT操做符
    否認它以後所跟的任何條件

clipboard.png


like

正則表達式 regexp

在where 條件中使用REGEXP關鍵字。

  • 基本字符匹配
    檢索列prod_name 包含文本1000的全部行:
    clipboard.png

  • 進行OR匹配
    至關於:或操做 「|」

clipboard.png

  • 匹配幾個字符之一
    只想匹配特定的字符。 能夠經過指定一組用[]括起來的字符來完成。
    clipboard.png
    [456]定義了一組字符,他的意思是匹配4或5或6. []是另外一種形式的OR語句。[456][4|5|6]的縮寫。
  • 匹配範圍
    [1-3] a-z都是合法的範圍、
    clipboard.png
  • 匹配特殊字符
    正則表達式語言由特殊含義的特殊字符構成。

    . 在正則表達式中表示匹配任何一個字符

    好比匹配prod_name中包括on字符串的行:
    clipboard.png

    那如何匹配.,[],|,-

    爲了匹配特殊字符,必須用\\爲前導。 好比\\.表示查找·

  • 匹配字符類

    clipboard.png

  • 匹配多個實例

    clipboard.png

    clipboard.png

    再好比 匹配連在一塊兒的4位數字:

    sticks? : s後的使s可選,由於匹配它前面緊跟的任何字符的0次或者1次出現。

    clipboard.png

    [:digit:]匹配任意數字,於是它爲數字的一個集合。{4}確切地要求它前面的字符出現4次。
    因此[:digit:]{4}匹配連在一塊兒的任意4位數字。
    clipboard.png

  • 定位符
    目前爲止全部例子都是匹配一個串中任意爲止的文本。爲了匹配特定爲止的文本,須要使用定位符。

    clipboard.png

    clipboard.png


concat

  • 拼接字段
    存儲在數據庫表中的數據通常不是應用程序所須要的格式。咱們須要直接從數據庫中檢索出轉換、計算或格式化過的數據;而不是檢索出數據,而後再在客戶機應用程序或報告程序中從新格式化。

    計算字段(字段 = 列,不過數據庫列通常稱爲列,而字段一般用於計算字段中)並不實際存在於數據庫表中,計算字段是運行時在select語句內建立的。

    拼接 concatenate 將值聯結到一塊兒構成單個值
    在MySQL的select語句中,可以使用Concat()函數來拼接兩個列。

    如建立由兩列組成的標題:生成一個供應商報表,須要在供應商的名字中按照name(location)這樣的格式列出供應商的位置。此報表須要單個值,而表中數據存儲的兩個列vend_namevend_country中。還須要用括號將vend_country括起來。

    clipboard.png

    新建立的列用AS賦一個別名

    clipboard.png

  • 去除空白
    Ltrim() RTrim() Trim()
  • 執行算術計算
    好比物品單單表存儲物品的價格和數量,可是不須要存儲每一個物品的總價格(用價格乘以數量便可)。 爲打印發票,須要物品的總價格。即須要增長一列,根據已有的列計算出來。

clipboard.png

文本函數

left()  串左邊字符
length() 串長度
locate() 找出串的一個子串
lower() 轉爲小寫
ltrim() 去掉左邊空格
right() 返回串右邊字符
rtrim() 去掉串右邊空格
soundex() 返回字符串soundex值
upper() 大寫

將選擇的文本轉換成大寫

select Upper(vend_name)
from vendors;

clipboard.png

Soundex()函數:將任何文本傳轉換爲描述其語音表示的字母數字模式的算法。(語音匹配?對發音比較而不是對字幕比較)

clipboard.png

日期函數

日期和時間函數
adddate() 增長一個日期-天或周
addtime() 增長一個時間
curdate() 返回當前日期
curtime() 返回當前時間
date() 返回日期時間的日期部分
datediff() 計算兩個日期差
date_add() 高度靈活的日期運算函數
date_format() 返回一個格式化的日期或時間串
day() 返回一個日期的天數部分
dayofweek() 對於一個日期,返回對應的星期幾
hour()
minute()
month()
now() 當前日期和時間
second()
time() 當前日期時間的時間部分
year()

通常,應用程序不使用用來存儲日期和時間的格式,所以日期和時間函數老是被用來讀取,統計和處理這些值。

MySQL的日期格式:yyyy-mm-dd。 好比 2005-09-01

clipboard.png

可是這樣的where order_date = '2005-09-01'不可靠。由於order_date存儲的數據類型是datatime. 這種類型存儲日期及時間值。好比存儲的order_date值爲2005-09-01 11:30:05,則where order_date = '2005-09-01'就會匹配失敗。

clipboard.png

因此最安全的方法是Date()函數,Date(order_date)指示MySQL提取列的日期部分。

select cust_id, order_num
from orders
where Date(order_date) = '2005-09-01';

再好比想要檢索出2005年9月下的全部訂單。

select cust_id, order_num
from orders
where Year(order_date) = 2005 and Month(order_date) = 9;

彙集函數

咱們常常須要彙總函數,而不是把它們實際檢索出來。
這種類型的檢索例子:
1. 肯定表中行數
2. 得到表中行組的和
3. 找出表列(or 全部行某些特定的行)的最大值,最小值和平均值

彙集函數(aggregate function) 運行在行組上,計算和返回單個值的函數。

AVG()     返回某列的平均值
COUNT()   返回某列的行數
MAX()     返回某列的最大值
MIN()     返回某列的最小值
SUM()     返回某列值的和
  • 求某一列的平均值
select avg(prod_price) as avg_price
from products;

clipboard.png
- 計數
使用count(*)對錶中行的數目進行計數(whether null or not)

clipboard.png

clipboard.png

使用count(column)對特定列具備值的行進行計數,忽略null

clipboard.png

  • 求和
    使用sum()返回指定列值的和

clipboard.png

group

目前爲止全部計算都是在表的全部數據或匹配特定的where子句的數據上進行的。
group by 子句指示MySQL分組數據,而後對每一個組進行彙集(計算),而不是整個結果集進行計算。

where 和 have 的區別:
where在分組前過濾,having在分組後過濾

  • 數據分組
1.group by 能夠包含任意數目的列
2.group by 中每一個列都必須是檢索列或有效的表達式(但不能使彙集函數)
3.除彙集函數外,select語句中的每一個列都必須在group by子句中出現
4.若是分組列有Null值,Null將做爲一個分組返回
5.group by 子句必須出如今where子句以後, order by 以前

首先看products 這個表
clipboard.png
主鍵是prod_id 產品id,每個產品都對應一個供應商ID,產品名,產品價格,以及簡介。
若是咱們查看該產品表的供應商信息:
clipboard.png
若是想進一步獲知每一個供應商提供多少種產品,就應該對供應商進行分組: 好比供應商1001提供3種產品,供應商1002提供2種產品,供應商1003提供7種產品,供應商1005提供2種產品。

分組:

mysqlselect vend_id, count(*) as num_prods
from products
group by vend_id;
  • 過濾分組
    除了能用group by 分組數據外,還容許過濾分組,規定包括哪些分組,排除哪些分組。例如:可能想要列出至少有兩個訂單的全部顧客。爲了得出這種數據,必須給予完整的分組,而不是個別的行進行過濾。

    having 很是類where, where能作的having都能作,惟一差異是where過濾行,having過濾分組。

    下面列出訂單表orders的狀況,每一個表的主鍵是訂單編號,每行還有訂單日期和顧客id.
    clipboard.png
    若是想要統計出訂單數目超過2的顧客id
    clipboard.png
    增長的having子句,過濾了count(*)>=2那些分組。

    wherehaving組合使用,能夠進行更強功能的操做。 如:列出提供了2個以上,價格爲10以上的產品的供應商:

    clipboard.png
    先用wehre子句過濾了全部價格至少爲10的行,而後按照vend_id分組數據,having子句過濾計數爲2或2以上的分組。

  • 分組和排序
    clipboard.png

子查詢

能夠涉及數據庫多個表,檢索數據的語句。

  • 子查詢用作過濾 in
    訂單存儲在兩個表(orders,orderitems)中。
    clipboard.png
    客戶信息存儲在customers表中
    clipboard.png

    若是須要列出訂購TNT2物品的全部客戶:
    須要包含以下步驟:
    step 1. 檢索包含物品TNT2的全部訂單的編號。
    step 2. 檢索具備前一步驟列出的訂單編號的全部客戶ID
    step 3. 檢索前一步驟所返回的全部客戶ID的信息
    能夠把一條select語句返回的結果用於另外一條select語句的where子句 -- 也可使用子查詢來把3個查詢組合成一條語句。

    select * from customers 
    where cust_id in (select cust_id from orders 
    where order_num in (select order_num from orderitems where prod_id = 'TNT2'));

    clipboard.png

  • 做爲計算字段使用子查詢
    若是須要顯示customers表中每一個客戶的訂單總數。 這須要使用customers,orders兩個表。
    clipboard.png
    使用select count(*) 對錶中的行進行計數,並經過where 子句過濾行(經過過濾id)

    orders是一個計算字段,它是由圓括號中的子查詢創建的。該子查詢對檢索出的每一個客戶執行一次。在這個例子中,該子查詢執行了5次,由於檢索出了5個客戶。


聯接表(join)

外鍵 外鍵爲某個表中的一列,它包含另外一個表的主鍵值,定義了兩個表之間的關係。
可伸縮性: 可以適應不斷增長的工做量而不失敗。關係型數據庫比非關係型數據庫的可伸縮性好。
聯結: 聯結是一種機制,用來在一條select語句中關聯表,所以稱之爲聯結。使用特殊的語法,能夠鏈接多個表返回一組輸出,聯結在運行時關聯表中正確的行。
聯結的引入是爲了解決 爲了帶來關係數據更大的可伸縮性而分解數據爲多個表,可是帶來的代價:數據分散存儲到多個表,怎麼用單條select語句檢索出數據。

兩個表: 供應商表vendors, 產品表 products

clipboard.png

  • 建立(等值)聯結

    clipboard.png
    固然也能夠按照主鍵,外鍵關係聯結多個表。可是出於性能的考慮,這種處理多是很是耗資源的。聯接的表越多,性能降低越厲害。

    select 嵌套語句實現的返回訂購產品TNT2的客戶列表的解決方法,可使用級聯:
    對比:

    select * from customers 
    where cust_id in (select cust_id from orders 
    where order_num in (select order_num from orderitems where prod_id = 'TNT2'));

    VS

    clipboard.png

clipboard.png

  • 使用不一樣類型的聯結

    clipboard.png

    • 自聯接
      > 查詢product_id爲DTNTR(products表)的供應商,這個供應商生產的其餘物品(vendors表)

    有兩種方法,一種是使用嵌套,另外一種是使用自聯接。
    嵌套:
    clipboard.png
    自聯接(同一個表別名爲p1,p2);
    clipboard.png

    > 有時候,處理聯結要比查理子查詢快的多。

    • 外部聯結
      聯結包含了哪些在相關表中沒有關聯的行。這種類型的鏈接稱爲外部連接。
      內部鏈接:

    clipboard.png

    使用outer join來指定聯結的類型。而不是在where子句。
    clipboard.png

  • 使用帶彙集函數的鏈接
    檢索全部客戶及每一個客戶所下的訂單數。

clipboard.png

  • 使用聯結和聯結條件
    > 1. 注意所使用的聯結類型。通常使用內部聯結,可是使用外部聯結也是有效的.
    > 2. 保證使用正確的聯結條件,不然將返回不正確的數據。
    > 3. 應該老是提供聯結條件,不然會得出笛卡爾積。
    > 4. 在一個聯結中能夠包含多個表,甚至對每一個聯結能夠採用不一樣的聯結類型。雖然這樣作是合法的,通常也頗有用,但應該在一塊兒測試他們以前,分別測試每一個聯結。排除故障更簡單。

組合查詢

使用Union操做符將多條select語句組合成一個結果集,並將結果做爲單個查詢結果集返回。這些組合查詢稱爲複合查詢compound query

有兩種狀況,須要使用組合查詢:
1. 在單個查詢中從不一樣的表返回相似結構的數據;

  1. 在單個表執行多個查詢,按單個查詢返回數據。
  • Union
    假如須要價格小於等於5的全部物品的信息,還想包括供應商1001,1002生產的全部物品(不考慮價格)

使用where:
clipboard.png
使用union:
clipboard.png

union 從查詢結果集中自動去除了重複的。

全文搜索

MyISAM 支持全文本搜索

InnoDB 不支持全文本搜索

通配符和正則表達式的缺陷:

  • 性能
    通配符和正則表達式匹配一般要求MySQL嘗試匹配表中全部行(並且這些搜索極少使用表索引)。所以,因爲被搜索行數不斷增長,這些搜索可能很是耗時。

  • 明確控制
    使用通配符和正則表達式匹配,很難(並且並不老是能)明確地控制匹配什麼和不匹配什麼。

  • 智能化的結果
    通配符和正則表達式匹配並不是是智能化的選擇結果。
    一個特殊詞的搜索將會返回包含該詞的全部行,而不區分包含單個匹配的行和包含多個匹配的行。

爲了進行全文本搜索,必須索引被搜索的列,並且要隨着數據的改變不斷地從新索引。在對錶列進行適當設計後,MySQL會自動進行全部的索引和從新索引。

在索引以後,select可與match()agianst()一塊兒使用以執行搜索。
match()指定被搜索的列,against()指定要使用的搜索表達式。

啓用全文本搜索支持

建立表時啓用全文本搜索。接受fulltext子句,給出被索引列的

CREATE TABLE productnotes(
 note_id int NOT NULL AUT_INCREMENT,
 note_text text NULL,
 FULLTEXT(note_text)

create table 接受 full text子句。

進行全文搜索

SELECT note_text
 FROM tb_name
 WHERE Match(note_text) Against(‘rabbit’)

clipboard.png

全文搜索(compared to like and regexp) 一個重要部分就是對結果排序。具備較高優先級的列先返回(由於這些行極可能就是你真正想要的行):好比先返回第三個詞rabbit的行,再返回第20個詞rabbit的行。
一個對比:

clipboard.png
like是按照出現順序,先返回第20個詞rabbit的行,再返回第三個詞rabbit的行。

查詢擴展

放寬所返回的全文本搜索結果的範圍。
好比:
想找到全部提到anvils的註釋,只有一個註釋包含了詞anvils,可是你還想找出可能與你的搜索有關的全部其餘行,即便不包含詞anvils.

在使用查詢擴展時,mysql對數據和索引兩遍掃描完成。利用查詢擴展,能找出可能相關的結果,即便它們並不精確包含所查找的詞。

  • 首先,進行一個基本的全文本搜索,找出與搜索條件匹配的全部行;

  • 其次,MySQL檢查這些匹配行並選擇全部有用的詞。

  • 再其次,MySQL再次進行全文本搜索們此次不只使用原來的條件,並且還使用全部有用的詞。

clipboard.png

clipboard.png

clipboard.png

布爾文本搜索

以布爾方式,能夠提供關於以下內容的細節:

  • 要匹配的詞;
  • 要排斥的詞(即便它包含其餘指定的詞,可是若是它包括了排斥的詞,也不返回該行);
  • 排列提示(指定某些詞比其餘詞更重要,更重要的詞等級更高);
  • 表達式分組;

  • 另一些內容

SELECT note_text
 FROM productontes
 WHERE Match(note_text) Against(‘heavy’ IN BOOLEAN MODE)

clipboard.png

clipboard.png

排除了任何包含rope*的行。
例子:
clipboard.png

clipboard.png

clipboard.png

搜索匹配safe和combination。下降後者的等級。

Insert

插入行到數據庫表。
能夠

  • 插入完整的行
  • 插入行的一部分
  • 插入多行
  • 插入某些查詢的結果
insert into customers ( cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country,
cust_contact,
cust_email)
values('Pep E. LaPew',
'100 Main Streat',
'Los Angels',
'CA',
'90046',
'USA',
null,
null
);

安全的insert語句,在表名後的括號裏明確地給出列名。
當插入多行數據時候,用單條insert語句處理多個插入比使用多條insert語句快。

還能夠插入檢索出的數據。insert select :假如想從另外一個表中合併客戶列表到你的customers表,不須要每次讀取一行,而後再用insert插入,能夠直接 insert select.
形式:

mysqlinsert into TableName(ColomnName1,...)
select (ColomnName1,...)
from AnotherTableName;

不要求列明匹配,使用的是列的位置。


update

更新特定行

mysqlupdate TABLENAME
set ColomnName1 = NewValue,
ColomnName2 = NewValue
where ... (過濾條件)

更新全部行

若是上面例子,沒有where過濾條件,就是更新全部行。


delete

刪除某個列的值

設置爲null(if表定義容許爲null)

mysqlupdate TABLENAME
set ColomnName1 = Null,
where ... (過濾條件)

刪除特定的行

mysqldelete from TABLENAME
where ... (過濾條件)

刪除全部行

若是上面例子,沒有where過濾條件,就是刪除全部行。

Note: delete 語句是從表中刪除行,甚至是刪除表中全部行。可是delete不刪除表自己。
Note: 更快的刪除,若是想從表中刪除全部行,不要使用delete, 可以使用truncate table語句(完成相同功能,可是速度更快,其實是刪除原來的表並從新建立一個表,而非逐行刪除表的數據)。


create

mysqlCREATE TABLE customers
(
  cust_id      int       NOT NULL AUTO_INCREMENT,
  cust_name    char(50)  NOT NULL ,
  cust_address char(50)  NULL ,
  cust_city    char(50)  NULL ,
  cust_state   char(5)   NULL ,
  cust_zip     char(10)  NULL ,
  cust_country char(50)  NULL ,
  cust_contact char(50)  NULL ,
  cust_email   char(255) NULL ,
  PRIMARY KEY (cust_id)
) ENGINE=InnoDB;

主鍵只能使用不容許NULL值的列。容許NULL值的列不能做爲惟一標識。

每一個表只容許一個AUTO_INCREMENT列,並且它必須被索引。

MySQL內部具備各自不一樣的功能和特性的多種引擎,爲不一樣的任務選擇正確的引擎能得到良好的功能和靈活性。

  • InnoDB 是一個可靠的事務處理引擎,它不支持全文本搜索;

  • Memory 在功能等同於MyISAM, 但因爲數據存儲在內存(而非磁盤)中,速度很快(特別適合於臨時表);

  • MyISAM 是一個性能極高的引擎,它支持全文本搜索,但不支持事務處理。


alter

更新表定義,alter table.

mysqlalter table vendors
add vend_phone char(20);

drop

刪除表,而非內容

mysqldrop table tableName;
相關文章
相關標籤/搜索