创建和使用数据库
一旦知道如何输入SQL语句,就可以访问数据库了。
假设你家中有几只宠物(你的动物园),并且你希望跟踪有关它们的各种类型的信息。你可以通过创建表来保存数据并使用所需信息加载数据,然后,你可以通过从表中检索数据来回答有关你的动物的各种问题,本节介绍如何执行以下操作:
- 创建一个数据库
- 创建一个表
- 将数据加载到表中
- 以各种方式从表中检索数据
- 使用多个表
动物园数据库很简单(故意),但要想到可能使用类似数据库的真实情况并不困难。例如,农民可以使用这样的数据库跟踪牲畜,或由兽医跟踪患者记录,可以从MySQL网站获得包含以下部分中使用的一些查询和样本数据的menagerie发行版,它通过https://dev.mysql.com/doc/以压缩tar文件和Zip格式提供。
使用SHOW
语句查找服务器上当前存在的数据库:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
mysql数据库描述了用户访问权限,test
数据库通常可用作工作空间供用户试用。
语句显示的数据库列表可能在你的计算机上有所不同,如果你没有SHOW DATABASES
权限,SHOW DATABASES
不会显示你没有权限的数据库。
如果test
数据库存在,请尝试访问它:
mysql> USE test
Database changed
与QUIT
一样,USE
不需要分号(如果你愿意,你可以用分号终止这样的语句,它没有坏处)。USE
语句在另一方面也是特殊的:它必须在一行上给出。
对于后面的示例,你可以使用测试数据库(如果你有权访问它),但是你在该数据库中创建的任何内容都可以被其他任何有权访问它的人删除。因此,你可能应该要求MySQL管理员允许使用你自己的数据库,假设你想调用你的menagerie
,管理员需要执行如下语句:
mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';
其中your_mysql_name
是分配给你的MySQL用户名,your_client_host
是连接到服务器的主机。
创建和选择数据库
如果管理员在设置权限时为你创建数据库,则可以开始使用它,否则,你需要自己创建它:
mysql> CREATE DATABASE menagerie;
在Unix下,数据库名称区分大小写(与SQL关键字不同),因此你必须始终将数据库作为menagerie
引用,而不是Menagerie
、MENAGERIE
或其他一些变体,表名也是如此。在Windows下,此限制不适用,但你必须在给定查询中使用相同的大小写引用数据库和表,但是,由于各种原因,建议的最佳做法始终是使用创建数据库时使用的相同字母。
如果你尝试创建数据库时收到错误,例如
ERROR 1044 (42000): Access denied for user 'micah'@'localhost' to database 'menagerie'
,这意味着你的用户帐户没有必要的权限。
创建数据库不会选择它来使用,你必须明确地这样做,要使menagerie
成为当前数据库,请使用以下语句:
mysql> USE menagerie
Database changed
你的数据库只需创建一次,但每次开始mysql
会话时都必须选择它才能使用,你可以通过发出USE
语句来执行此操作,如示例中所示。或者,你可以在调用mysql
时在命令行上选择数据库,只需在你可能需要提供的任何连接参数之后指定其名称,例如:
shell> mysql -h host -u user -p menagerie
Enter password: ********
刚刚显示的命令中的
menagerie
不是你的密码,如果要在
-p
选项后的命令行上提供密码,则必须在没有中间空间的情况下执行此操作(例如,
-p
password,而不是
-p
password)。但是,建议不要在命令行中输入密码,因为这样做会让登录到你机器上的其他用户窥探密码。
你可以随时使用
SELECT DATABASE()
查看当前选择的数据库。
创建表
创建数据库很容易,但此时它是空的,正如SHOW TABLES
告诉你的那样:
mysql> SHOW TABLES;
Empty set (0.00 sec)
更难的部分是决定数据库的结构应该是什么:你需要哪些表以及每个表中应该包含哪些列。
你想要一张包含每只宠物记录的表,这可以称为pet
表,它至少应该包含每种动物的名字,因为名称本身不是很有趣,所以该表应包含其他信息。例如,如果你家中有多个人饲养宠物,你可能希望列出每只动物的主人,你可能还想记录一些基本的描述性信息,如物种和性别。
年龄怎么样?这可能是有意义的,但存储在数据库中并不是一件好事,随着时间的推移,年龄会发生变化,这意味着你必须经常更新你的记录。相反,最好存储固定值,如出生日期,然后,只要你需要年龄,你就可以将其计算为当前日期和出生日期之间的差值。MySQL提供了进行日期算术的功能,因此这并不困难,存储出生日期而不是年龄也有其他优点:
- 你可以使用数据库执行任务,例如为即将到来的宠物生日生成提醒。如果你认为这种类型的查询有些无聊,请注意,在业务数据库的上下文中,您可能会问同样的问题,以确定您需要向哪些客户发送当前周或当前月的生日祝福,以实现计算机辅助的个人接触。
- 你可以计算与当前日期以外的日期相关的年龄,例如,如果你将死亡日期存储在数据库中,则可以轻松计算宠物死亡时的年龄。
你可能会想到在pet
表中有用的其他类型的信息,但是到目前为止所识别的信息已经足够了:name
、owner
、species
、sex
、birth
和death
。
使用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
之间的任何长度,无论你认为哪个最合理。如果你做了一个糟糕的选择,后来发现你需要一个更长的字段,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
,例如,如果你忘记了表中列的名称或它们具有的类型。
将数据加载到表中
创建表后,你需要填充它,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
(反斜杠,大写N),例如,Whistler鸟的记录看起来像这样(值之间的空格是单个制表符):
Whistler Gwen bird \N 1997-12-09 \N
要将文本文件pet.txt
加载到pet
表中,请使用以下语句:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
如果你使用编辑器在Windows上创建文件,该编辑器使用\r\n
作为行终止符,则应使用此语句:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet
LINES TERMINATED BY '\r\n';
(在运行OS X的Apple计算机上,你可能希望使用LINES TERMINATED BY '\r'
)。
如果需要,可以在LOAD DATA
语句中显式指定列值分隔符和行结束标记,但默认值为制表符和换行符,这些语句足以使语句正确读取pet.txt
文件。
如果语句失败,则默认情况下你的MySQL安装可能没有启用本地文件功能。
如果要一次添加一条新记录,INSERT
语句很有用,在最简单的形式中,你按照CREATE TABLE
语句中列出的列的顺序为每列提供值。假设Diane得到了一只名为“Puffball”的新hamster,你可以使用INSERT
语句添加新记录,如下所示:
mysql> INSERT INTO pet
VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
字符串和日期值在此处指定为带引号的字符串,此外,使用INSERT,你可以直接插入NULL
以表示缺少的值,你不像使用LOAD DATA
那样使用\N
。
从这个示例中,你应该能够看到,最初使用多个INSERT
语句而不是单个LOAD DATA
语句来加载记录会涉及更多的输入。