天天看點

mysql cookbook

轉自:http://blogold.chinaunix.net/u/10047/showart_2511711.html

mysql cookbook 2nd cn pdf: http://ishare.iask.sina.com.cn/f/13652605.html?w=][MySQL.Cookbook%28%B5%DA2%B0%E6%29].%28%C3%C0%29%B5%CF%B2%BC%CD%DF.%D6%D0%CE%C4%B0%E6.%C9%A8%C3%E8%B0%E6.pdf.7z

mysql version: >V5.0

mysql V5.1 zh handbook: http://dev.mysql.com/doc/refman/5.1/zh/index.html

examples data: http://www.kitebird.com/mysql-cookbook/downloads-2ed.php

1。使用MYSQL用戶端程式

   1.1 建立MYSQL使用者帳号:

    GRANT priv_type ON db_name.* TO 'username'@'ip or hostname' IDENTIFIED BY 'password'

   1.2 建庫和表

     create database dbname;

     create table tablename (volum1 type,volum2 type,...)

   1.3 啟動和停止mysql

   1.4 使用可選項檔案來指定連接配接參數,即輸入mysql指令即可登入mysql伺服器。

       $vi ~usrname/.my.cnf

         [client]

          host    = ip or hostname

          user    = mysqlusername

          password= xxx(若想自己輸入,則不寫=xxx,即password後留白)

          database=dbname(指定預設登入的庫)

         [mysql]

          skip-auto-rehash(關閉TAB鍵的自動補齊功能,反指令為去掉該句,或者mysql>rehash  或者 mysql>/#)

      $mysql --print-defaults 檢視mysql程式從選項檔案中讀取了哪些選項

      $my_print_defaults client mysql 檢視從[client] [mysql]選項中讀取了什麼

    1.5 保護選項檔案:既設定.my.cnf檔案的權限

    1.6 混合使用指令行和選項檔案參數:如上,為了安全,密碼需要手工輸入。

        注意:如果指令行和選項檔案都有某個參數,指令行的優先級高。

    1.7 找不到mysql時該如何做:即把mysql指令的路徑加入環境變量PATH裡。

    1.8 發起SQL語句:mysql語句的結尾可以是“;” or  "/g"

    1.9 取消一條部分輸入的語句:/c

    1.10 重複和編輯SQL語句:使用mysql内建的輸入行編輯能力,既gnu readline. 快捷鍵類似emacs. linux預設行編輯器也是它。不同VI。

         快捷鍵:up,down,left,right 方向鍵

                 ctrl+a 到行首(等于home)  ctrl+e 到行尾(等于end)

                 ctrl+l 清屏

                 backspace  向前删   delete 向後删(=ctrl+d)

    1.11 自動完成資料庫和表名的錄入:tab鍵自動補齊

         缺點:若庫中有大量表時mysql啟動會慢,因為預讀的原因。

    1.12 讓mysql從檔案中讀取語句:重定向$ mysql dbname < xxx.sql

                                  或者登入mysql後用指令mysql>source /xxx/yyy/sss.sql

    1.13 讓mysql從其他程式讀取語句:用管道(pipe) 如導出接着導入另一庫:$mysqldump cookbook |mysql -h hostname cookbook

    1.14 一指令行輸入所有sql:mysql能從其參數清單中讀取語句,使用-e(--execute).多條語句用分号隔開。

         $mysql -e "show tables;select * from mail;"

    1.15 使用拷貝粘貼作為mysql輸入源:GUI環境裡用。

    1.16 預防查詢輸出超出螢幕範圍:指定分頁檢視程式參數:在.my.cnf中設定[mysql]參數pager=/usr/bin/less

                                                         或者mysql>/P

                                    反指令是去掉pager參數或者mysql>/n

    1.17 發送查詢輸出到檔案或程式:沖定向mysql的輸出或者用管道

    1.18 選擇表格或制表符定界的查詢輸出格式:$mysql -t cookbook <inputfile

    1.19 指定任意的輸出列分隔符:使用shell替換功能

                                 $mysql cookbook <inputfile|sed -e "s/TAB/:/g" >outfile

    1.20 生成html或者xml:  $mysql --html -e "select * from mail;"

                           $mysql --xml -e "select * from mail;"

    1.21 在查詢輸出中禁止列出頭部:$mysql --skip-column-name -e "select * from mail;"

                                   等效于:mysql -ss -e "select * from mail;" 即兩次指定silent選項。

    1.22 使長輸出行更具有可讀性:show full columns from limbs /G 即垂直輸出

                                 等效于 mysql -E -e "show full columns from limbs;"

    1.23 控制mysql的繁墉級别:echo "show now()"|mysql

                              echo "show now()"|mysql -v

                              echo "show now()"|mysql -vv

                              echo "show now()"|mysql -vvv

                            反指令為:-s

    1.24 記錄互動式的mysql會話:mysql --tee=tmp.out cookbook

                                指令行裡開啟:/T tmp.out

                                指令行裡關閉:/t

    1.25 以之前執行的語句建立mysql腳本:讀取之前的tee檔案。或者檢視mysql的曆史檔案.mysql_history

    1.26 在sql語句中使用使用者自定義的變量:在sql語句中給變量指派文法:@var_name:=value

    1.27 為查詢輸出行計數:mysql --skip-colum-names -e "select * from mail;"|cat -n

                           等效:mysql>set @n=0;

                                 mysql>select @n :[email protected]+1 as rownum,t from mail;

    1.28 将mysql用作計數器:mysql> select (17+23)/sqrt(64);

    1.29 在shell腳本中使用mysql: 隻要為指令提供合适的參數即可。

    備注:windows OS 下的指令行環境:cygwin(cygnus工具)

2。編寫基于MYSQL的程式

   2.0 引言即MYSQL用戶端API架構

   2.1 連接配接、選擇資料庫及斷開連接配接

    不同API不同方法

   2.2 差錯

   2.3 編寫庫檔案

    封裝語句以提高效率。

   2.4 發起語句并檢索結果

   2.5 處理語句中的特殊字元和NULL值

    使用API的占位機制。

   2.6 處理辨別符中的特殊字元

   2.7 識别結果集中的null值

   2.8 擷取連接配接參數的技術

   2.9 結論和建議

3。從表中查詢資料

   3.0 引言

       這裡隻是部分SELECT語句的分析,完整的請看《MySQL 5.1參考手冊 》http://dev.mysql.com/doc/refman/5.1/zh/index.html

   3.1 指定查詢列/從指定列中查詢

       select * from tablename;

       select volumn1,volumn2,... from tablename;

   3.2 指定查詢行

       select * from tablename where ...

   3.3 格式化顯示查詢結果

       若不指定列名,則用預設列名作為輸出列名。

       若用表達式,則表達式為輸出列名。

       若用AS 新名,則新名輸出列名。

   3.4 使用列别名來簡化程式

       上面用到了表達式來查詢,如果引用該表達式結果時寫表達式名就比較繁瑣,可以用AS 新名來定義個别名。

   3.5 合并多列來建構複合值

        比如查詢出username和hostname,現要輸出郵件位址形式[email protected]

        用concat(username,'@',hostname) as mailadd

   3.6 where表達式中的列别名

        mysql是無法執行的。會報錯。解決方法就是在where中用原名或原表達式。

   3.7 調試比較表達式

        即在sql語句中把原值和查詢結果一起輸出,既可調試。

   3.8 使查詢結果唯一化

        關鍵字:distinct

        mysql内部幫助裡如何檢視所有函數?

   3.9 如何處理null值: 比較操作null

        is null  

        is not null

   3.10 在使用者程式中使用null作為比較參數

        根據不同的語言有不同的方法

   3.11 結果集排序

         order by 字段 (預設升序,加desc後降序)

   3.12 使用視圖來簡化查詢

        視圖不同臨時表(臨時表是存在的表,可以執行表的各種操作,不過是臨時工而已),不存在表,隻是封包了一堆語句而已。

        create view view_name as select t as t-time,srcuser as user,srchost as host from mail;

        select user,host from view_name;

   3.13 多表查詢:使用join(聯合),或者子查詢。

        select volumn1,volumn2,... from tablename1 inner join talbename2 on 條件1=條件2

        from字句指定了要查詢的表。

        on字句指定了兩個表的行的綁定規則。

   3.14 從查詢結果集頭或尾取出部分行

        limit N: 獲得查詢結果的頭N行

   3.15 在結果集中間選取部分行

        limit n,m:獲得從n開始(不含n)的m-n行。

   3.16 選擇合适的limit參數

        即當有多個相同值時limit會顯示不全,應該配合order by desc排序,distinct唯一來組合操作。

   3.17 當HTML需要“錯誤”的排列順序時做什麼。

         limint的靈活使用。

   3.18 從表達式中計算limit值

        limit隻能接收1到2個數字(可以直接是數字,也可以是變量)參數,不能接受表達式。

4。表管理

   4.1 克隆表

        克隆表結構: create table new_table_name like old_table_name

        克隆部分或全部資料:insert into new_table_name select * from old_table_name where ...

   4.2 将查詢結果儲存到表中

        一步完成:create table new_table_name select * from old_table_name;

        根據實際需求,調整SELECT語句,即可實作按要求的儲存。

   4.3 使用臨時表(temporary,即臨時,和mysql伺服器的連接配接關閉後該類表即被自動删除)

        普通的臨時表:create temporary table new_table_name (列定義);

        克隆表結構:create temporary table new_table_name like old_table_name;

        根據查詢結果建表:create temporary table new_table_name select ...;

        注意:臨時表名不可和普通表同名;

              若有連接配接池的API程式用臨時表,建前最好先寫删除語句:drop temporary table if exists new_table_name

   4.4 檢查或修改某個表的存儲引擎

         檢測:select engine from information_schema.tables where table_name like 'table_name';

               show table status like 'table_name';

               show create table table_name;

         修改:alter table table_name engine=引擎名(myisam  innodb  bdb...)

   4.5 生成唯一的表名的方法:

         使用temporary表;

         使用随機數;

         使用PID;

         使用連接配接ID;

5。與字元串共舞

   5.0 引言

       字元串分兩類:二進制 binary  varbinary blob: 存儲原始資料

                 非二進制 char  varchar text:存儲字元資料

   5.1 字元串屬性

       屬性之一就是二進制和非二進制

   5.2 選擇字元串的資料類型

       原則:是否是二進制資料?

             大小寫是否敏感?

             最大長度?

             定長還是變長?

             尾部空格是否保留?

             是否有固定的允許值集合?

   5.3 正确設定用戶端連接配接的字元集

        方法:編輯.my.cnf,添加:[mysql] /n default-character-set=utf8

              建立連接配接後設定 mysql>set names 'utf8';    

                     or一并設定校對規則   mysql>set names 'utf8' collate 'utf8-general-c1';

              其他程式設計語言自己的設定方法。

   5.4 串字母

        方法:單雙引号或者組合後把字母括起來

              用反斜線轉義

              用十六進制。

   5.5 檢查一個字元串的字元集charset()或字元排序collation(),即在字元集内用于比較字元的一套規則。

       函數:charset() 檢查字元集;  collation() 檢查排序規則

             mysql>select charset('abc') collation('abc')

   5.6 改變字元串的字元集或字元排序

       函數:convert(@var using utf8) 轉換字元串的字元集

       操作符:collate 新的排序規則名location

   5.7 更改字元串字母的大小寫

       函數:upper('abc')  upper(列名)

       函數:lower('ABC')  lower(列名)

   5.8 更改字元串字母的大小寫失敗的情況(和mysql版本有關系)

       原因:字元串為二進制,如binary  blob

       方法:轉換為非二進制後再轉換

   5.9 控制字元串比較中的大小寫敏感

       使用比較操字元。根據需要來選擇是否敏感

   5.10 使用SQL模式進行模式比對

      操作符: like+正規表達式 %abc  abc% __abc% %abc%    

               not like+正規表達式 %abc  abc% __abc% %abc%

   5.11 使用正在表達式進行模式比對

       ^   比對字元串的開始部分

       $   比對字元串的結尾部分

       .   比對任何字元(包括回車和新行)

       [...]  括号内任意一個字元

       [^...] 除了括号内字元的任意一個字元

       p1|p2|p3 三者中的任意一個

       *    比對0個或多個*之前的任何序列

       +    比對1個或多個+之前的任何序列

       {n}  n個{n}前面的任何序列

       {m,n} 最少m個,最多n個{m,n}之前的任何序列

    5.12 模式比對中的大小寫問題

        方法:更改字元串屬性,決定其在比對過程中是否大小寫敏感

              mysql預設大小寫不敏感。因為字元集是latin1,比較排序為latin1_swedish_ci

    5.13 分割或者串聯字元串

          分割函數:left(列名,n)

                    mid(列名,m,n)

                    right(列名,n)

                    substring(列名,n) 傳回“從n開始到右結尾”的所有字元

                    substring_index(列名,c,n) 傳回“從左側查找字元c第n次出現的位置,從該位置開始到右結尾”的所有字元

                    concat() 把該函數參數全部串聯起來。

   5.14 查詢字元串

          函數:LOCATE('abc',name,3)從第三個字元開始查找子字元串出現的第一個位置。

   5.15 使用FULLTEXT查詢:對大量文本進行查詢

        優點:速度快。老SQL方法也能實作,但速度慢。

         方法:給表加上FULLTEXT索引 alter table kjv add fulltext(vtext);

               用match()函數指定索引列和用against()函數指定查詢關鍵字:select count(*) from kjv where match(vtext) against('Mizraim');

   5.16 用短語來進行FULLTEXT查詢

   5.17 要求或禁止FULLTEXT搜尋單詞

   5.18  用FULLTEXT索引來執行詞組查詢

6。使用日期和時間

   6.0

   6.1 選擇合适的日期或者時間變量類型

       考慮:儲存時間、日期 或者時間+日期

             起止範圍是什麼

             是否需要庫自動為其初始化。

        DATE類型:儲存日期 1000-01-01~9999-12-31

        TIME類型:儲存時間 -838:59:59~838:59:59

        DATETIME類型:同時儲存日期和時間值 1000-01-01 00:00:00~9999-12-31 23:59:59。

        TIMESTAMP類型:同時儲存日期和時間值 1970-01-01 00:00:00~2037-12-31 23:59:59。

   6.2 修改Mysql中的日期格式

       mysql始終隻能使用ISO格式的日期來儲存和顯示。

       方法:将非ISO格式的重寫為ISO格式的來儲存。

              用DATE_FORMAT(datetime,format)函數将其從ISO格式轉換為其他格式顯示。

        格式化字元:%Y %y %M %m %D %d 類似UNIX/LINUX系統時間格式。

   6.3 設定用戶端時區

        若MYSQL伺服器和用戶端不在同一時區時需注意:雙方按自己的時區來儲存顯示。

        伺服器參數:--default-time-zone

   6.4 擷取目前日期或時間

       擷取用戶端日期或時間: curdate()  curtime() now()

       擷取目前utc日期或時間: utc_date() utc_time() utc_timestamp()

   6.5 使用TIMESTAMP(時間戳)來跟蹤行修改時間

       方法:使用TIMESTAMP資料類型即可,如果不INSERT進值,它會自動初始化和自動更新的特性。

   6.6 從日期或者時間值中分解出各部分值

       方法:使用特定函數,如YEAR() MONTH() HOUR()MINUTE()SECOND()

             使用格式化函數 DATE_FORMAT()  TIME_FORMAT()

             當作字元串,用LEFT() MID()等函數。

   6.7 合成日期或者時間值

       方法:使用maketime(14,47,00)函數組合時分秒

             使用date_format() 或者time_format()來替換

             使用分解函數+concat()函數

   6.8 在時間資料類型和基本機關間進行轉換

        方法:時間和秒間轉換 time_to_sec()  sec_to_time()

              日期和天間轉換 to_days() from_days()

              在timestamp or datetime類型值和秒間轉換,用unix_timestamp() from_unixtime()

   6.9 計算兩個日期和時間之間的間隔

         方法:時間差函數:datediff()

               雙方都換算成天或者秒,求差後再換算。

   6.10 增加日期或時間值

         方法:使用時間加法函數

               使用+internal or -internal函數

                轉換為基本計時機關,然後求和

   6.11 計算年齡

         方法:使用timestampdiff(機關(一般為YEAR),出生日期,目前日期(可用curdate()獲得)

   6.12 将一個日期和時間值切換到另一個時區

        方法:conver-tz('源時間','源時區','目标時區')

              如SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');

   6.13 找出每月的第一天,最後一天或者天數

         第一天:将日期後移dayofmonth(t)-1 day:select t,date_sub(t,interval dayofmonth(t)-1 day)  from mail;

         最後一天:last_day()

         天數:dayofmonth(last_day(date))

   6.14 通過子串替換來計算日期

         把源日期當作字元串,替換後産生新的日期

   6.15 計算某個日期為星期幾

         函數:dayname()

   6.16 查出給定的某周的某天的日期

   6.17 執行閏年計算

        閏年符合的條件:必須能夠被4整除

                        世紀元年除非同時能被400整除,不能用被100整除來判斷。

   6.18 接近但不是ISO格式的日期格式

   6.19 将日期或時間當成數值

        時間轉化為數值形式:在時間後加0,或者在一個數值上下文中使用時間值

   6.20 強制mysql将字元串當作時間值

   6.21 基于時間特性來查詢行

        即在WHERE語句中使用日期或時間條件。

7。排序查詢結果

   7.0 引言 排序的目的:使查詢結果有序并便于了解和檢查

   7.1 使用order by(按。。。排序)指令排序查詢結果

       資料預設查詢會亂序的原因:存儲資料是伺服器的工作,不一定就是順序的;且資料的增删改操作會打亂原來的索引順序。

                                 是以每次查詢出的資料順序可能不一樣,特别是資料變動後。

       要求:現實需求就是要查詢輸出有序資料,這樣才符合人類的習慣。

       方法:查詢時指定排序和排序規則;即order by

       order by特性:可以使用單獨一列或多列來排序。

                    預設是升序,也可以降序(DESC)。

                    可以使用别名來排序

                    隻有用order by指定的列才會排序;否則列是亂序的。

    7.2 使用表達式排序

        可以使用表達式來排序。

    7.3 顯示一組按照其他屬性排序的值

        即按照改變了資料類型的列來排序。比如輸出的是數值,但按“改變數值為字母”後字母來排序。                                    

    7.4 字元串排序的大小寫區分控制(資料庫的字段類型的collation問題。不過實際使用中使用資料庫預設的即可,或者指定一個以後就一直使用)

        方法:改變被排序數值的比較特征

        注意:二進制字元串是二進制序列,通過每個位元組的數字值比較來實作。

              非二進制字元串是collation列,通過預先定義的collation順序來實作字元和字元的對比。

              如果需要改變collation,則例: select name from mail order by name collate latin1_general_cs;

    7.5 基于日期的排序

        使用日期或時間資料類型排序即可。

    7.6 按月曆排序

        用函數把月曆中的需要排序的分解出即可。

        month() dayofmonth() dayofyear()

    7.7 按周曆排序

        函數: dayofweek() 該函數mysql預設按周日 周一 周二。。。排序)

              mod()轉換函數  mod(dayofweek(date)+5,7)=monday,....

       weekday() 周一為0,周二尾1,。。。(這個比較實用,符合常理)

    7.8 按時鐘排序

         函數:hour(date) minute(date)  second(date)

               time_to_sec(date)

    7.9 按資料列的子串排序

        用函數提取後排序

    7.10 按固定長度的子串排序

        用函數提取後排序:left()  mid() right()

    7.11 按可變長度的子串排序

        substring()  char_length()

    7.12 按域名順序排列主機名

         将主機名拆分,且将拆分部分從右到左排序

    7.13 按照數字順序排序點分式IP位址

         方法:拆分字元串,按數字順序排序各個資料片

               使用inet_aton()函數,把字元串IP轉換為數字。

    7.14 将數值移動到排序結果的頭部或尾部

        若為空則放在最大尾部: select val from t order by if(val is null,1,0),val

        若為空則放在最小頭部: select val from t order by if(val is null,0,1),val

    7.15 按照使用者定義排序

          函數:field(value,str1,str2,str3,str4) value會和這四個值比較,傳回1or2or3or4,就看哪個比對。若無比對則傳回0。

    7.16 排序枚舉數值

         enum(枚舉)數值不能像其他字元串一樣排序。因為enum被認為是字母,但實際上是按數字方式存儲的。如果想按字母排序,則用cast()函數轉換。

8.生成摘要

8.0 資料庫系統不僅能存儲和查詢資料,還可以以更簡要的方式生成摘要。

8.1 使用COUNT函數生成摘要

    缺點:大表的話速度會慢。

    彌補方法(Version>=5.0):

            select table_rows from information_schema.tables where

               table_schema='cookbook' and table_name='states';

       or   show table status;

8.2 使用MIN()和MAX()函數生成摘要

8.3 使用SUM()和AVG()數字函數生成摘要

8.4 使用DISTINCT函數消除重複

    使用COUNT(DISTINCT)來計數

8.5 查找數值相關的最大值和最小值

    把MIX MAX函數用在子查詢中。

8.6 控制MIN MAX函數的字元串大小寫區分

8.7 将摘要劃分為子群

    使用GROUP BY來分組

8.8 摘要與空值

    大部分聚類函數忽略NULL值

8.9 使用确定的特性選擇組群(即隻要部分聚類之後的資料)

    比如:SELECT COUNT(*),NAME FROM MAIL GROUP BY NAME HAVING COUNT(*)>3;

8.10 使用計數确定數值是否唯一

     聯合使用HAVING COUNT函數來确認是否唯一

8.11 使用表達式結果分組

     将表達式方到GROUP BY 子句中。

8.12 分類無類别的資料

     使用GROUP BY+表達式将這些數值分組

8.13 控制摘要顯示順序

     GROUP BY + ORDER BY

8.14 查找最小或最大的摘要數值

     在語句中增加LIMIT子句

8.15 基于日期的摘要

8.16 同時使用每一組的摘要和全體的摘要

     使用WITH ROLLUP函數在group by最後一行來彙總所有的摘要

8.17 生成包括摘要和清單的報告

9 擷取和使用中繼資料

9.0 引言

   中繼資料用來處理結果集的關系、表和庫的資訊、MYSQL伺服器的資訊。

   方法:用INFORMATION_SCHEMA庫,裡面有下列資訊:資料庫、表、列、字元集  

         用SHOW語句

9.1 擷取受語句影響的資料行數目

    有的發起語句的函數會傳回行數;

    有的需要自己調用單獨函數傳回。各種API語言不同。

9.2 擷取設定中繼資料的結果

    各種API語言不同。

9.3 确定一條語句是否生成了結果集

   檢查中繼資料中的資料列計數。若為0則無結果集。

9.4 使用中繼資料來格式化查詢輸出

9.5 列舉或檢查資料庫或表的擴充

    INFORMATION_SCHEMA庫中:SCHEMATA表裡是庫資訊;TABLES表裡是表資訊。

9.6 通路表資料列定義

    即看看一張表裡有那些列以及如何定義的。

    方法:從INFORMATION_SCHEMA的COLUMNS表裡查詢。

          用SHOW COLUMNS。

          用SHOW CREATE TABLE或MYSQLDUMP語句來顯示表結構的CREATE TABLE語句。

9.7 擷取ENUM和SET資料列資訊

9.8 在應用程式中使用表結構資訊

9.9 擷取伺服器中繼資料

    select version()

    select database()

    select user()

    select current_user()

    show global status

    show variables

9.10 編寫适合MYSQL伺服器版本的應用程式

9.11 确定預設資料庫

      DATABASE()

9.12 監測MYSQL伺服器

     SHOW VARIABLES

     SHOW STATUS

9.13 确定伺服器支援哪個存儲引擎

     show engines

10。資料導入和導出

  10.0引言:即不同格式資料的導入導出方法

 mysql原生工具集:導入 load data ; mysqlimport

                         導出 select ..into outfile;mysqldump

        導入的基本問題:

  記錄分隔符;

  域定界符;

  列的順序和數目;

  資料值是否需要進行驗證或重新格式化;

  null或空值如何處理。

 導出的基本問題相反:

 檔案格式:(常用的兩類)制表定界格式和逗号定界(CSV)格式

 10.1 使用LOAD DATA和mysqlimport導入資料(insert.txt裡字段分隔符為制表符,即TAB,記錄符是換行/r)

 load data local infile '../../mail.txt' into table table_name;

        mysqlimport --local cookbook mail.txt

  10.2 指定資料檔案位置

  load data --local指資料檔案在伺服器本地。

        load data 無local則按預設規則查找資料檔案:

  若給絕對路徑則直接讀取。

  若給的是相對路徑則從MYSQL預設庫的資料目錄下找。     

  10.3 指定資料檔案的結構(即不是預設的字段符和記錄分隔符)

  使用FIELDS和lines字句告訴load data如何解釋資料檔案。

  load data local infile 'mail.txt' into table mail /

   fields terminated by ':'/

   lines terminated by '/r';

            or  mysqlimport --local --fields-terminated-by=":" --line-terminated-by="/r" cookbook mail.txt

  10.4 處理引号和特殊字元

 要顯示地表示引用字元,用ENCLOSED BY 。

 要改變預設的轉義字元,用ESCAPED BY。

  10.5 導入CSV檔案

  load data local infile 'mail.txt' into table mail /

   fields terminated by ','/

   lines terminated by '/r/n';

            or  mysqlimport --local --fields-terminated-by="," --line-terminated-by="/r/n" cookbook mail.txt

  10.6 讀取不同作業系統的檔案

 unix: lines terminated by '/n';

 windows: lines terminated by '/r/n';

  10.7 處理重複的鍵值(即原表裡有重複資料時如何處理;否則會報錯)

 覆寫: load data local infile 'mail.txt' replace into table mail;

 忽略:  load data local infile 'mail.txt' ignore into table mail;

  10.8 擷取關于錯誤輸入資料的診斷資訊

       SHOW WARNINGS

  10.9 跳過資料檔案行(即跳過開頭的幾行)

 load data local infile 'mail.txt' into table mail ignore 3 lines;

  10.10 指定輸入列順序

 如原表列順序為a b c,而mail.txt裡内容對應列順序為b c a

  load data local infile 'mail.txt' into table mail (b,c,a)

  mysqlimport --local --columns=b,c,a cookbook mail.txt

  10.11 在插入輸入值之前對資料檔案進行預處理

 預處理用:用SET分開的一個或多個col_name=expr指派表達式

  10.12 忽略資料檔案列

 若多餘的列都在尾部,不管。預設LOAD會忽略它們,因為前面的列都和原庫表對上了。

 若多餘的列在中間,則在LOAD裡指定清單名,即把多餘的列指定到變量裡,不用這些變量。如:

  load data local infile 'mail.txt' into table mail fileds terminated by ':' (volum1,@dummy,volum2);

    mysqlimport --local --columns="volum1,@dummy,volum2" --fileds-terminated-by=":" cookbook mail.txt

  10.13 從MYSQL中導出查詢結果

 select * from mail into outfile '/tmp/out.txt' fileds terminated by ',' lines terminated by '/r/n';

 mysql -e "select * from mail" --skip-column-names cookbook > /tmp/out.txt

  10.14 将表導出為文本檔案

        mysqldump --no-create-info --tab=/tmp --fields-terminated-by="," cookbook mail

  10.15 以SQL格式導出表内容或定義

 mysqldump cookbook mail 〉/tmp/mail.sql

 mysqldump cookbook  〉/tmp/cookbook.sql

  10.16 将表或資料庫拷貝到另一個伺服器

 mysqldump cookbook mail 〉/tmp/mail.sql

 mysql test </tmp/mail.sql

      or mysqldump cookbook mail|mysql -h mysql2.test.com test

      or mysqldump cookbook mail|ssh  mysql2.test.com mysql test

  10.17 編寫出自己的導出程式

  10.18 将資料檔案從一種格式轉化為另一種格式

  10.19 提取和重排資料檔案列

  10.20 使用SQL模式來控制錯誤的輸入資料處理

  方法:在用戶端檢查;

  伺服器端設定MYSQL的SQL模式:set sql_mode='mode_value';

  設伺服器端置mysql全局模式:set global sql_mod='mode_value';

  10.21 驗證并轉接資料

  10.22 使用模式比對來驗證資料

  10.23 使用模式來比對廣泛的内容類型

  10.24 使用模式來比對數值

  10.25 使用模式來比對日期或時間

  10.26 使用模式來比對EMAIL位址或URL

  10.27 使用表中繼資料來驗證資料

  10.28 使用一個查找表來驗證資料

  10.29 将兩個數字的年份值轉化為四位形式

  10.30 驗證日期和時間合法性

  10.31 編寫時間處理工具

  10.32 使用不完整的日期

 mysql能夠用0代替确實的部分,以ISO格式表示它們。

  10.33 導入非ISO格式日期值(即導入非CCYY-MM-DD格式)

 load date local infile 'mail.txt' into table mail (name,@date,value) set date=str_to_date(@date,'%m/%d/%y');

  10.34 使用非ISO格式導出日期值

 可以使用别的程式處理導出後的資料;或者用DATE_FORMAT()函數來格式化。

  10.35 導入和導出NULL值

  10.36 根據資料檔案猜測表結構

 即有導入的檔案但庫裡無此表。

 方法:自己建表或寫程式自動識别并建表。

  10.37 在MYSQL和ACCESS之間交換資料

 方法:ACCESS作為用戶端,通過ODBC連接配接到MYSQL伺服器。

 or 自己動手ACCESS-〉TXT-〉MYSQL

  10.38 在mysql和ms excel之間交換資料

  10.39 将輸出結果導出為XML

 $mysql --xml -e "select * from mail;"

  10.40 将XML導入到MYSQL

  10.41 尾聲

11。生成和使用序列

  11.0 引言

 序列:即按順序産生的唯一值,代表唯一一個記錄。

 使用auto_increment列建立序列。

  11.1 建立一個序列列并生成序列值

 create table mail ( id int unsigned not null auto_increment,primary key(id), name varchar(30)...);

 注意:插入重複的auto_increment列時MYSQL會提示錯誤;

       auto_increment如被手工指定了值,下面行的auto_increment列會從它開始自增,會有斷層序列未被使用。

  11.2 為序列列選擇資料類型

 注意: auto_increment隻能作用于整數類型資料,如int,bigint,tinyint,smallint,mediumint.

  使用unsigned來避免出現負的auo_increment值。

  使用not null來避免出現null。

  auto_increment列必須能夠被索引。因為一個序列存在的目的就是提供一個唯一的标示,故使用primary key;若已經有primary key,則用unique(唯一)索引來確定唯一性。

  11.3 序列生成的行删除的效果

 删除行在不同的引擎下産生不同的結果:

  myisam or innodb引擎會機械單調增加序列号,不會使用已經删除的序列号。

  BDB引擎會自動調整序列行号,可以使用原來的序列号。

  11.4 查詢序列值

 方法:select max(id) from mail;

  插入資料後執行select last_insert_id();

  11.5 對一個已有的序列進行重新計數

 情況:序列有斷層,想重新計數。

 方法:删除該列後再增加該列。

  alter table mail drop id,add id int unsigned not null auto_increment first;

  11.6 擴充序列列的取值範圍(修改表結構)

 方法:設定列的類型為UNSIGNED(可以擴大一倍)

  增大列的資料類型 alter table mail modify id bigint not null auto_increment;

  11.7序列頂部數值的再使用

 使用alter table重置序列計數器

  11.8 確定各行按照給定順序重編号

  11.9 從某個特定值開始一個序列

 create table mail ( id int unsigned not null auto_increment,primary key(id)) auto_incremnet=100;...

  11.10 序列化一個未序列的表

 修改表結構即可:alter table mail add id int unsigned not null auto_increment,/

     add primary key (id);

  11.11 使用auto_increment欄來建立多重序列

 方法:把auto_increment列和其他列連結起來,使他們都是同一索引的一部分。

  ...primary key (name,id)

 注意:  如上例,ID必須是auto_increment;

         若name裡有null值,則應該建立unique(name,id)索引,因為primary key不能有null.

  11.12 管理多重并發auto_increment數值

  11.13 使用auto_increment值将表進行關聯

  11.14 将序列生成器用作計數器

 insert into booksales (titles,copies) /

  values('the Greater Trumps',last_insert_id(1))/

  on duplicate key update copies=last_insert_id(cpoies+1);

  11.15 建立循環序列

 使用divisio和modulo操作符生成循環元素

  11.16 按行順序輸出數列查詢

12。使用多重表

  12.0 引言 多表間的JOIN:内部連接配接inner join ;外部連結out join.

  12.1 在表中找到與另一個表中的行相比對的行

 select * from artist,painting where artist.a_id=painting.a_id;

 select * from artist inner join painting on artist.a_id=painting.a_id;

  若兩表的比對列名字相同且使用=操作符的話,可以用using(使用)來簡化:select * from artist inner join painting using(a_id);

  注意:on or using用來比對多個表;where用來限制哪些連接配接的行。

 三表内連接配接:select * from artist as a inner join painting as p on a.a_id=p.a_id inner join states as s on p.state=s.abbrev;

   select artist.name,count(painting.price),sum(painting.price),avg(painting.price) from artist inner join painting on artist.a_id=painting.a_id group by artist.name;

 内連接配接缺點:隻能顯示某個表中與其它表的值相比對的值産生結果。

      當要比較的列未被索引的時候速度慢。

  12.2 查找與其它表不比對的行

 使用外部連結:LEFT JOIN;RIGHT JOIN

 select artist.* from artist left join painting on artist.a_id = painting.a_id where painting.a_id IS NULL;

 select artist.* from painting right join artist on painting.a_id=artist.a_id where painting.a_id is null;

  12.3 将表與自身進行比較

 非JOIN語句:select a_id,title from painting where a_id=(select distinct a_id from painting where title="The Potato Eaters"

 INNER JOIN語句:select p2.a_id,p2.title from painting as p1 inner join painting as p2 on p1.a_id=p2.a_id where p1.title="The Potato Eaters";

  12.4 産生主從清單和摘要:即一對多

 select p.title,a.name from painting as p inner join artist as a on p.a_id=a.a_id order by p.title,a.name;

  12.5 枚舉多對多的關系:既多對多

 select t.name,t.year,t.wins,t.losses,p.name,p.city from euchre_team as t inner join euchre_link as l inner join euchre_player as p on t.id=l.team_id and p.id=l.player_id order by t.year,t.wins DESC,p.name;

 注意:join的表寫在一起,最後寫on連接配接表的條件,再用where設定行的條件。這樣寫思路清晰。

  12.6 查找每組行中含有最大或最小值的行

  12.7 計算隊伍排名

 select * from standings1 order by wins-losses DESC;

  12.8 使用連接配接補全或識别清單的缺口

  12.9 計算連續行的內插補點

  12.10 發現累計和與動态均值

  12.11 使用連接配接控制查詢輸出的順序

  12.12 在單個查詢中整合幾個結果集

 使用union(聯合)操作符将多個查詢結果整合為一個

 注意:union後的結果集列名和列的個數取決于第一個select語句所獲得的列名;

  預設情況下,union會消除重複記錄,除非union all;

  12.13 識别并删除失配或獨立行

 方法:使用LEFT JOIN。

  使用not in子查詢:select * from artist  where a_id not in (select a_id from painting);

  12.14 為不同資料庫間的表執行連接配接

 select * from 庫名.表名。。。

  12.15 同時使用不同的MYSQL伺服器

 方法:使用federated引擎的表,該類表能夠使MYSQL伺服器通路位于另一個mysql伺服器的表。

  or 為每個伺服器打開一個獨立的連接配接,然後手動将兩個表中的資訊結合起來。

  or 拷貝表到另一個伺服器後再操作。

  12.16 在程式中引用連接配接的輸出列名稱

 方法:在API中,将輸出的多列存儲到一個根據列名引用列值的資料結構中,再順序取出顯示。

13。統計技術

  13.0 引言

  13.1 計算描述統計

 通過計算一般的描述統計或概要統計特征以描述資料集。

  13.2 分組描述統計即:需要為感測資料中的每個子組生成描述統計

 方法:使用聚集函數,同時用GROUP BY子句将資料排列到合适的組中去。

  13.3 産生頻率分布

  13.4 計數缺失值即:資料集合并不完整,你需要找出缺失了多少值。

 計算集合衆空值出現的次數

  13.5 計算線性回歸和相關系數即:為兩個變量計算最小平方回歸線或表示它們之間關系強弱的相關系數

 方法:運用摘要函數計算所需要的項。

  13.6 生成随機數

 mysql的rand()函數

  13.7 随機化行集合

 使用order by rand(),如:select name from mail order by rand();

  13.8 從行集合中随機選擇條目

 方法:随機排列這些值,然後選擇第一個或前幾個。

  13.9 配置設定等級

 方法:确定一種分級方法然後使用該方法将值放入所期望的順序。

 set @rank=0,@prev_val=null;

 select @rank:=if(@prev_val=score,@rank,@rank+1) as rank,@prev_val:=score as score from t order by score DESC;

14。處理重複項

  14.0引言即處理那些不可接受的重複行。

  14.1防止表中發生重複

 使用primary key  or unique索引

  14.2 處理向表中裝載行時出現的重複錯誤

 使用insert ignore忽略 or replace 覆寫or insert ...on duplicate key update修改.

  14.3 計數和識别重複項

  14.4 從表中消除重複項

 方法: 從表中選擇具有唯一性的行并放入第二張表中,用它來替代原始表;

  用ALTER TABLE增加一個唯一性索引;

  用DELETE。。。LIMIT N來删除給定重複行集合中多餘的行。

  14.5 從自連接配接的結果中消除重複

15。執行事務

  15.0 引言

 使用事務原因:現實生活中,防止并發性和完整性的發生。

 事務特性:在事務執行過程中,别的用戶端不能更新事務中所使用的資料。防止了并發。

    隻有在事務中的語句都執行成功的情況下,它們才作為一個單元被聚合并送出,任何在發生錯誤前的操作都會被復原,以保證相關表沒有受影響。

  15.1 使用事務存儲引擎

 事務引擎:InnoDB  NDB  BDB

 檢查本MYSQL是否有支援事務的引擎:show engines;

 | MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance         |

 | MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables      |

 | InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys     |

 | MRG_MYISAM | YES     | Collection of identical MyISAM tables

  15.2 使用SQL執行事務

 使用start transaction(or begin)語句以挂起自動送出模式,然後發出組成事務的語句。若成功則用commit來結束事務。否則rollback復原。

 缺點:有些語句不能作為事務的一部分,如DROP DATABASE。

  15.3 在程式中執行事務

 若程式語言API提供事務術語則直接使用它;

 若無則使用常用語句釋出事務SQL語句,以直接利用普通資料庫調用的API。

  事務中的語句連同COMMIT操作被聚合在一個控制結構中;

  若控制結構的狀态顯示了沒有成功執行完畢,那麼事務會被復原。

  15.4 在PERL程式中使用事務

 使用标準DBI事務支援機制。

  15.5 在RUBY程式中使用事務

 使用标準DBI事務支援機制。

  15.6 在PHP程式中使用事務

 使用标準的PEAR DB事務支援機制

  使用autocommit()方法關閉auto-commit模式。在執行語句後,調用commit() or rollback以送出或會滾事務。

  15.7 在python程式中使用事務

 使用标準的DB-API事務支援機制

  15.8 在JAVA程式中使用事務

 使用标準的JDBC事務支援機制。

  15.9 使用事務的替代方法

 無事務的存儲引擎,事務的替代方法:如顯示地鎖定表。

  使用鎖來聚合語句:LOCK TABLE和UNLOCK TABLE

  使用重寫語句以避免事務:

16。使用存儲例程、觸發器和事件

   16.0引言

    存儲例程(函數和過程procedure [presi:dge]):

        存儲函數執行計算并傳回值,此傳回值可以用于表達式,用法類似RAND()、NOW()等。

        存儲過程隻執行不需要傳回值得計算,不能用于表達式,隻能被CALL語句調用。

    觸發器:觸發器被定義為當表被修改時産生動作的對象。可以用于insert,update delete語句。

    事件:事件是在預定時間執行SQL語句的對象。類似系統裡的計劃任務。

   16.1 建立複合語句對象

    問題:定義存儲例程 觸發器 事件時的語句結束符為;,與mysql預設的結束符相同,是以會報錯。

    方法:用delimiter(定界符)指令重新定義mysql語句結束符。

    如建函數:mysql>delimiter $$

        create function avg_mail_size (user varchar(8))

        returns float reads sql data

        begin

            if user is null then

                return (select avg(size) from mail);

            else

                return (select avg(size) from mail where srcuser =user);

            end if;

        end;

        $$

           mysql>delimiter ;

           mysql>select avg_mail_size(null),avg_mail_size('barb');

    如建存儲過程:

    mysql> delimiter //

    mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)

        -> BEGIN

            ->   SELECT COUNT(*) INTO param1 FROM t;

            -> END;

            -> //

        Query OK, 0 rows affected (0.00 sec)

        mysql> delimiter ;

        mysql> CALL simpleproc(@a);

        Query OK, 0 rows affected (0.00 sec)

        mysql> SELECT @a;

        +------+

        | @a   |

        +------+

        | 3    |

        +------+

        1 row in set (0.00 sec)

   16.2 使用存儲函數封裝計算

    使用存儲函數來隐藏讨厭的計算細節并使之更易執行

   16.3 使用存儲過程來“傳回”多個值

    存儲過程的參數可以有下面三類:IN(進)、OUT(出)、INOUT(可進可出)

    例如:create procedure mail_sender_stats(in user varchar(8),

                        out messages int,

                        out total_size float,

                        out avg_size float)

        ......

   16.4 用觸發器來定義動态的預設列值

    CREATE

        [DEFINER = { user | CURRENT_USER }]

        TRIGGER trigger_name trigger_time trigger_event

        ON tbl_name FOR EACH ROW trigger_stmt

   16.5 為其他日期和時間類型模拟TIMESTAMP屬性

   16.6 使用觸發器記錄表的變化

    例子(拍賣表)

    create table auction

    (

    id int unsigned not null auto_increment,

    ts timestamp,

    item varchar(30) not null,

    bid decimal(10,2) not null,

    primary key(id)

    );

    為了監測該表是以行的變化,建立日志表,使用觸發器記錄,如下:

    create table auction_log

    (

    action enmu('create','update','delete'),

    id int unsigned not null,

    ts timestamp,

    item varchar(30) not null,

    bid decimal(10,2) not null,

    index (id)

    );

    create trigger ai_auction after insert on auction for each row

        begin

        insert into auction_log (action,id,ts,item,bid) values('create',new.id,now(),new.item,new.bid);

        end

    create trigger au_auction after insert on auction for each row

        begin

        insert into auction_log (action,id,ts,item,bid) values('update',new.id,now(),new.item,new.bid);

        end

    create trigger ad_auction after insert on auction for each row

        begin

        insert into auction_log (action,id,ts,item,bid) values('delete',old.id,old.ts,old.item,old.bid);

        end        

   16.7 使用事件(event即定時器) 排程資料庫動作

    即建立周期性運作的資料庫操作,不需要使用者互動。

    方法:建立根據計劃執行的事件。

        create event event_name on schedule every 5 minute do insert into table_name(volum) values('...');

    檢查事件狀态:show variables like 'event_scheduler';

    手工激活事件:set global event_scheduler=1;

    永久激活事件: vi my.cnf

            [mysqld]

            event_scheduler=1

    删除事件:drop event event_name;

    停止事件:alter event event_name disable;

    重新激活事件:alter event event_name enable;

17。關于WEB應用中的MYSQL介紹

   17.0引言

   17.1 WEB頁面産生的基本原則

    即從教本中産生WEB頁面,而不是手工編寫。

   17.2 使用APACHE運作WEB腳本

    使用APACHE的cgi-bin執行腳本。

   17.3 使用TOMCAT運作WEB腳本

    使用JSP符号來編寫程式,在一個如TOMCAT的servlet容器中執行它。

   17.4 在WEB中輸出編碼特殊字元

    使用由你的API提供的方法來執行HTML編碼和URL編碼

18。在WEB頁面中混合查詢結果 (不同的開發語言不同的方法)

   18.0 引言 即格式化(段落、清單、表格、超連結、導航索引)輸出資料

   18.1 以段落文本顯示查詢結果

   18.2 以清單形式顯示查詢結果

   18.3 以表格形式顯示查詢結果

   18.4 将查詢結果顯示為超連結

   18.5 根據資料庫内容建立導航索引

   18.6 存儲圖檔或其他二進制資料

    使用LOAD_FILE()函數存儲圖檔

    使用腳本存儲圖檔

   18.7 檢索圖檔或其他二進制資料

   18.8 提供智語廣告

   18.9 提供可下載下傳的查詢結果

   18.10 使用模闆系統生成WEB頁面

    如ruby的pagetemplate和php的smarty。

19 。用MYSQL處理WEB輸入

   19.0引言

   19.1 編寫腳本生成WEB表單

    使用WEB表單 <form> </form>

   19.2 根據資料庫内容建構表單元素

   19.3 根據資料庫内容建構多取表單元素

   19.4 将一條資料庫記錄導入表單

   19.5 收集WEB輸入

   19.6 驗證WEB輸入

   19.7 将WEB輸入存入資料庫

    sql注入式攻擊的結果:mysql伺服器額外的負載;

                當腳本嘗試消化從MYSQL中傳回的結果集時,會引發記憶體溢出問題;

                當腳本把結果發送給用戶端時,消耗額外的網絡帶寬。

   19.8 處理檔案上傳

   19.9 執行搜尋并顯示結果

   19.10 生成上一頁和下一頁連結

   19.11 生成點選排序的表格頭單元

   19.12 WEB頁面通路計數

   19.13 WEB頁面通路日志

   19.14 使用mysql存儲apache日志

20。使用基于MYSQL的WEB會話管理

   20.0 引言

    會話管理問題:

        用戶端cookies;

        伺服器端cookies;

   20.1 在PERL應用程式中使用基于MYSQL的會話

    perl子產品: apache::session

   20.2 在ruby應用程式中使用基于mysql的存儲

    ruby子產品: CGI:sesson

   20.3 在PHP會話管理器中使用基于mysql的存儲

    預設php使用臨時檔案來備份存儲

   20.4 在TOMCAT中為會話支援存儲使用mysql

    配置server.xml檔案來設定jdbc參數。

繼續閱讀