想更一進步的支持我,請掃描下方的二維碼,你懂的~
mysql
數據集合
。理解數據庫最簡單的方法是想象成一個文件櫃。特定類型
數據的結構化清單
。表能夠保存顧客清單、產品目錄或者其餘信息清單。特定類型
表示存儲在表中的數據是一種類型的數據或一個清單,功能專注。決不該該把兩種類型的表混合在一塊兒。mysql
或者git
mysql -u username -p
而後輸入密碼正則表達式
建立庫:算法
create database dbname;
刪除庫sql
drop database dbname;
選擇數據庫,使用use
關鍵字;如數據庫
use kvseg;
SHOW DATABASES
返回可用的數據庫的一個列表。segmentfault
SHOW TABLES
SHOW COLUMNS FROM customers
create database dbname; use dbname; source dir
dir是.sql文件的路徑。若是不清楚路徑能夠輸入pwd
指令查看當前路徑安全
mysqldump -u root -p news > news.sql
select 子句順序svg
子句 說明 select 要返回的列或表達式 from 從中檢索數據的表 where 行級過濾 group by 分組說明 having 組級過濾 order by 輸出排序順序 limit 要檢索的行數
爲了使用select檢索表數據,必須至少給兩條信息 -- 想選擇什麼(哪一列),以及從什麼地方(數據庫)選擇函數
select cust_name from customers;
select cust_id,cust_name from customers;
select * from products;
select distinct vend_id from products;
LIMIT
關鍵字select prod_name from products limit 5;
好比從行5開始的5行
select prod_name from products limit 55;
排序檢索數據
使用select語句的order by 子句,根據須要排序檢索出數據。
select * from products order by 列名(keyword for sorting)
order by 子句取一個或多個列的名字,據此對輸出進行排序。
按照多個列排序時,排序徹底按照所規定的順序進行。換句話說,對於上述中的輸出,僅僅在多個行具備相同的segk(第一關鍵字)值時纔對按照randnum(第二關鍵字)排序。
DESC
還能夠實現按照第一個關鍵字降序,第二個關鍵字升序
DESC
只用到直接位於其前面的列明。若是想在多個列上進行降序排列,必須對每一個列指定DESC關鍵字。
IN A CONCLUSION: order by子句必須是select語句的最後一條子句。
op | descriptions |
---|---|
= | 等於 |
<> | 不等於 |
!= | 不等於 |
< / > | 小於 / 大於 |
<= / >= | 小於等於/ 大於等於 |
Between | 在指定的兩個值之間 |
is NULL | 空值檢查 |
搜索條件/過濾條件
過濾出來的數據。mysqlselect * from products where prod_price = 55;
mysqlselect * from products where prod_price <> 55;
mysqlselect * from products where prod_price between 30 and 60;
mysqlselect * from products where prod_price is Null;
計算次序問題: 使用
圓括號
明確的分組相應的操做符。
好比選擇segk 爲118 或者 120的行,而且隨機數小於等於2;
由於sql對and進行優先級處理。
任什麼時候候後使用具備and 和 or操做符的where子句,都應該使用圓括號明確的分組操做符,不要過度依賴默認的計算次序。使用圓括號來消除歧義。
在where 條件中使用REGEXP關鍵字。
基本字符匹配
檢索列prod_name 包含文本1000的全部行:
進行OR匹配
至關於:或操做 「|」
[
和]
括起來的字符來完成。[456]
定義了一組字符,他的意思是匹配4或5或6. []
是另外一種形式的OR語句。[456]
是[4|5|6]
的縮寫。[1-3]
a-z
都是合法的範圍、匹配特殊字符
正則表達式語言由特殊含義的特殊字符構成。
.
在正則表達式中表示匹配任何一個字符
好比匹配prod_name中包括on
字符串的行:
那如何匹配.
,[]
,|
,-
?
爲了匹配特殊字符,必須用
\\
爲前導。 好比\\.
表示查找·
匹配字符類
匹配多個實例
再好比 匹配連在一塊兒的4位數字:
sticks?
: s
後的?
使s可選,由於?
匹配它前面緊跟的任何字符的0次或者1次出現。
[:digit:]
匹配任意數字,於是它爲數字的一個集合。{4}
確切地要求它前面的字符出現4次。
因此[:digit:]{4}
匹配連在一塊兒的任意4位數字。
定位符
目前爲止全部例子都是匹配一個串中任意爲止的文本。爲了匹配特定爲止的文本,須要使用定位符。
拼接字段
存儲在數據庫表中的數據通常不是應用程序所須要的格式。咱們須要直接從數據庫中檢索出轉換、計算或格式化過
的數據;而不是檢索出數據,而後再在客戶機應用程序或報告程序中從新格式化。
計算字段(字段 = 列,不過數據庫列通常稱爲列,而字段一般用於計算字段中)並不實際存在於數據庫表中,計算字段是運行時在select語句內建立的。
拼接 concatenate 將值聯結到一塊兒構成單個值
在MySQL的select語句中,可以使用Concat()
函數來拼接兩個列。
如建立由兩列組成的標題:生成一個供應商報表,須要在供應商的名字中按照name(location)這樣的格式列出供應商的位置。此報表須要單個值,而表中數據存儲的兩個列vend_name
和vend_country
中。還須要用括號將vend_country
括起來。
新建立的列用AS
賦一個別名
left() 串左邊字符 length() 串長度 locate() 找出串的一個子串 lower() 轉爲小寫 ltrim() 去掉左邊空格 right() 返回串右邊字符 rtrim() 去掉串右邊空格 soundex() 返回字符串soundex值 upper() 大寫
將選擇的文本轉換成大寫
select Upper(vend_name) from vendors;
Soundex()
函數:將任何文本傳轉換爲描述其語音表示的字母數字模式的算法。(語音匹配?對發音比較而不是對字幕比較)
日期和時間函數 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
可是這樣的where order_date = '2005-09-01'
不可靠。由於order_date存儲的數據類型是datatime. 這種類型存儲日期及時間值。好比存儲的order_date值爲2005-09-01 11:30:05
,則where order_date = '2005-09-01'
就會匹配失敗。
因此最安全的方法是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;
- 計數
使用count(*)對錶中行的數目進行計數(whether null or not)
使用count(column)對特定列具備值的行進行計數,忽略null
目前爲止全部計算都是在表的全部數據或匹配特定的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 這個表
主鍵是prod_id 產品id,每個產品都對應一個供應商ID,產品名,產品價格,以及簡介。
若是咱們查看該產品表的供應商信息:
若是想進一步獲知每一個供應商提供多少種產品,就應該對供應商進行分組: 好比供應商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.
若是想要統計出訂單數目超過2的顧客id
增長的having子句,過濾了count(*)>=2那些分組。
where
和having
組合使用,能夠進行更強功能的操做。 如:列出提供了2個以上,價格爲10以上的產品的供應商:
先用wehre子句過濾了全部價格至少爲10的行,而後按照vend_id分組數據,having子句過濾計數爲2或2以上的分組。
能夠涉及數據庫多個表,檢索數據的語句。
子查詢用作過濾 in
訂單存儲在兩個表(orders,orderitems)中。
客戶信息存儲在customers表中
若是須要列出訂購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'));
做爲計算字段使用子查詢
若是須要顯示customers表中每一個客戶的訂單總數。 這須要使用customers,orders兩個表。
使用select count(*) 對錶中的行進行計數,並經過where 子句過濾行(經過過濾id)
orders是一個計算字段,它是由圓括號中的子查詢創建的。該子查詢對檢索出的每一個客戶執行一次。在這個例子中,該子查詢執行了5次,由於檢索出了5個客戶。
外鍵
外鍵爲某個表中的一列,它包含另外一個表的主鍵值,定義了兩個表之間的關係。可伸縮性
: 可以適應不斷增長的工做量而不失敗。關係型數據庫比非關係型數據庫的可伸縮性好。聯結
: 聯結是一種機制,用來在一條select語句中關聯表,所以稱之爲聯結。使用特殊的語法,能夠鏈接多個表返回一組輸出,聯結在運行時關聯表中正確的行。
聯結的引入是爲了解決 爲了帶來關係數據更大的可伸縮性而分解數據爲多個表,可是帶來的代價:數據分散存儲到多個表,怎麼用單條select語句檢索出數據。
兩個表: 供應商表vendors, 產品表 products
建立(等值)聯結
固然也能夠按照主鍵,外鍵關係聯結多個表。可是出於性能的考慮,這種處理多是很是耗資源的。聯接的表越多,性能降低越厲害。
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
使用不一樣類型的聯結
有兩種方法,一種是使用嵌套,另外一種是使用自聯接。
嵌套:
自聯接(同一個表別名爲p1,p2);
> 有時候,處理聯結要比查理子查詢快的多。
使用outer join
來指定聯結的類型。而不是在where子句。
使用帶彙集函數的鏈接
檢索全部客戶及每一個客戶所下的訂單數。
使用Union操做符將多條select語句組合成一個結果集,並將結果做爲單個查詢結果集返回。這些組合查詢稱爲並
或複合查詢compound query
有兩種狀況,須要使用組合查詢:
1. 在單個查詢中從不一樣的表返回相似結構的數據;
Union
使用where:
使用union:
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’)
全文搜索(compared to like and regexp) 一個重要部分就是對結果排序。具備較高優先級的列先返回(由於這些行極可能就是你真正想要的行):好比先返回第三個詞rabbit的行,再返回第20個詞rabbit的行。
一個對比:
like是按照出現順序,先返回第20個詞rabbit的行,再返回第三個詞rabbit的行。
放寬所返回的全文本搜索結果的範圍。
好比:
想找到全部提到anvils的註釋,只有一個註釋包含了詞anvils,可是你還想找出可能與你的搜索有關的全部其餘行,即便不包含詞anvils.
在使用查詢擴展時,mysql對數據和索引兩遍掃描完成。利用查詢擴展,能找出可能相關的結果,即便它們並不精確包含所查找的詞。
首先,進行一個基本的全文本搜索,找出與搜索條件匹配的全部行;
其次,MySQL檢查這些匹配行並選擇全部有用的詞。
再其次,MySQL再次進行全文本搜索們此次不只使用原來的條件,並且還使用全部有用的詞。
以布爾方式,能夠提供關於以下內容的細節:
表達式分組;
另一些內容
SELECT note_text FROM productontes WHERE Match(note_text) Against(‘heavy’ IN BOOLEAN MODE)
排除了任何包含rope*的行。
例子:
搜索匹配safe和combination。下降後者的等級。
插入行到數據庫表。
能夠
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;
不要求列明匹配,使用的是列的位置。
mysqlupdate TABLENAME set ColomnName1 = NewValue, ColomnName2 = NewValue where ... (過濾條件)
若是上面例子,沒有where過濾條件,就是更新全部行。
設置爲null(if表定義容許爲null)
mysqlupdate TABLENAME set ColomnName1 = Null, where ... (過濾條件)
mysqldelete from TABLENAME where ... (過濾條件)
若是上面例子,沒有where過濾條件,就是刪除全部行。
Note: delete 語句是從表中刪除行,甚至是刪除表中全部行。可是delete不刪除表自己。
Note: 更快的刪除,若是想從表中刪除全部行,不要使用delete, 可以使用truncate table語句(完成相同功能,可是速度更快,其實是刪除原來的表並從新建立一個表,而非逐行刪除表的數據)。
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 table
.
mysqlalter table vendors add vend_phone char(20);
刪除表,而非內容
mysqldrop table tableName;