荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: georgehill (清风浮云 人生), 信区: Linux
标  题: mysql8
发信站: BBS 荔园晨风站 (Fri Nov 17 15:56:33 2000), 站内信件

【 以下文字转载自 georgehill 的信箱 】
【 原文由 georgehill.bbs@fb2000.dhs.org 所发表 】
寄信人: deardragon.bbs@bbs.whnet.edu.cn
标  题: mysql8
发信站: 快意灌水站 BBS 信差
来  源: from bbs.whnet.edu.cn (bbs.whnet.edu.cn [202.112.20.132])
日  期: Fri Nov 17 01:05:57 2000

发信人: hzh (网络飞翔), 信区: PHP
标  题: mysql8
发信站: 武汉白云黄鹤站 (Tue May 30 18:16:24 2000), 站内信件

MySQL中文参考手册
译者:晏子 (clyan@sohu.com)      主页:http://linuxdb.yeah.net
----------------------------------------------------------------------------
----
第一章, 前一章, 下一章, 最后一章,目录.
----------------------------------------------------------------------------
----
8 MySQL教程
本章通过演示如何使用mysql客户程序创造和使用一个简单的数据库,提供一个MySQL的
入门教程。mysql(有时称为“终端监视器”或只是“监视”)是一个交互式程序,允许
你连接一个MySQL服务器,运行查询并察看结果。mysql可以用于批模式:你预先把查询
放在一个文件中,然后告诉mysql执行文件的内容。使用mysql的两个方法都在这里涉及

为了看清由mysql提供的一个选择项目表了,用--help选项调用它:
shell> mysql --help
本章假定mysql已经被安装在你的机器上,并且有一个MySQL服务器你可以连接。如果这
不是真的,联络你的MySQL管理员。(如果你是管理员,你将需要请教这本手册的其他章
节。)
本章描述建立和使用一个数据库的全过程。如果你仅仅对存取一个已经存在数据库感兴
趣,你可能想要跳过描述怎样创建数据库及它所包含的表的章节。
既然本章本质上是一个教程,许多细节有必要被省略。对于这里所涉及的话题的更多信
息,咨询本手册的相关章节。
8.1 连接与断开服务者
为了连接服务器,当你调用mysql时,你通常将需要提供一个MySQL用户名和很可能,一
个口令。如果服务器运行在不是你登录的一台机器上,你也将需要指定主机名。联系你
的管理员以找出你应该使用什么连接参数进行连接(即,那个主机,用户名字和使用的口
令)。一旦你知道正确的参数,你应该能象这样连接:
shell> mysql -h host -u user -p
Enter password: ********
********代表你的口令;当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 459 to server version: 3.22.20a-log
Type 'help' for help.
mysql>
提示符告诉你mysql准备为你输入命令。
一些MySQL安装允许用户以“anoymous”(匿名)用户连接在本地主机上运行的服务器。如
果在你的机器是这种情况,你应该能通过没有任何选项地调用mysql与该服务器连接:
shell> mysql
在你成功地连接后,你可以在mysql>提示下打入QUIT随时断开:
mysql> QUIT
Bye
你也可以键入control-D断开。
在下列章节的大多数例子都假设你连接到服务器。由mysql>提示指明他们。
8.2 输入查询
确保你连接上了服务器,如在先前的章节讨论的。这样做本身将不选择任何数据库来工
作,但是那很好。从这点讲,知道关于如何出询问的一点知识,比马上跳至创建表、给
他们装载数据并且从他们检索数据要来的重要写。本节描述输入命令的基本原则,使用
几个查询,你能尝试让自己mysql是如何工作的。
这是一个简单的命令,要求服务器告诉你它的版本号和当前日期。在mysql>提示打入如
下命令并按回车键:
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| version()    | CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19   |
+--------------+--------------+
1 row in set (0.01 sec)
mysql>
这询问说明关于mysql几件事:
一个命令通常由SQL语句组成,随后有一个分号。(有一些例外不需要一个分号。早先提
到的QUIT是他们之一。我们将以后看到其它。)
当你发出一个命令时,mysql发送它给服务器并显示结果,然后打出另外一个mysql>显示
它准备好接受另外的命令。
mysql以一张表格(行和列)显示查询输出。第一行包含列的标签,随后的行是询问结果。
通常, 列标签是你取自数据库表的列的名字。如果你正在检索一个表达式而非表列的值
(如刚才的例子),mysql用表达式本身标记列。
mysql显示多少行被返回,和查询花了多长执行,它给你提供服务器性能的一个大致概念
。因为他们表示时钟时间(不是 CPU 或机器时间),并且因为他们受到诸如服务器负载和
网络延时的影响,因此这些值是不精确的。(为了简洁,在本章剩下的例子中不再显示
“集合中的行”。)
关键词可以以任何大小写字符被输入。下列询问是等价的:
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.707107 |      25 |
+-------------+---------+
至今显示的命令是相当短的,单行语句。你甚至能在单行上输入多条语句,只是以一个
分号结束每一条:
mysql> SELECT VERSION(); SELECT NOW();
+--------------+
| version()    |
+--------------+
| 3.22.20a-log |
+--------------+
+---------------------+
| NOW()               |
+---------------------+
| 1999-03-19 00:15:33 |
+---------------------+
一个命令不必全在一个单独行给出,所以需要多行的较长命令不是一个问题。mysql通过
寻找终止的分号而不是寻找输入行的结束来决定你的语句在哪儿结束。(换句话说,my
sql接受自由格式输入:它收集输入行但执行他们直到它看见分号。)
这里是一个简单的多行语句的例子:
mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+--------------------+--------------+
| USER()             | CURRENT_DATE |
+--------------------+--------------+
| joesmith@localhost | 1999-03-18   |
+--------------------+--------------+
在这个例子中,在你输入一个多行查询的第一行后,要注意提示符如何从mysql>变为->
,这正是mysql如何指出它没见到完整的语句并且正在等待剩余的部分。提示符是你的朋
友,因为它提供有价值的反馈,如果你使用该反馈,你将总是知道mysql正在等待什么。

如果你决定,你不想要执行你在输入过程中输入的一个命令,打入\c取消它:
mysql> SELECT
    -> USER()
    -> \c
mysql>
这里也要注意提示符,在你打入\c以后,它切换回到mysql>,提供反馈以表明mysql准备
接受一个新命令。
下表显示出你可以看见的各个提示符并总结他们意味着mysql在什么状态下:
提示符 意思
mysql>  准备好接受新命令
->  等待多行命令的下一行
'>  等待下一行,收集以单引号(“'”)开始的字符串
">  等待下一行,收集以双引号(“"”)开始的字符串
当你打算在一个单行上发出一个命令时,多行语句通常“偶然”出现,但是忘记终止的
分号。在这种情况中,mysql等待进一步输入:
mysql> SELECT USER()
    ->
如果这发生在你身上(你认为你输完了语句但是唯一的反应是一个->提示符),很可能my
sql正在等待分号。如果你没有注意到提示符正在告诉你什么,在认识到你需要做什么之
前,你可能花一会儿时间呆坐在那儿。进入一个分号完成语句,并且mysql将执行它:
mysql> SELECT USER()
    -> ;
+--------------------+
| USER()             |
+--------------------+
| joesmith@localhost |
+--------------------+
'>和">提示符出现在在字符串收集期间。在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准备好接受一个新命令了。
知道'>和">提示符意味着什么是很重要的,因为如果你错误地输入一个未终止的字符串
,任何比你下一步输入的行好象将要被mysql忽略--包括包含QUIT的行!这可能相当含糊
,特别是在你能取消当前命令前,如果你不知道你需要提出终止引号。
8.3 常用查询的例子
下面是一些学习如何用MySQL解决一些常见问题的例子。
一些例子使用数据库表“shop”,包含某个商人的每篇文章(物品号)的价格。假定每个
商人的每篇文章有一个单独的固定价格,那么(物品,商人)是记录的主键。
你能这样创建例子数据库表:
CREATE TABLE shop (
 article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 dealer  CHAR(20)                 DEFAULT ''     NOT NULL,
 price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),
(3,'D',1.25),(4,'D',19.95);
好了,例子数据是这样的:
SELECT * FROM shop
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | A      |  3.45 |
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | B      |  1.45 |
|    0003 | C      |  1.69 |
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+
8.3.1 列的最大值
“最大的物品号是什么?”
SELECT MAX(article) AS article FROM shop
+---------+
| article |
+---------+
|       4 |
+---------+
8.3.2 拥有某个列的最大值的行
“找出最贵的文章的编号、商人和价格”
在ANSI-SQL中这很容易用一个子查询做到:
SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop)
在MySQL中(还没有子查询)就用2步做到:
用一个SELECT语句从表中得到最大值。
使用该值编出实际的查询:
SELECT article, dealer, price
FROM   shop
WHERE  price=19.95
另一个解决方案是按价格降序排序所有行并用MySQL特定LIMIT子句只得到的第一行:
SELECT article, dealer, price
FROM   shop
ORDER BY price DESC
LIMIT 1
注意:如果有多个最贵的文章( 例如每个19.95),LIMIT解决方案仅仅显示他们之一!
8.3.3 列的最大值:按组:只有值
“每篇文章的最高的价格是什么?”
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 |
+---------+-------+
8.3.4 拥有某个字段的组间最大值的行
“对每篇文章,找出有最贵的价格的交易者。”
在ANSI SQL中,我可以用这样一个子查询做到:
SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article)
在MySQL中,最好是分几步做到:
得到一个表(文章,maxprice)。见8.3.4 拥有某个域的组间最大值的行。
对每篇文章,得到对应于存储最大价格的行。
这可以很容易用一个临时表做到:
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;
如果你不使用一个TEMPORARY表,你也必须锁定“tmp”表。
“它能一个单个查询做到吗?”
是的,但是只有使用我称之为“MAX-CONCAT诡计”的一个相当低效的诡计:
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 |
+---------+--------+-------+
最后例子当然能通过在客户程序中分割连结的列使它更有效一点。
8.3.5 使用外键
不需要外键联结2个表。
MySQL唯一不做的事情是CHECK以保证你使用的键确实在你正在引用表中存在,并且它不
自动从有一个外键定义的表中删除行。如果你象平常那样使用你的键值,它将工作得很
好!
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 |
+----+-------+--------+-------+
8.4 创造并使用一个数据库
既然你知道怎样输入命令,现在是存取一个数据库的时候了。
假定在你的家(你的“动物园”)中有很多宠物,并且你想追踪关于他们各种各样类型的
信息。你可以通过创建表来保存你的数据并根据所需要的信息装载他们做到,然后你可
以通过从表中检索数据来回答关于你的动物不同种类的问题。本节显示如何做到所有这
些事情:
怎样创建一个数据库
怎样创建一个数据库表
怎样装载数据到数据库表
怎样以各种方法从表中检索数据
怎样使用多个表
动物园数据库将会是简单的(故意的),但是不难把它想象成可能用到相似类型数据库的
真实世界情况。例如,这样的一个数据库能被一个农夫用来追踪家畜,或由一个兽医追
踪病畜记录。
使用SHOW语句找出在服务器上当前存在什么数据库:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+
数据库列表可能在你的机器上是不同的,但是mysql和test数据库很可能的在其间。mys
ql是必需的,因为它描述用户存取权限,test数据库经常作为一个工作区提供给用户试
试身手。
如果test数据库存在,尝试存取它:
mysql> USE test
Database changed
注意,USE,类似QUIT,不需要一个分号。(如果你喜欢,你可以用一个分号终止这样的
语句;这无碍)USE语句在使用上也有另外一个特殊的地方:它必须在一个单行上给出。

你可列在后面的例子中使用test数据库(如果你能访问它),但是你在该数据库创建的任
何东西可以被与访问它的其他人删除,为了这个原因,你可能应该询问你的MySQL管理员
许可你自己使用的一个数据库。假定你想要调用你的menagerie,管理员需要执行一个这
样的命令:
mysql> GRANT ALL ON menagerie.* TO your_mysql_name;
这里your_mysql_name是分配给你的MySQL用户名。
8.4.1 创建并选用一个数据库
如果在设置你的权限时,管理员为你创建了数据库,你可以开始使用它。否则,你需要
自己创建它:
mysql> CREATE DATABASE menagerie;
在Unix下,数据库名字是区分大小写的(不像SQL关键词),因此你必须总是以menagerie
引用你的数据库,不是Menagerie、MENAGERIE或一些其他变种。对表名也是这样的。(
在Windows下,该限制不适用,尽管你必须在一个给定的查询中使用同样的大小写来引用
数据库和表。)
创建了一个数据库并不选定以使用它,你必须明确地做这件事。为了使menagerie称为当
前的数据库,使用这个命令:
mysql> USE menagerie
Database changed
你的数据库只需要创建一次,但是你必须在每次启动一个mysql会话时为使用而选择它。
你可以由发出上面一个USE语句做到。另外,当你调用时mysql,你可在命令行上选择数
据库,就在你可能需要提供的任何连接参数之后指定其名字。例如:
shell> mysql -h host -u user -p menagerie
Enter password: ********
注意,menagerie不是你在刚才所示命令的口令。如果你想要在命令行上在-p选项后提供
你的口令,你必须做到没有多余的空格(例如,如-pmypassword,不是-p mypassword)。
然而,不建议把你的口令放在命令行上,因为这样做把它暴露出来,能被在你的机器上
登录的其他用户窥探到。
8.4.2 创建一个数据库表
创建数据库是容易的部分,但是在这时它是空的,正如SHOW TABLES将告诉你:
mysql> SHOW TABLES;
Empty set (0.00 sec)
较难的部分是决定你的数据库结构应该是什么:你将需要什么数据库表,和在他们中有
什么样的列。
你将需要一个包含你每个宠物的记录的表。它可称为pet表,并且它应该包含,最少,每
个动物的名字。因为名字本身不是很有趣,表应该包含另外的信息。例如,如果在你豢
养宠物的家庭有超过一个人,你可能想要列出每个动物的主人。你可能也想要记录例如
种类和性别的一些基本的描述信息。
年龄呢?那可能有趣,但是在一个数据库中存储不是一件好事情。年龄随着时间流逝而
变化,这意味着你将要不断地更新你的记录。相反, 存储一个固定值例如生日比较好,
那么,无论何时你需要年龄,你可以以当前日期和出生日期之间的差别来计算它。MySQ
L为日期运算提供了函数,因此这并不困难。存储出生日期而非年龄也有其他优点:
你可以将数据库用于这样的任务例如生成即将到来的宠物生日的提示。(如果你认为这
类查询是点蠢,注意,这与在一个商务数据库来标示你不久要给它发出生日祝贺的客户
的环境中是同一个问题,因为计算机帮助私人联络。)
你可以相对于日期而不止是当前日期来计算年龄。例如,如果你在数据库存储死亡日期
,你能容易计算一只宠物是何时多大死的。
你可能想到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到255的任何长度,无论哪个对你来
说好象最合理。(如果你做了较差的选择,以后会变得你需要一个更长的字段,MySQL提
供一个ALTER TABLE语句。)
动物性表可以用许多方法表示,例如,"m"和"f",或也许"male"和"female"。使用单个
字符"m"和"f"是最简单的。
为birth和death列使用DATE数据类型是相当明显的选择。
既然你创建了一个表,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,例如,如果你忘记在你表中的列的名字或他们是什么类型。
8.4.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  1998-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”,每行包含一个记录,用定位符(tab)把值分开,
并且以在CREATE TABLE语句中列出的列次序给出。对于丢失的值(例如未知的性别,或仍
然活着的动物的死亡日期),你可以使用NULL值。为了在你的文本文件表示这些,使用\
N。例如,对Whistler鸟的记录看起来像这样的(这里在值之间的空白是一个单个的定位
字符):
Whistler  Gwen  bird  \N  1997-12-09  \N
为了装载文本文件“pet.txt”到pet表中,使用这个命令:
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
如果你愿意,你能明确地在LOAD DATA语句中指出列值的分隔符和行尾标记,但是缺省是
定位符和换行符。这些对争取读入文件“pet.txt”的语句是足够的。
当你想要一次增加一个新记录时,INSERT语句是有用的。在它最简单的形式,你为每一
列提供值,以列在CREATE TABLE语句被列出的顺序。假定Diane把一只新仓鼠命名为Puf
fball,你可以使用一个这样INSERT语句增加一条新记录:
mysql> INSERT INTO pet
    -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
注意,这里字符串和日期值被指定为引号扩起来的字符串。另外,用INSERT,你能直接
插入NULL代表不存在的值。你不能使用\N,就像你用LOAD DATA做的那样。
从这个例子,你应该能看到涉及很多的键入用多个INSERT语句而非单个LOAD DATA语句装
载你的初始记录。
8.4.4 从一个数据库表检索信息
SELECT语句被用来从一张桌子拉出信息。语句的一般格式是:
SELECT what_to_select
FROM which_table
WHERE conditions_to_satisfy
what_to_select指出你想要看到的,这可以是列的一张表,或*表明“所有的列”。whi
ch_table指出你想要从其检索数据的表。WHERE子句是可选的,如果它在,conditions_
to_satisfy指定行必须满足的检索条件。
8.4.4.1 选择所有数据
SELECT最简单的形式是从一张表中检索每样东西:
mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name     | owner  | species | sex  | birth      | death      |
+----------+--------+---------+------+------------+------------+
| Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
| Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
| Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
| Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
| Bowser   | Diane  | dog     | m    | 1998-08-31 | 1995-07-29 |
| Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
| Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
| Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
| Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
+----------+--------+---------+------+------------+------------+
如果你想要考察整个表,这种形式的SELECT是很有用的。例如,在你刚刚给它装载了你
的初始数据集装以后。当它发生时,刚才显示的输出揭示了在你的数据文件的一个错误
:在Bowser死了以后,它好象要出生了!请教你原来的家谱,你发现正确的出生年是19
89,而不是1998。
至少有一些修正它的方法:
编辑文件“pet.txt”改正错误,然后使用DELETE和LOAD DATA弄空表并且再次装载它:
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
然而, 如果你这样做,你必须重新输入Puffball记录。
用一个UPDATE语句仅修正错误记录:
mysql> UPDATE pet SET birth = "1989-08-31" WHERE name = "Bowser";
如上所示,检索整个表是容易的,但是一般你不想那样做,特别地当表变得很大时。相
反,你通常对回答一个特别的问题更感兴趣,在这种情况下你在你想要的信息上指定一
些限制。让我们看一些他们回答有关你宠物的问题的选择查询。
8.4.4.2 选择特定行
你能从你的表中只选择特定的行。例如,如果你想要验证你对Bowser的出生日期所做的
改变,像这样精选Bowser的记录:
mysql> SELECT * FROM pet WHERE name = "Bowser";
+--------+-------+---------+------+------------+------------+
| name   | owner | species | sex  | birth      | death      |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
输出证实年份现在正确记录为1989,而不是1998。
字符串比较通常是大小些无关的,因此你可以指定名字为"bowser"、"BOWSER"等等,查
询结果将是相同的。
你能在任何列上指定条件,不只是name。例如,如果你想要知道哪个动物在1998以后出
生的,测试birth列:
mysql> SELECT * FROM pet WHERE birth >= "1998-1-1";
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
+----------+-------+---------+------+------------+-------+
你能组合条件,例如,找出雌性的狗:
mysql> SELECT * FROM pet WHERE species = "dog" AND sex = "f";
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
上面的查询使用AND逻辑操作符,也有一个OR操作符:
mysql> SELECT * FROM pet WHERE species = "snake" OR species = "bird";
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL  |
| Slim     | Benny | snake   | m    | 1996-04-29 | NULL  |
+----------+-------+---------+------+------------+-------+
AND和OR可以混用。如果你这样做,使用括号指明条件应该如何被分组是一个好主意:
mysql> SELECT * FROM pet WHERE (species = "cat" AND sex = "m")
    -> OR (species = "dog" AND sex = "f");
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
8.4.4.3 选择特定列
如果你不想要看到你的表的整个行,就命名你感兴趣的列,用逗号分开。例如,如果你
想要知道你的动物什么时候出生的,精选name和birth列:
mysql> SELECT name, birth FROM pet;
+----------+------------+
| name     | birth      |
+----------+------------+
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Buffy    | 1989-05-13 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+
找出谁拥有宠物,使用这个查询:
mysql> SELECT owner FROM pet;
+--------+
| owner  |
+--------+
| Harold |
| Gwen   |
| Harold |
| Benny  |
| Diane  |
| Gwen   |
| Gwen   |
| Benny  |
| Diane  |
+--------+
然而,注意到查询简单地检索每个记录的owner字段,并且他们中的一些出现多次。为了
使输出减到最少,通过增加关键词DISTINCT检索出每个唯一的输出记录:
mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner  |
+--------+
| Benny  |
| Diane  |
| Gwen   |
| Harold |
+--------+
你能使用一个WHERE子句把行选择与列选择相结合。例如,为了只得到狗和猫的出生日期
,使用这个查询:
mysql> SELECT name, species, birth FROM pet
    -> WHERE species = "dog" OR species = "cat";
