蓝派网(www.lan27.com)-精选网络资源,分享和交流! 文章首页站内搜索在线手册广告代码酷站欣赏万年历
您现在的位置: 蓝派网 >> 文章中心 >> 数据库 >> Mysql >> 正文

MySQL教程(三)

作者:佚名    文章来源:网络    更新时间:2007-5-30 15:41:36
此时,可看到能够电子化地完成学分记录,且在赋予学分等级时不必做各种乏味的手工计算。但是,在考虑了如何实际在一个数据库中表示学分信息后,又会被怎样抽象和拆分组成学分信息的表示难住了。自然会产生一个问题:“根本不使用数据库可能会更好一些?或许MySQL不适合我?”正如您所猜测的那样,笔者将从否定的方面对这个问题进行回答,否则这本书就没必要再往下写了。不过,在考虑如何做一件工作时,应考虑各种情况并提问是否最好不使用数据库系统(如MySQL)而使用一些别的东西(如电子表格等):
■ 学分簿有行和列,而电子表格也有。这使学分簿和电子表格在概念上和外观上都非常类似。
■ 电子表格能够完成计算,可以利用一个计算字段来累计每个学生的学分。但是,要对测验和测试进行加权可能有点麻烦,但这也是可以办得到的。另一方面,如果希望只查看某部分数据(如只查看学分或测试),进行诸如男孩与女孩的比较,或以一种灵活的方式显示合计信息等,情况又大有不同了。电子表格的功能显得要差一些,而关系数据库系统完成这些工作相当容易。另外要考虑的一点是为了在关系数据库中进行表示而对数据进行抽象和分解,这个问题并不真的那么难以应付。只要考虑安排数据库使其不会以一种对您希望做的事无意义的方式来表示数据即可。但是,在确定了表示方式之后,就要靠数据库引擎来协调和表示数据了。您肯定不会希望将它视为一堆支离破碎的东西。
例如,在从score 表中检索学分时,不希望看到事件ID;但希望看到日期。这没有什么问题。数据库将会根据事件ID 从event 表中查找出日期。您还可能想要看看是测验的学分或测试的学分。这也不成问题。数据库将用相同的方法查找出学分类型,也是利用事件ID。请记住,这就是如像MySQL这样的关系数据库的优势所在,即,使一样东西与另一样东西相关联,以便从多个来源得出信息并以您实际想看到的形式提供出来。在学分保存数据的情况中,MySQL确实利用事件ID 将信息组合到了一起,而无需人工来完成这件事。
现在我们先来看看,如何使MySQL完成这种将一个东西与另一个东西相联系的工作。
假定希望看到1999年9月2 3号的学分,针对某个特定日期中给出的事件的学分查询如下所示:

相当吓人,是吗?这个查询通过将score 表的记录与event 表的记录连接(关联)来检索学生名、日期、学分和学分的类型。其结果如下所示:

您肯定注意到了,它与图1-4 中给出的表设计相同,而且不需要知道事件ID 就可得出这个结果,只需指出感兴趣的日期并让MySQL查找出哪个学分记录具有该日期即可。如果您一直担心抽象和分解会使我们损失一些东西的话,看到这个世界,就不会有这种担心了。
当然,在考虑过查询后,您还可能对其他别的东西产生担心。即,这个查询看上去有点长并且也有点复杂;是不是做了很多工作写出这样的东西只是为了查找某个给定日期的学分?是的,确实是这样。但是,在每次想要发布一个查询时,有几种方法可以避免键入多行的SQL。一般情况下,一旦您决定如何执行这样一个查询并将它保存起来后,就可以按需要多次执行它。我们将在1. 5节“与mysql交互的技巧”中介绍怎样完成这项工作。
在上述查询的介绍中,我们有点超前了。不过,这个查询比起我们要实际用来得出学分的查询是有点简单了。原因是,我们还要对表的设计作更多的修改。我们将采用一个唯一的学生ID,而不在score 表中记录学生名。(即,我们将使用来自学分簿的“ ID”列的值而不是来自“ Name”列的值。)然后,创建另一个称为student 的表来存放name 和student_id 列(见图1- 7)。

为什么要作出这种修改呢?只有一个原因,可能有两个学生有相同的名字。采用唯一的学生ID 号可帮助区分他们的学分。(这与利用唯一的事件ID 而不是日期来分辨出相同日期的测试或测验完全类似。)在对表的设计作了这样的修改后,实际用来获得给定日期的学分查询变得更为复杂了一些,这个查询如下:

如果您不能立即清楚地读懂这个查询的意思的话,也不必担心。在进一步深入这个教程之后,就能看懂这个查询了。将会从图1- 7中注意到,在student 表中增加了点学分簿中没有的东西。它包含了一个性别列。这便可以做一些简单的事情,如对班级中男孩和女孩的人数计数;也可以做一些更为复杂的事情,如比较男孩和女孩的学分。我们已经设计完了学分保存的几乎所有的表。现在只需要另外
一个表来记录出勤情况即可。这个表的内容相对较为直观,即,一个学生ID 号和一个日期(见图1- 8)。表中的每行表示特定的学生在
给定的日期缺勤。在学分时段末,我们将调用MySQL的计数功能来汇总此表的内容,以便得出每个学生的缺勤数。

既然现在已经知道学分保存的各个表的结构,现在可以创建它们了。student 表的CREATE TABLE 语句如下:

将上述语句键入mysql或执行下列外壳程序命令:

CREATE TABLE 语句创建了一个名为student 的表,它含有三列,分别为: name、s e x和s t ud e n t _ i d。name 是一个可变长的字符串列,最多可存放20 个字符。这个名字的表示比历史同盟表中所用的表示要简单,它只用了单一的列而不是分别的名和姓列。这是因为我们已经预先知道,不存在无需做另外的工作就使得在多个列上工作得更好的查询样例。sex 表示学生是男孩还是女孩。这是一个ENUM(枚举)列,表示只能取明确地列在说明中的值之一,这里列出的值为:“F”和“M”,分别表示女和男。在某列只具有一组有限值时,ENUM 类型非常有用。我们可以用CHAR(1) 来代替它,但是ENUM 更明确规定了列可以取什么值。如果对包括一个ENUM 列的表发布一条DESCRIBE tbl_name 语句,MySQL将确切地显示可取的值有哪些。顺便说一下, ENUM 列中的值不一定只是单个字符。此列还可以定义为ENUM(‘f e m a l e’,‘m a l e’)。
student_id 为一个整数型列,它将包含唯一的ID 号。通常,大概会从一个中心资料来源处(如学校办公室)取得学生的ID 号,但在这里是我们自己定的。虽然student_id 列只包含一个数,但其定义包括几个部分:
■ INT 说明此列的值必须取整数(即无小数部分)。
■ UNSIGNED 不允许负数。
■ NOT NULL 表示此列的值必须填入。(任何学生都必须有一个ID 号。)
■ AUTO_INCREMENT 是MySQL中的一个特殊的属性。其作用为:如果在创建一个新的student 表记录时遗漏了student_id 的值(或为NULL),MySQL自动地生成一个大于当前此列中最大值的唯一ID 号。在录入学生表时将用到这个这特性,录入学生表时可以只给出name 和sex 的值,让MySQL自动生成student_id 列值。
■ PRIMARY KEY 表示相应列的值为快速查找进行索引,并且列中的每个值都必须是惟一的。这样可防止同一名字的ID出现两次,这对于学生ID 号来说是一个必须的特性。(不仅如此,而且MySQL还要求每个AUTO_INCREMENT 列都具有一个惟一索引。)如果您不理解AUTO_INCREMENT 和PRIMARY KEY 的含义,只要将其想像为一种为每个学生产生ID 号的魔术方法即可。除了要求值唯一外,没有什么别的东西。请注意:如果确实打算从学校办公室取得学生ID 号而不是自动生成它们,则可以按相同的方法定义student_id 列,只不过不定义AUTO_INCREMENT 属性即可。event 表如下定义:

将此语句键入mysql或执行下列外壳程序的命令:

所有列都定义为NOT NULL,因为它们中任何一个值都不能省略。date 列存储标准的MySQLDATE 日期值,格式为“Y Y Y Y- M M - D D”(首先是年)。type 代表学分类型。像student 表中的sex 一样,type 也是一个枚举列。所允许的值为“T”和“Q”,分别表示“测试”和“测验”。event_id 是一个AUTO_INCREMENT 列,类似于student 表中的student_id 列。采用AUTO_INCREMENT 允许生成唯一的事件ID 值。正如student 表中的student_id 列一样,与值的惟一性相比,某个特定的值并不重要。score 表如下定义:

将此语句键入mysql或执行下列外壳程序的命令:

score 为一个INT (整型)列。即,假定学分值总是为一个整数。如果希望使学分值具有小数部分,如5 8 . 5,应该采用浮点列类型,如FLOAT或DECIMAL。student_id 列和event_id 列都是整型,分别表示每个学分所对应的学生和事件。通过利用它们来连接到student 和event 表,我们能够知道学生名和事件的日期。我们将两个列组成了PRIMARY KEY。这保证我们不会对同一测验或测试重复一个学生的学分。而且,这样还很容易在以后更改某个学分。例如,在发现学分录入错时,可以在利用MySQL的REPLACE语句放入一个新记录,替换掉旧的记录。不需要执行DELETE 语句与INSERT 语句;MySQL自动替我们做了。请注意,它是惟一的event_id 和student_id 的组合。在score 表中,两者自身都可能不惟一。一个event_id 值可有多个学分记录(每个学生对应一个记录),而每个student_id 值都对应多个记录(每个测验和测试有一个记录)。用于出勤情况的absence 表如下定义:

将此语句键入mysql或执行下列外壳程序的命令:

