?? manual_tutorial.html
字號:
+---------+
| article |
+---------+
| 4 |
+---------+
</pre>
<h3><a NAME="example-Maximum-row" HREF="manual_toc.html#example-Maximum-row">8.3.2
擁有某個列的最大值的行</a></h3>
<p>“找出最貴的文章的編號、商人和價格”</p>
<p>在ANSI-SQL中這很容易用一個子查詢做到: </p>
<pre>SELECT article, dealer, price
FROM shop
WHERE price=(SELECT MAX(price) FROM shop)
</pre>
<p>在<strong>MySQL</strong>中(還沒有子查詢)就用2步做到:
<ol>
<li>用一個<code>SELECT</code>語句從表中得到最大值。 </li>
<li>使用該值編出實際的查詢: <pre>SELECT article, dealer, price
FROM shop
WHERE price=19.95
</pre>
</li>
</ol>
<p>另一個解決方案是按價格降序排序所有行并用<strong>MySQL</strong>特定<code>LIMIT</code>子句只得到的第一行:
</p>
<pre>SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1
</pre>
<p><strong>注意</strong>:如果有多個最貴的文章( 例如每個19.95)<code>,LIMIT</code>解決方案僅僅顯示他們之一!
</p>
<h3><a NAME="example-Maximum-column-group" HREF="manual_toc.html#example-Maximum-column-group">8.3.3
列的最大值:按組:只有值</a></h3>
<p>“每篇文章的最高的價格是什么?” </p>
<pre>SELECT article, MAX(price) AS price
FROM shop
GROUP BY article
+---------+-------+
| article | price |
+---------+-------+
| 0001 | 3.99 |
| 0002 | 10.99 |
| 0003 | 1.69 |
| 0004 | 19.95 |
+---------+-------+
</pre>
<h3><a NAME="example-Maximum-column-group-row" HREF="manual_toc.html#example-Maximum-column-group-row">8.3.4
擁有某個字段的組間最大值的行</a></h3>
<p>“對每篇文章,找出有最貴的價格的交易者。” </p>
<p>在<code>ANSI SQL</code>中,我可以用這樣一個子查詢做到: </p>
<pre>SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article)
</pre>
<p>在<strong>MySQL</strong>中,最好是分幾步做到:
<ol>
<li>得到一個表(文章,maxprice)。見<a HREF="manual_Tutorial.html#example-Maximum-column-group-row">8.3.4
擁有某個域的組間最大值的行</a>。 </li>
<li>對每篇文章,得到對應(yīng)于存儲最大價格的行。 </li>
</ol>
<p>這可以很容易用一個臨時表做到: </p>
<pre>CREATE TEMPORARY TABLE tmp (
article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
price DOUBLE(16,2) DEFAULT '0.00' NOT NULL);
LOCK TABLES article read;
INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;
SELECT article, dealer, price FROM shop, tmp
WHERE shop.article=tmp.articel AND shop.price=tmp.price;
UNLOCK TABLES;
DROP TABLE tmp;
</pre>
<p>如果你不使用一個<code>TEMPORARY</code>表,你也必須鎖定“tmp”表。 </p>
<p>“它能一個單個查詢做到嗎?” </p>
<p>是的,但是只有使用我稱之為“MAX-CONCAT詭計”的一個相當(dāng)?shù)托У脑幱嫞?
</p>
<pre>SELECT article,
SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer,
0.00+LEFT( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price
FROM shop
GROUP BY article;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0001 | B | 3.99 |
| 0002 | A | 10.99 |
| 0003 | C | 1.69 |
| 0004 | D | 19.95 |
+---------+--------+-------+
</pre>
<p>最后例子當(dāng)然能通過在客戶程序中分割連結(jié)的列使它更有效一點。
</p>
<h3><a NAME="example-Foreign_keys" HREF="manual_toc.html#example-Foreign_keys">8.3.5
使用外鍵</a></h3>
<p>不需要外鍵聯(lián)結(jié)2個表。 </p>
<p><code>MySQL</code>唯一不做的事情是<code>CHECK</code>以保證你使用的鍵確實在你正在引用表中存在,并且它不自動從有一個外鍵定義的表中刪除行。如果你象平常那樣使用你的鍵值,它將工作得很好!
</p>
<pre>CREATE TABLE persons (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE shirts (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,
PRIMARY KEY (id)
);
INSERT INTO persons VALUES (NULL, 'Antonio Paz');
INSERT INTO shirts VALUES
(NULL, 'polo', 'blue', LAST_INSERT_ID()),
(NULL, 'dress', 'white', LAST_INSERT_ID()),
(NULL, 't-shirt', 'blue', LAST_INSERT_ID());
INSERT INTO persons VALUES (NULL, 'Lilliana Angelovska');
INSERT INTO shirts VALUES
(NULL, 'dress', 'orange', LAST_INSERT_ID()),
(NULL, 'polo', 'red', LAST_INSERT_ID()),
(NULL, 'dress', 'blue', LAST_INSERT_ID()),
(NULL, 't-shirt', 'white', LAST_INSERT_ID());
SELECT * FROM persons;
+----+---------------------+
| id | name |
+----+---------------------+
| 1 | Antonio Paz |
| 2 | Lilliana Angelovska |
+----+---------------------+
SELECT * FROM shirts;
+----+---------+--------+-------+
| id | style | color | owner |
+----+---------+--------+-------+
| 1 | polo | blue | 1 |
| 2 | dress | white | 1 |
| 3 | t-shirt | blue | 1 |
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
| 7 | t-shirt | white | 2 |
+----+---------+--------+-------+
SELECT s.* FROM persons p, shirts s
WHERE p.name LIKE 'Lilliana%'
AND s.owner = p.id
AND s.color &lt;&gt; 'white';
+----+-------+--------+-------+
| id | style | color | owner |
+----+-------+--------+-------+
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
+----+-------+--------+-------+
</pre>
<h2><a NAME="Database_use" HREF="manual_toc.html#Database_use">8.4
創(chuàng)造并使用一個數(shù)據(jù)庫</a></h2>
<p>既然你知道怎樣輸入命令,現(xiàn)在是存取一個數(shù)據(jù)庫的時候了。 </p>
<p>假定在你的家(你的“動物園”)中有很多寵物,并且你想追蹤關(guān)于他們各種各樣類型的信息。你可以通過創(chuàng)建表來保存你的數(shù)據(jù)并根據(jù)所需要的信息裝載他們做到,然后你可以通過從表中檢索數(shù)據(jù)來回答關(guān)于你的動物不同種類的問題。本節(jié)顯示如何做到所有這些事情:
<ul>
<li>怎樣創(chuàng)建一個數(shù)據(jù)庫</li>
<li>怎樣創(chuàng)建一個數(shù)據(jù)庫表</li>
<li>怎樣裝載數(shù)據(jù)到數(shù)據(jù)庫表</li>
<li>怎樣以各種方法從表中檢索數(shù)據(jù)</li>
<li>怎樣使用多個表</li>
</ul>
<p>動物園數(shù)據(jù)庫將會是簡單的(故意的),但是不難把它想象成可能用到相似類型數(shù)據(jù)庫的真實世界情況。例如,這樣的一個數(shù)據(jù)庫能被一個農(nóng)夫用來追蹤家畜,或由一個獸醫(yī)追蹤病畜記錄。
</p>
<p>使用<code>SHOW</code>語句找出在服務(wù)器上當(dāng)前存在什么數(shù)據(jù)庫: </p>
<pre>mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
</pre>
<p>數(shù)據(jù)庫列表可能在你的機器上是不同的,但是<code>mysql</code>和<code>test</code>數(shù)據(jù)庫很可能的在其間。<code>mysql</code>是必需的,因為它描述用戶存取權(quán)限,<code>test</code>數(shù)據(jù)庫經(jīng)常作為一個工作區(qū)提供給用戶試試身手。
</p>
<p>如果<code>test</code>數(shù)據(jù)庫存在,嘗試存取它: </p>
<pre>mysql> USE test
Database changed
</pre>
<p>注意,<code>USE</code>,類似<code>QUIT</code>,不需要一個分號。(如果你喜歡,你可以用一個分號終止這樣的語句;這無礙)<code>USE</code>語句在使用上也有另外一個特殊的地方:它必須在一個單行上給出。
</p>
<p>你可列在后面的例子中使用<code>test</code>數(shù)據(jù)庫(如果你能訪問它),但是你在該數(shù)據(jù)庫創(chuàng)建的任何東西可以被與訪問它的其他人刪除,為了這個原因,你可能應(yīng)該詢問你的<strong>MySQL</strong>管理員許可你自己使用的一個數(shù)據(jù)庫。假定你想要調(diào)用你的<code>menagerie</code>,管理員需要執(zhí)行一個這樣的命令:
</p>
<pre>mysql> GRANT ALL ON menagerie.* TO your_mysql_name;
</pre>
<p>這里<code>your_mysql_name</code>是分配給你的<strong>MySQL</strong>用戶名。 </p>
<h3><a NAME="Creating_database" HREF="manual_toc.html#Creating_database">8.4.1
創(chuàng)建并選用一個數(shù)據(jù)庫</a></h3>
<p>如果在設(shè)置你的權(quán)限時,管理員為你創(chuàng)建了數(shù)據(jù)庫,你可以開始使用它。否則,你需要自己創(chuàng)建它:
</p>
<pre>mysql> CREATE DATABASE menagerie;
</pre>
<p>在Unix下,數(shù)據(jù)庫名字是區(qū)分大小寫的(不像SQL關(guān)鍵詞),因此你必須總是以<code>menagerie</code>引用你的數(shù)據(jù)庫,不是<code>Menagerie</code>、<code>MENAGERIE</code>或一些其他變種。對表名也是這樣的。(在Windows下,該限制不適用,盡管你必須在一個給定的查詢中使用同樣的大小寫來引用數(shù)據(jù)庫和表。)</p>
<p>創(chuàng)建了一個數(shù)據(jù)庫并不選定以使用它,你必須明確地做這件事。為了使<code>menagerie</code>稱為當(dāng)前的數(shù)據(jù)庫,使用這個命令:
</p>
<pre>mysql> USE menagerie
Database changed
</pre>
<p>你的數(shù)據(jù)庫只需要創(chuàng)建一次,但是你必須在每次啟動一個<code>mysql</code>會話時為使用而選擇它。你可以由發(fā)出上面一個<code>USE</code>語句做到。另外,當(dāng)你調(diào)用時<code>mysql</code>,你可在命令行上選擇數(shù)據(jù)庫,就在你可能需要提供的任何連接參數(shù)之后指定其名字。例如:
</p>
<pre>shell> mysql -h host -u user -p menagerie
Enter password: ********
</pre>
<p>注意,<code>menagerie</code>不是你在剛才所示命令的口令。如果你想要在命令行上在<code>-p</code>選項后提供你的口令,你必須做到?jīng)]有多余的空格(例如,如<code>-pmypassword</code>,不是<code>-p
mypassword</code>)。然而,不建議把你的口令放在命令行上,因為這樣做把它暴露出來,能被在你的機器上登錄的其他用戶窺探到。
</p>
<h3><a NAME="Creating_tables" HREF="manual_toc.html#Creating_tables">8.4.2
創(chuàng)建一個數(shù)據(jù)庫表</a></h3>
<p>創(chuàng)建數(shù)據(jù)庫是容易的部分,但是在這時它是空的,正如<code>SHOW
TABLES</code>將告訴你: </p>
<pre>mysql> SHOW TABLES;
Empty set (0.00 sec)
</pre>
<p>較難的部分是決定你的數(shù)據(jù)庫結(jié)構(gòu)應(yīng)該是什么:你將需要什么數(shù)據(jù)庫表,和在他們中有什么樣的列。
</p>
<p>你將需要一個包含你每個寵物的記錄的表。它可稱為<code>pet</code>表,并且它應(yīng)該包含,最少,每個動物的名字。因為名字本身不是很有趣,表應(yīng)該包含另外的信息。例如,如果在你豢養(yǎng)寵物的家庭有超過一個人,你可能想要列出每個動物的主人。你可能也想要記錄例如種類和性別的一些基本的描述信息。
</p>
<p>年齡呢?那可能有趣,但是在一個數(shù)據(jù)庫中存儲不是一件好事情。年齡隨著時間流逝而變化,這意味著你將要不斷地更新你的記錄。相反,
存儲一個固定值例如生日比較好,那么,無論何時你需要年齡,你可以以當(dāng)前日期和出生日期之間的差別來計算它。<strong>MySQL</strong>為日期運算提供了函數(shù),因此這并不困難。存儲出生日期而非年齡也有其他優(yōu)點:
<ul>
<li>你可以將數(shù)據(jù)庫用于這樣的任務(wù)例如生成即將到來的寵物生日的提示。(如果你認為這類查詢是點蠢,注意,這與在一個商務(wù)數(shù)據(jù)庫來標(biāo)示你不久要給它發(fā)出生日祝賀的客戶的環(huán)境中是同一個問題,因為計算機幫助私人聯(lián)絡(luò)。)</li>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -