Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103727968
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Mysql/postgreSQL

2008-05-11 17:36:53

3.4. 获得数据库和表的信息

如果你忘记数据库或表的名字,或给定的表的结构是什么(例如,它的列叫什么),怎么办?MySQL通过提供数据库及其支持的表的信息的几个语句解决这个问题。

你已经见到了SHOW DATABASES,它列出由服务器管理的数据库。为了找出当前选择了哪个数据库,使用DATABASE( )函数:

mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+

如果你还没选择任何数据库,结果是NULL

为了找出当前的数据库包含什么表(例如,当你不能确定一个表的名字),使用这个命令:

mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| event               |
| 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    |       |
+---------+-------------+------+-----+---------+-------+

Field显示列名字,Type是列的数据类型,Null表示列是否能包含NULL值,Key显示列是否被索引而Default指定列的默认值。

如果表有索引,SHOW INDEX FROM tbl_name生成有关索引的信息。

3.5. 在批处理模式下使用mysql

在前面的章节中,你交互式地使用mysql输入查询并且查看结果。你也可以以批模式运行mysql。为了做到这些,把你想要运行的命令放在一个文件中,然后告诉mysql从文件读取它的输入:
shell> mysql < batch-file

如果在Windows下运行mysql,并且文件中有一些可以造成问题的特殊字符,可以这样操作:

C:\> mysql -e "source batch-file"

如果你需要在命令行上指定连接参数,命令应为:

shell> mysql -h host -u user -p < batch-file
Enter password: ********

当这样操作mysql时,则创建一个脚本文件,然后执行脚本。

如果你想在语句出现错误的时候仍想继续执行脚本,则应使用--force命令行选项。

为什么要使用一个脚本?有很多原因:

  • 如果你需要重复运行查询(比如说,每天或每周),可以把它编成一个脚本,则每次执行时不必重新键入。
  • 可以通过拷贝并编辑脚本文件从类似的现有的查询生成一个新查询。
  • 当你正在开发查询时,批模式也是很有用的,特别对多行命令或多语句命令序列。如果你犯了一个错误,你不必重新输入所有内容,只需要编辑脚本来改正错误,然后告诉mysql再次执行脚本。
  • 如果你有一个产生多个输出的查询,你可以通过一个分页器而不是盯着它翻屏到屏幕的顶端来运行输出:
·                shell> mysql < batch-file | more
  • 你可以捕捉文件中的输出以便进行进一步的处理:
·                shell> mysql < batch-file > mysql.out
  • 你可以将脚本分发给另外的人,以便他们也能运行命令。
  • 某些情况不允许交互地使用,例如, 当你从一个cron任务中运行查询时。在这种情况下,你必须使用批模式。

当你以批模式运行mysql时,比起你交互地使用它时,其默认输出格式是不同的(更简明些)。例如,当交互式运行SELECT DISTINCT species FROM pet时,输出应为:

 

+---------+
| species |
+---------+
| bird    |
| cat     |
| dog     |
| hamster |
| snake   |
+---------+

但是当以批模式运行时,输出应为:

species
bird
cat
dog
hamster
snake

如果你想要在批模式中得到交互输出格式,使用mysql -t。为了回显以输出被执行的命令,使用mysql -vvv

你还可以使用源代码或 \.命令从mysql提示符运行脚本:

mysql> source filename;
mysql> \. filename

3.6. 常用查询的例子

下面是一些学习如何用MySQL解决一些常见问题的例子。

在一些例子中,使用数据库表“shop”来储存某个商人(经销商)的每件物品(物品号)的价格。假定每个商人对每项物品有一个固定价格,那么(物品,商人)即为该记录的主关键字。

启动命令行工具mysql并选择数据库:

shell> mysql your-database-name

(在大多数MySQL中,你可以使用test数据库)。

你可以使用以下语句创建示例表:

mysql> 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));
mysql> 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);

执行语句后,表应包含以下内容:

mysql> 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 |
+---------+--------+-------+

3.6.1. 列的最大值

“最大的物品号是什么?”