student_id 和date 列两者都定义为NOT NULL,不允许省略值。应定义这两列的组合为主键,以免不当心建立了重复的记录。重要的是不要对同一天某个学生的缺旷进行重复计数。
1.4.7 增加新记录
至此,我们的数据库及其表都已经创建了,在下一节“检索信息”中,我们将看到怎样从数据库中取出数据。现在我们先将一些数据放入表中。在数据库中加入数据有几种方法。可通过发布INSERT 语句手工将记录插入某个表中。还可以通过从某个文件读取它们来增加记录,在这个文件中,记录既可以是利用L O A DDATA 语句或mysqlimport 实用程序装入的原始数据值,也可以是预先写成可馈入mysql的INSERT 语句的形式。本节介绍将记录插入表的每种方法。您所应做的是演习各种方法以明了它们是如何起作用的。然后到本节结束处运行那儿给出的命令来清除表并重装它们。这样做,能够保证表中含有作者撰写下一节时所处理的相同记录,您也能得到相同的结果。让我们开始利用INSERT 语句来增加记录,这是一个SQL 语句,需要为它指定希望插入数据行的表或将值按行放入的表。INSERT 语句具有几种形式:
■ 可指定所有列的值

例如:

“I N TO”一词自MySQL3.22.5 以来是可选的。(这一点对其他形式的INSERT 语句也成立。)VALUES 表必须包含表中每列的值,并且按表中列的存放次序给出。(一般,这就是创建表时列的定义次序。如果不能肯定的话,可使用DESCRIBE tbl_name 来查看这个次序。)在MySQL中,可用单引号或双引号将串和日期值括起来。上面例子中的NULL值是用于student 和event 表中的AUTO_INCREMENT 列的。(插入“错误”的值将导致下一个student_id 或event_id 号的自动生成。)自3.22.5 以来的MySQL版本允许通过指定多个值的列表,利用单个的INSERT语句将几行插入一个表中,如下所示:

例如:

这比多个INSERT 语句的键入工作要少,而且服务器执行的效率也更高。
■ 可以给出要赋值的那个列,然后再列出值。这对于希望建立只有几个列需要初始设置的记录是很有用的。

例如:

  自MySQL3.22.5 以来,这种形式的INSERT 也允许多个值表:

在列的列表中未给出名称的列都将赋予缺省值。
■ 自MySQL3.22 .10 以来,可以col_name = value 的形式给出列和值。

例如:

在SET 子句中未命名的行都赋予一个缺省值。使用这种形式的INSERT 语句不能插入多行。将记录装到表中的另一种方法是直接从文件读取数据值。可以用LOAD DATA 语句或用mysqlimport 实用程序来装入记录。LOAD DATA 语句起批量装载程序的作用,它从一个文件中读取数据。可在mysql内使用它,如下所示:

该语句读取位于客户机上当前目录中数据文件member.txt 的内容,并将其发送到服务器装入member 表。如果您的MySQL版本低于3 . 2 2 . 15,则LOAD DATA LOCAL 不起作用,因为那时从客户机读取数据的能力是在LOAD DATA 上的。(没有LOCAL 关键字,被读取的文件必须位于服务器主机上,并且需要大多数MySQL用户都不具备的服务器访问权限。)缺省时,LOAD DATA 语句假定列值由tab 键分隔,而行则以换行符结束。还假定各个值是按列在表中的存放次序给出的。也有可能需要读取其他格式的文件,或者指定不同的列次
序。更详细的内容请参阅附录D的LOAD DATA 的条款。mysqlimport 实用程序起LOAD DATA 的命令行接口的作用。从外壳程序调用mysqlimport ,它生成一个LOAD DATA 语句:

mysqlimport 生成一个LOAD DATA 语句,此语句使member.txt 文件被装入member 表。如果您的MySQL版本低于3 . 2 2 . 15,这个实用程序不起作用,因为--local 选项需要L O A DDATA LOCAL。正如使用mysql一样,如果您需要指定连接参数,可在命令行上数据库名前指定它们。mysqlimport 从数据文件名中导出表名(它将文件名第一个圆点前的所有字符作为表名)。例如,member.txt 将被装入member 表,而president.txt 将被装入president 表。如果您有多个需要装入单个表的文件,应仔细地选择文件名,否则mysqlimport 将不能使用正确的表名。对于如像member1.txt 与member2.txt 这样的文件名, mysqlimport 将会认为相应的表名为
member1和member 2。不过,可以使用如member.1.txt 和member.2.txt 或member.txt1和member.txt2 这样的文件名。在试用过这些记录追加的方法后,应该清除各个表并重新装载它们,以便它们的内容与下一节假定的内容相同。从外壳程序执行下列命令:


  • 上一篇文章:
  • 下一篇文章:
  • 百度搜索: MySQL教程(三)

  • 发表评论】【打印此文】【关闭窗口】【点击数:
    ★好玩的休闲小游戏★