1.表中的任何列都可以作為主鍵, 只要它滿足以下條件:
任意兩行都不具有相同的主鍵值;
每一行都必須具有一個主鍵值( 主鍵列不允許NULL值) ;
主鍵列中的值不允許修改或更新;
主鍵值不能重用( 如果某行從表中刪除, 它的主鍵不能賦給以后的新行)
2.MySQL的要求:任意兩行都不具有相同的主鍵值;
每個行都必須具有一個主鍵值(主鍵列不允許NULL值)。
3.tips:除MySQL強制實施的規則外,應該堅持的
幾個普遍認可的最好習慣為:
? 不更新主鍵列中的值;
? 不重用主鍵列的值;
? 不在主鍵列中使用可能會更改的值。(例如,如果使用一個
名字作為主鍵以標識某個供應商,當該供應商合并和更改其
名字時,必須更改這個主鍵。)
第二章
1.MySQL選項和參數 如果僅輸入mysql, 可能會出現一個錯誤
消息。因為可能需要安全證書,或者是因為MySQL沒有運行
在本地或默認端口上。 mysql接受你可以(和可能需要)使用
的一組命令行參數。例如,為了指定用戶登錄名ben,應該使
用mysql -u ben。為了給出用戶名、主機名、端口和口令,
應該使用mysql -u ben -p -h myserver -P 9999。
完整的命令行選項和參數列表可用mysql --help獲得。
2.命令輸入在mysql>之后;
? 命令用;或\g結束,換句話說,僅按Enter不執行命令;
? 輸入help或\h獲得幫助,也可以輸入更多的文本獲得特定命令的
幫助(如,輸入help select獲得使用SELECT語句的幫助);
? 輸入quit或exit退出命令行實用程序。
第三章
1.必須先使用USE打開數據庫,才能讀取其中的數據。
2.SHOW COLUMNS 要 求 給 出 一 個 表 名 ( 這 個 例 子 中 的 FROM
customers),它對每個字段返回一行,行中包含字段名、數據
類型、是否允許NULL、鍵信息、默認值以及其他信息(如字段cust_id
的auto_increment)。
什么是自動增量? 某些表列需要唯一值。例如,訂單編號、
雇員ID或(如上面例子中所示的)顧客ID。在每個行添加到表
中時, MySQL可以自動地為每個行分配下一個可用編號,不
用在添加一行時手動分配唯一值(這樣做必須記住最后一次使
用的值)。這個功能就是所謂的自動增量。
3.SHOW STATUS,用于顯示廣泛的服務器狀態信息;
? SHOW CREATE DATABASE和SHOW CREATE TABLE,分別用來顯示創
建特定數據庫或表的MySQL語句;
? SHOW GRANTS,用來顯示授予用戶(所有用戶或特定用戶)的安
全權限;
? SHOW ERRORS和SHOW WARNINGS, 用來顯示服務器錯誤或警告消息。
第四章 檢索數據
1.要想從一個表中檢索多個列,使用相同的SELECT語句。唯一的不同
是必須在SELECT關鍵字后給出多個列名,列名之間必須以逗號分隔。
2.mysql命令行用;
3.在選擇多個列時,一定要在列名之間加上逗號,但
最后一個列名后不加。如果在最后一個列名后加了逗號,將出
現錯誤。
4.如果給定一個通配符( *),則返回表中所有列
5.SELECT DISTINCT vend_id告訴MySQL只返回不同(唯一)的
vend_id行,因此只返回4行.不能部分使用DISTINCT DISTINCT關鍵字應用于所有列而
不僅是前置它的列。
6.此語句使用SELECT語句檢索單個列。 LIMIT 5指示MySQL返回
不多于5行.LIMIT 5, 5指示MySQL返回從行5開始的5行。
7.SELECT products.prod_name FROM products;
第五章,排序
1.SELECT prod_name
FROM products
ORDER BY prod_name;
2.SELECT prod_id,prod_price,prod_name FROM products
ORDER BY prod_price,prod_name DESC;
DESC表示降序,ASC是升序
3.如何區分大小寫和排序順序是數據庫管理員設定規則
4.在給出ORDER BY子句時,應該保證它
位于FROM子句之后。如果使用LIMIT,它必須位于ORDER BY
之后。使用子句的次序不對將產生錯誤消息。
第六章 過濾數據
1.SELECT prod_name,prod_price
FROM products
WHERE prod_price=2.50
2.在同時使用ORDER BY和WHERE子句時,應
該讓ORDER BY位于WHERE之后, 否則將會產生錯誤
3.SELECT prod_name,prod_price
FROM products
WHERE prod_price BETWEEN 5 AND 10;
4.SELECT prod_name
FROM products
WHERE prod_price IS NULL;
第七章 數據過濾
1.AND在計算次序中優先級更高。
2.SELECT prod_name,prod_price
FROM products
WHERE vend_id NOT IN (1002,1003)
ORDER BY prod_name;
3.MySQL 支 持 使 用 NOT 對 IN 、 BETWEEN 和
EXISTS子句取反,這與多數其他DBMS允許使用NOT對各種條件
取反有很大的差別。
第八章 用通配符進行過濾
1.通配符,搜索模式,在搜索子句中用通配符必須使用LIKE操作符
2.SELECT prod_id,prod_name
FROM products
WHERE prod_name LIKE 'jet%';
%表示任何字符出現的任意次數。
3.tips:尾空格可能會干擾通配符匹配。例如,在保存詞
anvil 時 , 如 果 它 后 面 有 一 個 或 多 個 空 格 , 則 子 句 WHERE
prod_name LIKE '%anvil'將不會匹配它們,因為在最后的l
后有多余的字符。解決這個問題的一個簡單的辦法是在搜索模
式最后附加一個%。
雖然似乎%通配符可以匹配任何東西,但有一個例
外,即NULL。即使是WHERE prod_name LIKE '%'也不能匹配
用值NULL作為產品名的行
4.與%能匹配0個字符不一樣, _總是匹配一個字符,不能多也不能少。
5.tips:不要過度使用通配符。如果其他操作符能達到相同的目的,應該
使用其他操作符。
? 在確實需要使用通配符時,除非絕對有必要,否則不要把它們用
在搜索模式的開始處。把通配符置于搜索模式的開始處,搜索起
來是最慢的。
? 仔細注意通配符的位置。如果放錯地方,可能不會返回想要的數
第九章 用正則表達式進行搜索
1.SELECT prod_name
FROM products
WHERE prod_name REGEXP'1000'
ORDER BY prod_name;
2.LIKE是匹配整個列,REGEXP匹配列值,為在搜索子句中使用通配符,必須使用LIKE操作符。 LIKE指示MySQL,
后跟的搜索模式利用通配符匹配而不是直接相等匹配進行比較。
3.MySQL正則表達式匹配后不區分大小寫。區分大小寫可以用BINARY關鍵字,如WHERE prod_name REGEXP BINARY 'JetPack.000'
4.匹配特定的字符用[].
5.否定字符集合用^.
6.正則表達式匹配列值,只要列值中含有就可以,LIKE則是匹配整個列形式。
7..是匹配任意字符,匹配特殊字符用\為前導。、|[].
8.\f換頁,\n換行,\r回車,\t制表,\v縱向制表。
9.找出你自己經常使用的數字,所有字母字符或所有數字字母字符的匹配。預定義的字符類。
[:alnum:]任意字母和數字
[:alpha:]任意字符
[:blank:]空格和制表[\t]
[:cntrl:]ASCII控制字符 0到31和127
[:digit:]任意數字
[:graph:]與[:print:]相同,但不包括空格
[:lower:]任意小寫
[:print:]任意可打印字符
[:punct:]既不是alnum也不是cntrl的字符
[:space:]包括空格在內的空白字符,同[\f\n\r\t\v]
[:upper:]
[:xdigit:]任意十六進制數字
10.匹配多個實例
*0個或多個匹配
+1個或多個
?0個或1個
{n}指定數目的匹配
{n,}不少于指定數目的匹配
{n,m}匹配數目的范圍
11.^文本的開始 $文本的結尾 [[:<:]]詞的開始 [[:>:]]詞的結尾
SELECT 'hello' REGEXP '[0-9]'返回0
第十章 創建計算字段
1.存儲在表中的數據都不是應用程序所需要的。
我們需要直接從數據庫中檢索出轉換、計算或格式化過的數據;而不是
檢索出數據,然后再在客戶機應用程序或報告程序中重新格式化。
這就是計算字段發揮作用的所在了。與前面各章介紹過的列不同,
計算字段并不實際存在于數據庫表中。計算字段是運行時在SELECT語句
內創建的。數據庫知道SELECT語句中哪些列是實際的
表列,哪些列是計算字段。從客戶機(如應用程序)的角度來看,計算
字段的數據是以與其他列的數據相同的方式返回的。
2.tips:多數DBMS使用+或||來實現拼接,
MySQL則使用Concat()函數來實現。當把SQL語句轉換成
MySQL語句時一定要把這個區別銘記在心
3.SELECT Concat(vend_name,'(',vend_country,')')
FROM vendors
ORDER BY vend_name;
4.SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')')
FROM vendors
ORDER BY vend_name;
Rtrim去掉右邊所有空格,Ltrim去掉左邊所有空格
5.使用別名
SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')')AS
vent_title
FROM vendors
ORDER BY vend_name;
6.計算字段
SELECT prod_id,
quatity,
item_price,
quatity*item_price AS expanded_price
FROM orderotems
WHERE order_num=2005;
第十一章 用數據處理函數
1.常用文本處理函數
Left()返回左邊字符,Length(),Locate()找出串的一個子串,Lower(),LTrim(),Right(),Rtrim(),Soundex()返回串的soundex值,SubString()返回子串的字符,Upper()
2.SELECT cust_name,cust_contact
FROM customers
WHERE Soundex(cust_contact)=Soundex('Y Lie');
3.日期和時間處理函數
AddDate()天,周,AddTime()時,分,CurDate(),CurTime(),Date()日期時間的日期部分,DateDiff()日期之差,Date_Add()高度靈活的日期運算函數,Date_Format()返回格式化日期或者時間串,Day(),DayOfWeek(),Hour(),Minute(),Month(),Now(),Second(),Time(),Year()。
4.數值處理函數
abs(),cos(),exp(),mod(),pi(),rand()隨機數,sin(),sqrt(),tan()
第十二章 匯總數據
1.聚集函數 運行在行組上,計算和返回單個值的函數。
2.AVG()平均值COUNT()行數 MAX()MIN()SUM()
3.SELECT AVG(prod_price)AS avg_price
FROM products;
4.確定特定列的平均值
AVG()忽略NULL的行
SELECT AVG(prod_price) AS avg_price
FROM products
WHERE vend_id =1003;
5.COUNT()
COUNT()包含null,COUNT(column)忽略null
SELECT COUNT() AS num_cust
FROM customers;
6.MAX()在用于文本數據時,如果數
據按相應的列排序,則MAX()返回最后一行。???
7.SELECT SUM(item_pricequantity)AS total_price
FROM orderitems
WHERE order_num=2005;
8.distinct只考慮不同的
SELECT AVG(DISTICT prod_price)AS avg_price
FROM products
WHERE vend_id =1003;
9tips:
如果指定列名,則DISTINCT只能用于COUNT()。DISTINCT
不能用于COUNT(),因此不允許使用COUNT( DISTINCT),
否則會產生錯誤。類似地, DISTINCT必須使用列名,不能用
于計算或表達式。
第十三章 分組數據
1.SELECT vend_id, COUNT() AS num_prods
FROM products
GROUP BY vend_id;
GROUP BY子句可以包含任意數目的列。這使得能對分組進行嵌套,
為數據分組提供更細致的控制。
? 如果在GROUP BY子句中嵌套了分組,數據將在最后規定的分組上
進行匯總。換句話說,在建立分組時,指定的所有列都一起計算
(所以不能從個別的列取回數據)。
? GROUP BY子句中列出的每個列都必須是檢索列或有效的表達式
(但不能是聚集函數)。如果在SELECT中使用表達式,則必須在
GROUP BY子句中指定相同的表達式。不能使用別名。
? 除聚集計算語句外, SELECT語句中的每個列都必須在GROUP BY子
句中給出。
? 如果分組列中具有NULL值,則NULL將作為一個分組返回。如果列
中有多行NULL值,它們將分為一組。
? GROUP BY子句必須出現在WHERE子句之后, ORDER BY子句之前。
使用有 WITH ROLLUP 子句的 GROUP BY 語句時,不能再使用 ORDER語句對結果集進行排序,如果對返回的結果順序不滿意,需要應用程序獲得結果后在程序中進行排序
2.WHERE 過濾行,HAVING過濾分組
SELECT cust_id,COUNT()AS orders
FROM orders
GROUP BY cust_id
HAVING count()>=2;
這里有另一種理解方法,WHERE在數據
分組前進行過濾, HAVING在數據分組后進行過濾。這是一個重
要的區別, WHERE排除的行不包括在分組中。這可能會改變計
算值,從而影響HAVING子句中基于這些值過濾掉的分組。
3.SELECT vend_id,COUNT()AS num_prods
FROM products
WHERE prod_price>=10
GROUP BY vend_id
HAVING COUNT()>=2;
4.如果用了having 就要用group by。
SELECT order_num,SUM(quatityitem_price)AS ordertotal
FROM orderitems
GROUP BY order_num
HAVING SUM(quatity*item_price)>=50
ORDER BY ordertotal;
5.SELECT 是
WHERE 否
GROUP BY 按組計算聚集使用
HAVING 否 ORDER BY
LIMIT 否
第14章 使用子查詢
1.SQL
SELECT cust_id
FROM orders
WHERE order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2');
2.SELECT cust_name,cust_contact
FROM customers
WHERE cust_id IN(SELECT cust_id
FROM orders
WHERE order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2'));
3.列必須匹配:
在WHERE子句中使用子查詢(如這里所示),應
該保證SELECT語句具有與WHERE子句中相同數目的列。通常,
子查詢將返回單個列并且與單個列匹配,但如果需要也可以
使用多個列。
4.SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM orders
WHERE order.cust_id=customers.cust_id)AS orders
FROM customers
ORDER BY cust_name;
第十五章 聯結表
1.外鍵為某個表中的一列,它包含另一個表
的主鍵值,定義了兩個表之間的關系。
2.在一條SELECT語句中聯結幾個表時,相應的關系是
在運行中構造的。在數據庫表的定義中不存在能指示MySQL如何對表進
行聯結的東西。你必須自己做這件事情。在聯結兩個表時,你實際上做
的是將第一個表中的每一行與第二個表中的每一行配對。 WHERE子句作為
過濾條件,它只包含那些匹配給定條件(這里是聯結條件)的行。
3.由沒有聯結條件的表關系返回
的結果為笛卡兒積。檢索出的行的數目將是第一個表中的行數乘
以第二個表中的行數。
4.SELECT vend_name,prod_name,prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id=products.vend_id;
5.ANSI SQL規范首選INNER JOIN語法。此外,
盡管使用WHERE子句定義聯結的確比較簡單,但是使用明確的
聯結語法能夠確保不會忘記聯結條件,有時候這樣做也能影響
性能
SELECT cust_name,cust_contact
FROM customers
WHERE cust_id IN(SELECT cust_id
FROM orders
WHERE order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2'));
SELECT cust_name,cust_contact
FROM customers,orders,orderitems
WHERE customers.cust_id=orders.cust_id
AND orderitems.order_num=order.order_num
ADN prod_id='TNT2';
第十六章 創建高級聯結
1.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';
自聯結通常作為外部語句用來替代
從相同表中檢索數據時使用的子查詢語句。雖然最終的結果是
相同的,但有時候處理聯結遠比處理子查詢快得多。應該試一
下兩種方法,以確定哪一種的性能更好。
2.自然聯結
SELECT c.*o.order_num,o.order_date,
oi.prood_id,oi.quatity,OI.item_price
FROM customers AS c,orders AS o,orderitems AS oi
WHERE c.cust_id=o.cust_id
AND oi.order_num=o.order_num
AND prod_id='FB';
通配符只對第一個表使用。所有其他列明確列
出,所以沒有重復的列被檢索出來。
3.SELECT customer.cust_id,orders.order_num
FROM customers INNER JOIN orders
ON customers.cust_id=orders.cust_id;
4.SELECT customer.cust_id,orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id;
這條SELECT語句使用了關
鍵字OUTER JOIN來指定聯結的類型(而不是在WHERE子句中指
定)。但是,與內部聯結關聯兩個表中的行不同的是,外部聯結還包括沒
有關聯行的行。在使用OUTER JOIN語法時,必須使用RIGHT或LEFT關鍵字
指定包括其所有行的表( RIGHT指出的是OUTER JOIN右邊的表,而LEFT
指出的是OUTER JOIN左邊的表)。上面的例子使用LEFT OUTER JOIN從FROM
子句的左邊表( customers表)中選擇所有行。???
5.SELECT customers.cust_name,
customers.cust_id,
COUNT(orders.order_num)AS num_ord
FROM customers INNER JOIN orders
ON customers.cust_id=orders.cust_id
GROUP BY custmers.cust_id;
6.SELECT customers.cust_name,
customers.cust_id,
COUNT(orders.order_num)AS num_ord
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id
GROUP BY customers.cust_id:
第十七章 組合查詢
1.使用UNION
SELECT vend_id,prod_id,prod_price
FROM products
WHERE prod_price<=5
UNION
SELECT vend_id,prod_id,prod_price
FROM products
WHERE vend_id IN(1001,1002);
TIPS:UNION可能比使用WHERE子句更為復雜。
但對于更復雜的過濾條件,或者從多個表(而不是單個表)中檢索數據
的情形,使用UNION可能會使處理更簡單。
- UNION規則
必須由兩條或兩條以上的SELECT語句組成,語句之間用關
鍵字UNION分隔(因此,如果組合4條SELECT語句,將要使用3個
UNION關鍵字)。
? UNION中的每個查詢必須包含相同的列、表達式或聚集函數(不過
分析各個列不需要以相同的次序列出)。
? 列數據類型必須兼容:類型不必完全相同,但必須是DBMS可以
隱含地轉換的類型(例如,不同的數值類型或不同的日期類型)。
如果遵守了這些基本規則或限制,則可以將并用于任何數據檢索任務。
UNION可以去除重復的行,想返回所有匹配行,使用UNION ALL 而不是UNION,在使用UNION組合查詢的時候,只能使用一條ORDER BY,必須出現在最后一條SELECT語句之后 不能用多條
第十八章,全文本搜索
1.MySQL
支持幾種基本的數據庫引擎。并非所有的引擎都支持本書所描
述的全文本搜索。兩個最常使用的引擎為MyISAM和InnoDB,
前者支持全文本搜索,而后者不支持。這就是為什么雖然本書
中 創 建 的 多 數 樣 例 表 使 用 InnoDB , 而 有 一 個 樣 例 表
( productnotes表)卻使用MyISAM的原因。