[翻譯]MySQL5.0用戶手冊——第三章:快速入門
前一段時間翻譯了第一章的部分內容,可是人氣不旺,可能是因為第一章講概論性的東西提不起大家的興趣吧。
第二章是講怎樣安裝MySQL的,kai已經開始翻譯這章,我就不重復勞動了。
所以我決定翻譯第三章,來點實質性的東西。希望大家多多捧場。
目錄
3.1. 連接服務器和斷開連接
3.2. 輸入查詢語句
3.3. 創建和使用數據庫
3.3.1. 創建和選擇一個數據庫
3.3.2. 創建一個表
3.3.3. 向表中載入數據
3.3.4. 從表中提取數據
3.4. 獲得關於數據庫的表格的信息
3.5. 在批處理模式下使用 mysql
3.6. 常用示例
3.6.1. 查詢一列的最大值
3.6.2. 查詢一列的最大值所在的行的數據
3.6.3. 查詢一列中每一組的最大值
3.6.4. 查詢一列中每一組的最大值所在的行的數據
3.6.5. 使用自定義變量
3.6.6. 使用外鍵
3.6.7. 根據兩個鍵查詢
3.6.8. 計算每天的訪問量
3.6.9. 使用自動增量
3.7. 在Twin Project中查詢數據
3.7.1. 尋找所有未分開的雙胞胎
3.7.2. 顯示一個表示每一對雙胞胎的地位的表
3.8. 在Apache中使用MySQL
章提供了一個教程,該教程演示了如何通過mysql 客戶端程序來創建和使用一個簡單的數據庫。mysql (有時候稱作 “終端監視器” 或簡稱為 “監視器”) 是一個允許你連接到一個MySQL Server、運行查詢和查看看結果的交互程序。mysql 也可以以批處理方式運行: 你可以把查詢語句預先寫到一個文件中,然後讓mysql 執行該文件的內容。 使用mysql 的兩種方法這裡都會講到。
以--help 選項啟動mysql,可以查看它提供了哪些選項:
shell> mysql --help
本章假設mysql 已經安裝在你的機器上並且有一個可用的MySQL服務器能夠連接, 否則請聯系你的 MySQL 管理員。 (如果你就是管理員,請閱讀本手冊的相關章節,如Chapter 5, Database Administration。)
這一章描述了建立和使用一個數據庫的全過程, 如果你僅僅對存取一個已經存在數據庫感興趣, 可以跳過介紹創建數據庫和創建表的章節。
因為本章本質上是一個教程,所以許多細節已被省略。如果需要獲得更多信息,請查看本手冊的相關章節。
3.1. 連接服務器和斷開連接
在使用mysql連接服務器的時候,你通常需要提供一個 MySQL 用戶名,很有可能還需要一個密碼;如果服務器運行在遠程主機上,你還需要指定主機名。聯系你的管理員以找出你應該使用什麼樣的連接參數 ( 即,那個主機,用戶名和密碼 )。一旦你知道正確的參數,你應該這樣連接:
shell> mysql -h host -u user -p
Enter password: ********
host 和 user 代表MySQL 服務器運行的主機名 和你的 MySQL 帳戶的用戶名,請替換為適當的值。 ******** 代表你的密碼;當 mysql 顯示 Enter password: 提示時輸入它。
如果連接成功,你將看到mysql> 提示符後面顯示一些介紹信息:
shell> mysql -h host -u user -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 25338 to server version: 5.0.19-standard
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
mysql> 提示符說明mysql 已經准備好,你可以輸入命令。
如果你是在運行 MySQL服務器的機器上登陸, 你可以省略主機名,如下:
shell< mysql -u user -p
如果你試圖連接的時候得到如下錯誤信息ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2),這說明MySQL服務器守護進程(Unix) 或服務 (Windows) 沒有運行,請 聯系管理員或者查看Chapter 2, Installing MySQL 來解決問題。
獲得登錄時遇到的常見問題的幫助, 請查看 Section A.2, “Common Errors When Using MySQL Programs”.
有些MySQL安裝後可以允許用戶在本機上匿名登錄, 如果你的機器時這種情況,你可以不帶任何參數運行mysql來連接服務器:
shell> mysql
連接成功後,可以輸入QUIT (或者\q) 命令斷開與服務器的連接:
mysql> QUIT
Bye
在Unix系統, 也可以通過按下 Control-D來斷開連接。
下面章節的大部分例子都假設你已經連接到服務器,mysql> 提示符指明這一點。
3.2. 輸入查詢語句
確信你已經按照前面的方法連接到服務器。 連接服務器的時候沒有選擇要操作哪一個數據庫,從這點上講,學會如何發出查詢比直接跳到創建表、載入數據和讀出數據要重要些。這一章描述了輸入命令的基本原則,輸入幾個查詢語句,自己體會一下mysql 如何工作。
下面是一個簡單的命令,要求服務器告訴你它的版本號和當前日期。在 mysql> 提示後輸入命令並按回車鍵:
mysql> SELECT VERSION(), CURRENT_DATE;
+----------------+--------------+
| VERSION() | CURRENT_DATE |
+----------------+--------------+
| 5.0.7-beta-Max | 2005-07-11 |
+----------------+--------------+
1 row in set (0.01 sec)
mysql>
這個查詢說明如下幾點:
一個命令通常由一個SQL語句和一個分號組成。(一些特殊的情況下,分號也可以省略,比如QUIT就是其中一個,其它的情況以後還會遇到。)
當你發出一個命令,mysql 把它發送到服務器執行並顯示結果, 然後顯示mysql> 提示符指明可以輸入下一條命令。
mysql 以表格形式顯示查詢的結果, 第一行是每一列的標志,後面的行是查詢結果。 通常,列標志是你從數據庫中取出的數據的列名, 如果你查詢的值是一個表達式的運算結果(如下面的例子),mysql 會使用這個表達式作為這一列的標志。
mysql 顯示有多少行數據返回和執行這個查詢花了多少時間,讓你對服務器的性能有一個初步的印象。這些值是不精確的,因為它代表的是時鐘時間 (而不是CPU 時間或機器時間),它會受到服務器負載量和網絡延時的影響。(為了簡潔起見,下面的例子中有時將不再顯示 “rows in set”這一行。)
關鍵字不區分大小寫,下面的語句是等價的:
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;
下面的查詢語句說明可以把mysql 當成一個簡單的計算器:
mysql> SELECT SIN(PI()/4), (4+1)*5;
+------------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+------------------+---------+
| 0.70710678118655 | 25 |
+------------------+---------+
1 row in set (0.02 sec)
到目前,我們演示的都是簡單的,單行的語句,其實也可以在同一行中輸入多條語句,每個語句以分號隔開:
mysql> SELECT VERSION(); SELECT NOW();
+----------------+
| VERSION() |
+----------------+
| 5.0.7-beta-Max |
+----------------+
1 row in set (0.00 sec)
+---------------------+
| NOW() |
+---------------------+
| 2005-07-11 17:59:36 |
+---------------------+
1 row in set (0.00 sec)
一個命令也不是非要在一行裡面輸完,把一個語句分成多行輸入是沒有問題的,mysql 使用分號代表一個語句的結束,而不是把一行當成一個語句。 (換句話說,mysql 接受非常自由的輸入, 它收集所有的輸入知道看到分號的時候才執行。)
這是一個簡單的多行語句:
mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
+---------------+--------------+
| USER() | CURRENT_DATE |
+---------------+--------------+
| jon@localhost | 2005-07-11 |
+---------------+--------------+
在這個例子中,你可以注意到輸入一行未完成的命令後, mysql 的提示符從mysql>變成了->,指明命令沒有輸完。 提示符是我們的朋友,它提供非常有價值的反饋信息,通過這些信息,我們可以知道mysql 期待什麼輸入。
如果一個命令輸入了一部分,你卻不想執行了的話,可以鍵入\c取消:
mysql> SELECT
-> USER()
-> \c
mysql>
在這裡,也請注意提示符的變化, 在輸入 \c之後,提示符又變回mysql>, 提供反饋說明mysql 可以接受新的命令。
下面的表格總結了所有mysql 的提示符的意義:
提示符 意義
mysql> 准備接受新命令。
-> 等待一個多行命令的下一行。
'> 等待一個以單引號 (‘'’)開始的字符串的下一行。
"> 等待一個以單引號 (‘"')開始的字符串的下一行。
`> 等待一個以backtick (‘`’)開始的標識符的下一行。
/*> 等待一個以/*開始的注釋的下一行。
在 MySQL 5.0 系列中, /*> 提示符從 MySQL 5.0.6版開始提供。
我們經常會意外的遇到多行命令的情況,那就是當我們輸入一行語句後卻忘記了輸入分號。在這種情況下,mysql等待下一行的輸入:
mysql> SELECT USER()
->
如果你遇到這種情況 (你認為你已經輸完一個語句卻只得到一個-> 提示符),極有可能就是mysql 正在等待分號。 如果你沒有注意到提示符的變化,你可能就會傻坐著等。 只要輸入一個分號結束語句,mysql 就會執行它:
mysql> SELECT USER()
-> ;
+---------------+
| USER() |
+---------------+
| jon@localhost |
+---------------+
'> 和 "> 在輸入字符串的時候有時會出現 (換一句話說 MySQL 正在等待未完成的字符串)。 在MySQL中,你可以使用 ‘'’ 或 ‘"’字符來輸入字符串 (比如,'hello' 或 "goodbye"),而且mysql 能夠讓你輸入多行的字符串。 當你看到一個 '> 或 "> 提示符時,意味著你已經輸入了字符串開頭的引號,還沒有輸入結尾的引號,如果你確實正在輸入一個多行字符串,很好,但是果真如此嗎?不盡然。更常見的, '> 和 "> 提示符顯示你粗心地漏掉了一個引號字符。例如:
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
'>
如果你輸入該 SELECT 語句,然後按回車鍵並等待結果,什麼都沒有出現。“為什麼 該查詢這麼長呢?”,注意 "> 提示符提供的線索。它告訴你 mysql 期望見到一個未終止字符串的 余下部分。(你在語句中看見錯誤嗎?字符串 "Smith 正好缺少第二個引號。)
在這種情況下,該怎麼辦?最簡單的方法就是取消命令的執行, 但是,卻不能簡單地只輸入\c ,因為MySQL會認為這是字符串未完成的部分, 相反,我們應該先輸入一個引號 (這樣就可以告訴mysql 字符串我們已經輸完了)然後再輸入\c:
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
'> '\c
mysql>
提示符又變成了mysql>,說明mysql 可以接受下一條命令。
`> 提示符和'> 以及">提示符相似, 只不過指明的是你沒有完成acktick-quoted 標識符的輸入。
知道'>, ">,和`> 的標識符的意義是非常重要的, 為如果你錯誤地輸入一個未終止的字符串,你下一步輸入的任何行好象都將要被mysql忽略 — 包括包含QUIT命令的行。 如果你不知道在輸入其它命令之前好要先中止引號的話,這將搞得你一頭霧水。
.3. 創建和使用數據庫
3.3.1. 創建和選擇一個數據庫
3.3.2. 創建一個表
3.3.3. 向表中載入數據
3.3.4. 從表中提取數據
現在已經知道了怎樣輸入命令,是操作數據庫的時候了。
假設你家(動物園)裡有許多寵物,並且你希望能夠跟蹤它們的信息,你可以創建一個表,把你需要的信息輸入表中,通過從表中提取數據,你就可以回答關於你的寵物的各種各樣的問題。這一節將演示怎樣做到下面的這些事情:
創建一個數據庫
創建一個表
向表中輸入數據
用不同的方法從表中獲得數據
使用多個表
這裡的動物園數據庫是簡單的 (故意的),但是不難想象在現實生活中有許多情況需要使用類似的數據庫,比如,一個農場主可以使用一個類似的數據庫來管理他的家畜, 或者一個獸醫用來管理病畜記錄。 這裡使用到的動物園數據庫中,包含其中的數據和查詢語句,都可以在 MySQL 的網站上找到,同時提供 tar 壓縮(http://www.mysql.com/Downloads/Contrib/Examples/menagerie.tar.gz) 和 Zip 壓縮 (http://www.mysql.com/Downloads/Contrib/Examples/menagerie.zip) 兩種格式的文件下載。
使用 SHOW 語句找出目前在服務器上存在哪些數據庫:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
這個數據庫的列表在你的機器上可能是不同的,但基本都會包含mysql和test數據庫。mysql 數據庫是必須的,因為它保存了用戶訪問權限的數據, test 數據庫經常作為一個工作區提供給用戶試試身手。
注意,你有可能看不到所有的數據庫,如果你沒有SHOW DATABASES 權限。請查看Section 13.5.1.3, “GRANT Syntax”.
如果test 數據庫存在,嘗試訪問它:
mysql> USE test
Database changed
這裡請注意USE命令和QUIT命令一樣,不需要分號結尾。 (你使用分號結尾也沒有影響。) USE 語句還有一個特別的地方: 它只能作為單行輸入。
你可以使用test 數據庫 (只要你有訪問它的權限) 來練習下面的例子,但是你在這個數據庫中創建的任何東西都可以被其他訪問這個數據庫的人刪掉,所以,你應該向你的 MySQL 管理員要求允許你使用一個自己的數據庫,假設你想給你的數據庫取名為menagerie, 管理員需要執行一個這樣的命令:
mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';
這裡your_mysql_name 是分配給你的 MySQL 用戶名,your_client_host 是你連接服務器所使用的機器的機器名。
3.3.1. 創建和選擇一個數據庫
如果管理員在給你分配權限的時候創建了這個數據庫,你就可以直接使用了, 否則,你需要自己創建它:
mysql> CREATE DATABASE menagerie;
在 Unix系統中,數據庫名是區分大小寫的 (不像 SQL 關鍵字),因此你必須總是以 menagerie 引用你的數據庫,不是 Menagerie 、 MENAGERIE 或其他變種。 這條規則對表名也適用。 (在Windows中,這個限制不適用, 盡管你必須在同一個查詢中使用同樣的大小寫來引用數據庫和表。 由於這些原因,我們建議的最佳做法就是引用數據庫和表的時候使用和創建它們時同樣的大小寫。)
Note: 如果你得到ERROR 1044 (42000): Access denied for user 'monty'@'localhost' to database 'menagerie' when attempting to create a database的錯誤信息, 說明你的用戶帳戶不具備進行這個操作的權限。告訴你的管理員或者查看Section 5.8, “The MySQL Access Privilege System”.
創建數據庫後不會自動把它當成當前數據庫使用, 你必須明確的選擇它。 要使menagerie 成為當前數據庫, 使用如下命令:
mysql> USE menagerie;
Database changed
你的數據庫只需要創建一次, 但是每次啟動mysql 會話的時候都需要選擇它。你可以使用上面介紹的 USE 語句來選擇數據庫, 也可以在運行 mysql的時候通過命令行參數選擇數據庫,只需要在所有命令行參數之後指定數據庫名就可以:
shell> mysql -h host -u user -p menagerie
Enter password: ********
請注意,如上命令行中的menagerie 可不是你的密碼喲,如果你想在命令行中的-p 選項中提供密碼,你必須不加任何空格, (比如,是-pmypassword,而不是-p mypassword)。然而,不建議把密碼放在命令行中,因為會直接把明文暴露給使用你機器的其它用戶。
3.3.2. 創建一個表
創建數據庫很容易是吧,但它現在還是空的,可以用SHOW TABLES 查看:
mysql> SHOW TABLES;
Empty set (0.00 sec)
較難的部分是設計數據庫的結構:數據庫中包含哪些表和每個表中包含哪些列。
我們現在需要的是一個保存寵物記錄的表, 可以給這個表取名為pet , 而且這個表最少也要包含每個動物的名字,但是僅僅只包含名字卻沒有什麼意思,我們還要一些其它的信息。 比如,如果你家有多個人養寵物的話,你就可以給每個動物指定一個主任,還可以記錄一些象種類和性別這樣的信息。
年齡呢? 你肯定很關心這個信息,但是把它儲存到數據庫中卻並不是一個好主意,因為年齡是隨著時間變化的,你需要不斷的更新你的數據庫。一個更好的辦法就是儲存動物的生日,當你需要年齡的時候,你可以根據當前時間和生日進行計算, MySQL 提供了進行時間計算的函數,所以要做到這一點並不難。 存儲生日而不是年齡還有以下幾個好處:
你可以讓數據庫在寵物的生日即將來臨的時候提醒你, (不要認為這個思路很無聊,在商業應用中,有很多時候需要在每個星期或每個月給要過生日的客戶發出生日祝福,它們本質上是一樣的。)
你可以根據相對日期而不是當前日期來計算年齡, 比如,你在數據庫中儲存了動物的死亡日期, 你就可以非常容易的計算出動物是在多大的時候死的。
你還可以給 pet 表添加其他有用的信息,但是到目前為止這些已經足夠了:名字、主人、種類,性別、出生和死亡日期。
使用CREATE TABLE 語句來指定你的表的結構:
mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
-> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
VARCHAR 類型用於儲存name, owner, 和 species 列是比較合適的, 因為這些列中的數據是變長的。 這個定義不要求你這一列的數據長度豆一樣,也不需要都是20。你可以選擇1 到 65535之間的任何長度,只要你認為這個長度合適。 (Note: 在 MySQL 5.0.3以前,最大限制是 255。)如果你剛開始的選擇不合理,以後需要較長的字段, 可以用MySQL 提供的ALTER TABLE 語句修改。
動物的性別可以用多種方法表示, 比如'm' 和 'f'或者'male' and 'female'。使用單個字符'm' 和 'f'是最簡單的。
使用DATE 數據類型來保存birth和death 列的數據是比較合適的。
創建表以後,在使用SHOW TABLES 將產生如下輸出:
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet |
+---------------------+
驗證創建的表是否符合我們的設計,使用 DESCRIBE 語句:
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | date | YES | | NULL | |
| death | date | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
我們可以在任何時候使用DESCRIBE , 比如,當我們忘記某以列的名字或者它的數據類型時。
要獲得更多關於 MySQL 數據類型的信息,請查看Chapter 11, Data Types.
3.3.3. 向表中載入數據
創建表之後,就需要向表中填入數據,用 LOAD DATA 和 INSERT 語句可以做到。
假設你的寵物信息如下表所示。 (請注意觀察,MySQL 的日期數據應該用 'YYYY-MM-DD' 的格式輸入, 有些人的習慣可能跟這不同。)
name owner species sex birth death
Fluffy Harold cat f 1993-02-04
Claws Gwen cat m 1994-03-17
Buffy Harold dog f 1989-05-13
Fang Benny dog m 1990-08-27
Bowser Diane dog m 1979-08-31 1995-07-29
Chirpy Gwen bird f 1998-09-11
Whistler Gwen bird 1997-12-09
Slim Benny snake m 1996-04-29
因為現在數據表表是空的,所以向表中載入數據的簡單做法就是把這些數據保存到文本文件中,然後使用一個語句把這個文本文件的內容加載到數據表中。
我們可以創建一個pet.txt 文本文件,它的每一行包含一條記錄,每個值按照CREATE TABLE 語句中給出的順序排列,並且用跳格符隔開,對於遺失的數據 ( 例如未知的性別,或仍然活著的動物的死亡日期 ),你可以使用NULL 值,在文本文件中,使用\N (backslash, capital-N)表示。 例如, Whistler 鳥的數據看起來象這樣 (這些值之間的空白是單個的跳格符):
name owner species sex birth death
Whistler Gwen bird \N 1997-12-09 \N
把文本文件pet.txt into 載入到pet 表,使用如下命令:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
請注意,如果你是在Winows系統上創建的文本文件,並且文字編輯器使用\r\n 作為一行的結束,你應該使用如下語句:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet
-> LINES TERMINATED BY '\r\n';
(在運行 OS X操作系統的蘋果機上,你很有可能需要使用LINES TERMINATED BY '\r'。)
你可以在LOAD DATA語句中明確指出每列數據和每行數據之間的分隔符, 默認是跳格符和換行符。
如果該語句運行失敗,極有可能是你的 MySQL 默認的配置為不接受從本地文件載入數據。 請查看Section 5.7.4, “Security Issues with LOAD DATA LOCAL”, 獲得更改該默認配置的信息。
如果希望一次添加一條記錄,可以INSERT語句,該語句最簡單的用法中, 你只需要按照CREATE TABLE 語句中定義列的順序為每一列指定數據即可。 假設 Diane新養了一只名叫 “Puffball.”的倉鼠, 你可以使用 INSERT 語句向表中添加一條記錄:
mysql> INSERT INTO pet
-> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
注意,這裡的字符串和日期都是以用引號括起來的字符串的形式輸入的, 而且在INSERT語句中,你可以直接插入NULL表示遺失的數據,而不是象LOAD DATA語句中使用 \N 。
從這個例子中可以看出, 一開始就使用多個INSERT 語句載入數據,比使用單個LOAD DATA語句載入數據,敲起鍵盤來要麻煩的多。