+--------+---------+------------+
| name   | species | birth      |
+--------+---------+------------+
| Fluffy | cat     | 1993-02-04 |
| Claws  | cat     | 1994-03-17 |
| Buffy  | dog     | 1989-05-13 |
| Fang   | dog     | 1990-08-27 |
| Bowser | dog     | 1989-08-31 |
+--------+---------+------------+
8.4.4.4 排序行
你可能已经注意到前面的例子中结果行没有以特定的次序被显示。然而,当行以某个有
意义的方式排序,检验查询输出通常是更容易的。为了排序结果,使用一个ORDER BY子
句。
这里是动物生日,按日期排序:
mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name     | birth      |
+----------+------------+
| Buffy    | 1989-05-13 |
| Bowser   | 1989-08-31 |
| Fang     | 1990-08-27 |
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Slim     | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy   | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
为了以逆序排序,增加DESC(下降 )关键字到你正在排序的列名上:
mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name     | birth      |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Claws    | 1994-03-17 |
| Fluffy   | 1993-02-04 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Buffy    | 1989-05-13 |
+----------+------------+
你能在多个列上排序。例如,按动物的种类排序,然后按生日,首先是动物种类中最年
轻的动物,使用下列查询:
mysql> SELECT name, species, birth FROM pet ORDER BY species, birth DESC;
+----------+---------+------------+
| name     | species | birth      |
+----------+---------+------------+
| Chirpy   | bird    | 1998-09-11 |
| Whistler | bird    | 1997-12-09 |
| Claws    | cat     | 1994-03-17 |
| Fluffy   | cat     | 1993-02-04 |
| Fang     | dog     | 1990-08-27 |
| Bowser   | dog     | 1989-08-31 |
| Buffy    | dog     | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim     | snake   | 1996-04-29 |
+----------+---------+------------+
注意DESC关键词仅适用于紧跟在它之前的列名字(birth);species值仍然以升序被排序

8.4.4.5 日期计算
MySQL提供几个函数,你能用来执行在日期上的计算,例如,计算年龄或提取日期的部分

为了决定你的每个宠物有多大,用出生日期和当前日期之间的差别计算年龄。通过变换
2个日期到天数,取差值,并且用365除(在一年里的天数):
mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 FROM pet;
+----------+-------------------------------------+
| name     | (TO_DAYS(NOW())-TO_DAYS(birth))/365 |
+----------+-------------------------------------+
| Fluffy   |                                6.15 |
| Claws    |                                5.04 |
| Buffy    |                                9.88 |
| Fang     |                                8.59 |
| Bowser   |                                9.58 |
| Chirpy   |                                0.55 |
| Whistler |                                1.30 |
| Slim     |                                2.92 |
| Puffball |                                0.00 |
+----------+-------------------------------------+
尽管查询可行,关于它还有能被改进的一些事情。首先,如果行以某个次序表示,其结
果能更容易被扫描。第二,年龄列的标题不是很有意义的。
第一个问题通过增加一个ORDER BY name子句按名字排序输出来解决。为了处理列标题,
为列提供一个名字以便一个不同的标签出现在输出中(这被称为一个列别名):
mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age
    -> FROM pet ORDER BY name;
+----------+------+
| name     | age  |
+----------+------+
| Bowser   | 9.58 |
| Buffy    | 9.88 |
| Chirpy   | 0.55 |
| Claws

--
※ 来源:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 211.69.195.74]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 210.38.240.158]
--
※ 转寄:·快意灌水站 fb2000.dhs.org·[FROM: 210.39.3.50]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.115]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店