Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2520380
  • 博文数量: 609
  • 博客积分: 10061
  • 博客等级: 上将
  • 技术积分: 5920
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-25 08:30
文章分类

全部博文(609)

文章存档

2010年(13)

2009年(39)

2008年(558)

我的朋友

分类: Mysql/postgreSQL

2008-08-31 19:02:03

Mysql入门系列:MySQL教程(3)

(2) member 表

  存储历史同盟会员清单的member 表在每个记录都包含单个人员的基本描述信息这一点上,类似于president 表。但是每个member 的记录所含的列更多,member 表的各列如下:

  ■ 姓名。使用如president 表一样的三个列来表示:姓、名(如果可能的话还有中名)、后缀。

   ■ ID 号。这是开始记录会员时赋给每个会员的唯一值。以前同盟未用ID 号,但现在的记录做得更有系统性,所以最好开始使用ID 号。(我希望您找到有利于使用MySQL并考虑到其他的将它用于历史同盟记录的方法。使用数字,将member 表中的记录与其他与会员有关的表中的记录相关联要更容易一些。)

  ■ 截止日期。会员必须定期更新他们的会员资格以免作废。对于某些应用,可能会用到最近更新的日期,但是近更新日期不适合于历史同盟。会员资格可在可变的年数 内(一般为一年、二年、三年或五年)更新,而最近更新的日期将不能表示下一次更新必须在何时进行。此外,历史同盟还允许有终生会员。我们可以用未来一个很 长的日期来表示终生会员,但是用NULL 似乎更为合适,因为“无值”在逻辑上对应于“永不终止”。

  ■ 电子邮件地址。对于有电子邮件地址的会员,这将使他们能很容易地进行相互之间的通信。作为历史同盟秘书,这使您能电子化地发送更新通知给会员,而用不着发 邮政信函。这比到邮局发送信函更容易,而且也不贵。还可以用电子邮件给会员发送他们的地址名录条目的当前内容,并要求他们在有必要时更新信息。

   ■ 邮政地址。这是与没有电子邮件(或没有返回信息)的会员联络所需要的。将分别使用街道地址、城市、州和Zip 号。街道地址列又可以用于有诸如P.O. Box 123 而不是123 Elm St. 的会员的信箱号。我们假定所有同盟会员全都住在美国。当然,对于具有国际会员的机构,此假设过于简化了。如果希望处理多个国家的地址,还需要对不同国家的 地址格式作一些工作。例如,这里的Zip 号就不是一个国际标准,有的国家有省而不是州。

    ■ 电话号码。与地址字段一样,这个列对于联络会员也是很有用的。

  ■ 特殊爱好的关键词。假定每个会员一般都对美国历史都有兴趣,但可能有的会员对某些领域有特殊的兴趣。此列记录了这些特殊的兴趣。会员可以利用这个信息来找到其他具有类似兴趣的会员。

  (3) 创建表

  现在我们已经作好了创建历史同盟表的准备。我们用CREATE TABLE 语句来完成这项工作,其一般格式如下:



   其中tbl_name 代表希望赋予表的名称。column_specs 给出表中列的说明,以及索引的说明(如果有的话)。索引能使查找更快;我们将在第4 章“查询优化”中对其作进一步的介绍。

  president 表的CREATE TABLE 语句如下所示:



  如果想自己键入这条语句,则调用mysql,使samp_db 为当前数据库:


   然后,键入如上所示的CREATE TABLE 语句。(请记住,语句结尾要增加一个分号,否则mysql将不知道哪儿是语句的结尾。)

  为了利用来自样例数据库分发包的预先写下的描述文件来创建president 表,可从外壳程序运行下列命令:



  不管用哪种方法调用mysql,都应该在命令行中数据库名的前面指定连接参数(主机名、用户名或口令)。CREATE TABLE 语句中每个列的说明由列名、类型(该列将存储的值的种类)以及一些可能的列属性组成。president 表中所用的两种列类型为VARCHAR 和DATE。VARCHAR(n)代表该列包含可变长度的字符(串)值,其最大长度为n 个字符。可根据期望字符串能有多长来选择n 值。

  state 定义为VARCHAR( 2 );即所有州名都只用其两个字符的缩写来表示。其他的字符串列则需要更长一些,以便存放更长的值。

  我们使用过的其他列类型为DATE。这种列类型表示该列存储的是日期值,这一点也不令人吃惊。而令人吃惊的是,日期的表示以年份开头。其标准格式为“ Y Y Y Y- M M - D D”(例如,“1999 - 07 - 18”)。这是日期表示的ANSI SQL 标准。我们用于president 表的唯一列属性为NULL(值可以缺少)和NOT NULL(必须填充值)。多数列是NOT NULL 的,因为我们总要有一个它们的值。可有NULL 值的两个列是s uff i x(多数姓名没有后缀)和death(有的总统仍然健在,所以没有死亡日期)。member 表的CREATE TABLE 语句如下所示:



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


  从列的类型来看,member 表并不很有趣:所有列中,除了一列之外,其他列都是可变长字符串。这个例外的列就是e x p i r a t i o n,为DATE 型。终止日期值有一个缺省值为“0 0 0 0 - 0 0 -0 0”,这是一个非NULL 的值,它表示未输入合法的日期值。这样做的原因是expiration 可以是NULL,它表示一个会员是终身会员。但是,因为此列可以为NULL,除非另外指定一个不同的值,否则它将取缺省值“ 0 0 0 0 - 0 0 - 0 0”。如果创建了一个新会员记录,但忘了指定终止日期,该会员将成为一个终身会员!通过采用缺省值“ 0 0 0 0 - 0 0 - 0 0”的方法,避免了这个问题。它还向我们提供了一种手段,即可以定期地搜索这个值,以找出过去未正确输入终止日期的记录。

  请注意,我们“忘了”放入会员ID 号的列。这是专门为了以后练习使用ALTER TABLE语句而遗留下的。现在让我们来验证一下MySQL是否确实如我们所期望的那样创建了表。在mysql中,发布下列查询:

   与MySQL3.23 一样,此输出还包括了显示访问权限信息的另一个列,这里没有给出,

  因为它使每行太长,不易显示。

  这个输出结果看上去和我们所期望的非常一致,除了state 列的信息显示它的类型为CHAR( 2 )。这就有点古怪了,我们不是定义它为VARCHAR(2) 了吗?是的,是这样定义的,但是MySQL已经悄悄地将此类型从VARCHAR 换成了CHAR。原因是为了使短字符串列的存储空间利用更为有效,这里不多讨论。如果希望详细了解,可参阅第3 章中关于ALTE RTABLE 语句的介绍。但对这里的使用来说,两种类型没有什么差别。

  如果发布一个DESCRIBE member 查询,mysql也会显示member 表的类似信息。DESCRIBE 在您忘了表中的列名、需要知道列的类型、了解列有多宽等的时候很有用。它对于了解MySQL存储表行中列的次序也很有用。列的这个存储次序在使用 INSERT 或LOAD DATA 语句时非常重要,因为这些语句期望列值以缺省列的次序列出。DESCRIBE 可以省写为DESC,或者,如果您喜欢键入较多字符,则DESCRIB Etbl_name 另一个等同的语句为SHOW COLUMNS FROM tbl_name。

  如果忘了表名怎么办?这时可以使用SHOW TABLE S。对于samp_db 数据库,我们目前

  为止创建了两个表,其输出结果如下:



  如果您甚至连数据库名都记不住,可在命令行上调用mysql而不用给出数据库名,然后发布SHOW DATABASES 查询:

  
  数据库的列表在不同的服务器上是不同的,但是至少可以看到samp_db 和mysql;后一个数据库存放控制MySQL访问权限的授权表。DESCRIBE 与SHOW 查询具有可从外壳程序中使用的命令行等同物,如下:

  % mysqlshow 与SHOW DATABASES 一样列出所有数据库

  % mysqlshow db _ name 与SHOW TABLES 一样列出给定数据库的表

  % mysqlshow db_name tbl_name 与DESCRIBE tbl_name 一样,列出给定表中的列

 2. 用于学分保存方案的表

   为了知道学分保存方案需要什么表,我们来看看在原来学分簿上是怎样记学分的。图1- 2示出学分簿的一页。该页的主体是一个记录学分矩阵。还有一些对学分有意义的必要信息。学生名和ID 号列在矩阵的一端。(为了简单好看,只列出了四个学生。)在矩阵顶端,记录了进行测验和测试的日期。图中示出9月3号、6号、16号和2 3号进行测验, 9月9号和10月1号进

  行测试。

  为了利用数据库来记录这些信息,需要一个学分表。这个表中应该包含 什么记录呢?很明显,每一行都需要有学生名、测验或测试的日期以及学分。图1-3 示出了用这样的表表示的一些来自学分簿的学分。(日期以MySQL的表示格式“Y Y Y Y- M M - D D”表示。)

 
 
   但是,以这种方式设置表似乎有点问题。好像少了点什么。请看图1- 3中的记录,我们分辨不出是测验的学分还是测试的学分。如果测验和测试的学分权重不同,在确定最终的学分等级时知道学分的类型是很重要的。或许可以试着从 学分的取值范围来确定学分的类型(测验的学分一般比测试的学分少),但是这样做很不方便,因为这需要进行判断,而且在数据中也不明显。可以通过记录学分的 类型来进行区分,如对学分表增加一列,此列包含“ T”或“Q”以表示是“测试”或是“测验”,如图1-4 所示。这具有使学分数据类型清析易辨的优点。不利的地方是这个信息有点冗余。显然对具有同一给定日期的记录,学分的类型列总是取相同的值。9月2 3日的学分总是为“ Q”类型,而10月1日的学分其类型总是具有“ T”类型。这样令人很不满意。如果我们以这种方式记录一组测验或测试的学分,不仅要为每个新记录输入相同的日期,而且还要一再重复地输入相同的学分类型。 谁会希望一再输入冗余的信息呢?

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