SELECT MAX(article) AS article FROM shop;

+---------+
| article |
+---------+
|       4 |
+---------+

3.6.2. 拥有某个列的最大值的行

任务:找出最贵物品的编号、销售商和价格。

这很容易用一个子查询做到:

SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop);

另一个解决方案是按价格降序排序所有行并用MySQL特定LIMIT子句只得到第一行:

SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;

:如果有多项最贵的物品( 例如每个的价格为19.95)LIMIT解决方案仅仅显示其中一个!

3.6.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 |
+---------+-------+

3.6.4. 拥有某个字段的组间最大值的行

任务:对每项物品,找出最贵价格的物品的经销商。

可以用这样一个子查询解决该问题:

SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article);

3.6.5. 使用用户变量

你可以清空MySQL用户变量以记录结果,不必将它们保存到客户端的临时变量中。(参见 9.3节,“用户变量”.)。

例如,要找出价格最高或最低的物品的,其方法是:

mysql> SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
mysql> SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+

3.6.6. 使用外键

MySQL中,InnoDB表支持对外部关键字约束条件的检查。参见15.2节,“InnoDB存储引擎”。还可以参见 1.8.5.5节,“外键”

只是联接两个表时,不需要外部关键字。对于除InnoDB类型的表,当使用REFERENCES tbl_name(col_name)子句定义列时可以使用外部关键字,该子句没有实际的效果,只作为备忘录或注释来提醒,你目前正定义的列指向另一个表中的一个列。执行该语句时,实现下面很重要:

·         MySQL不执行表tbl_name 中的动作,例如作为你正定义的表中的行的动作的响应而删除行;换句话说,该句法不会致使ON DELETEON UPDATE行为(如果你在REFERENCES子句中写入ON DELETEON UPDATE子句,将被忽略)。

·         该句法可以创建一个column;但不创建任何索引或关键字。

·         如果用该句法定义InnoDB表,将会导致错误。

你可以使用作为联接列创建的列,如下所示:

CREATE TABLE person (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name CHAR(60) NOT NULL,
    PRIMARY KEY (id)
);
 
CREATE TABLE shirt (
    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 person(id),
    PRIMARY KEY (id)
);
 
INSERT INTO person VALUES (NULL, 'Antonio Paz');
 
SELECT @last := LAST_INSERT_ID();
 
INSERT INTO shirt VALUES
(NULL, 'polo', 'blue', @last),
(NULL, 'dress', 'white', @last),
(NULL, 't-shirt', 'blue', @last);
 
INSERT INTO person VALUES (NULL, 'Lilliana Angelovska');
 
SELECT @last := LAST_INSERT_ID();
 
INSERT INTO shirt VALUES
(NULL, 'dress', 'orange', @last),
(NULL, 'polo', 'red', @last),
(NULL, 'dress', 'blue', @last),
(NULL, 't-shirt', 'white', @last);
 
SELECT * FROM person;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | Antonio Paz         |
|  2 | Lilliana Angelovska |
+----+---------------------+
 
SELECT * FROM shirt;
+----+---------+--------+-------+
| 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 person p, shirt s
 WHERE p.name LIKE 'Lilliana%'
   AND s.owner = p.id
   AND s.color <> 'white';
 
+----+-------+--------+-------+
| id | style | color  | owner |
+----+-------+--------+-------+
|  4 | dress | orange |     2 |
|  5 | polo  | red    |     2 |
|  6 | dress | blue   |     2 |
+----+-------+--------+-------+

按照这种方式使用,REFERENCES子句不会显示在SHOW CREATE TABLEDESCRIBE的输出中:

SHOW CREATE TABLE shirt\G
*************************** 1. row ***************************
Table: shirt
Create Table: CREATE TABLE `shirt` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`style` enum('t-shirt','polo','dress') NOT NULL,
`color` enum('red','blue','orange','white','black') NOT NULL,
`owner` smallint(5) unsigned NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

在列定义中,按这种方式使用REFERENCES作为注释或“提示”适用于表MyISAMBerkeleyDB

阅读(445) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~