My SQL 学习资料库

 

Mysql学习点滴

摘自天极网

2003-5-7

122

◇◇

如何将图片储存在MySQL数据库里 

zwh

2003-5-7

11

◇◇

MySQL修改密码方法总结

starseacn(beta)

2003-4-29

11

◇◇

如何实现MySQL中的用户管理? 

李冬 

2003-4-29

8

◇◇

修改MySQL中一个用户的密码

冷风

2003-4-29

7

◇◇

分页显示Mysql数据库记录的类

sharetop 

2003-4-29

8

◇◇

MySQL用于PHP的库, 对数据库进行操作

冷风

2003-4-29

6

◇◇

MYSQL服务维护笔记 

chedong.com

2003-4-29

10

◇◇

Mysql初步使用 

zhangabo

2003-4-29

21

◇◇

MYSQL初学者使用指南

fanqiang.com

2003-4-12

148

◇◇

MySQL优化简明指南

晏子

2003-4-12

10

◇◇

MySQL数据目录结构

fanqiang.com

2003-4-12

10

◇◇

MySQL服务器的启动与停止

晏子

2003-4-12

15

◇◇

关于mysql中文排序的方法

baitie

2003-4-12

7

◇◇

MySQL 文件系统

 

 

 

 

 

Mysql学习点滴

作者:摘自天极网

由于工作中需要使用mysql,笔者通过网上学习,动手实践,终于从一个"数据库菜鸟"变成了能熟练操作mysql的"准大虾"了,:)。现将学习心得整理如下。

  MySQL是完全网络化的跨平台关系型数据库系统,一个真正的多用户、多线程SQL数据库服务器,同时是具有客户机/服务器体系结构的分布式数据库管理系统。它具有功能强、使用简便、管理方便、运行速度快、安全可靠性强等优点,用户可利用许多语言编写访问MySQL 数据库的程序,对于中、小型应用系统是非常理想的。除了支持标准的ANSI SQL语句,更重要的是,它还支持多种平台,而在Unix系统上该软件支持多线程运行方式,从而能获得相当好的性能。对于不使用Unix的用户,它可以在Windows NT系统上以系统服务方式运行,或者在Windows 95/98系统上以普通进程方式运行。而在Unix/Linux系统上,MySQL支持多线程运行方式,从而能获得相当好的性能,而且它是属于开放源代码软。

  MySQL是以一个客户机/服务器结构的实现,它由一个服务器守护程序mysqld和很多不同的客户程序和库组成,MySQL 的执行性能非常高,运行速度非常快,并非常容易使用,是一个非常棒的数据库。MySQL的官方发音是"My Ess Que Ell"(不是 MY-SEQUEL )。

一.获得MySQL

  首先必须下载MySQL。Mysql的官方网站是:http://www.mysql.com ,在中国的镜像是:http://www.freecode.net.cn/mirror/mysql/ 或者http://www2.linuxforum.net/mirror/mysql/,可以下载MySQL的稳定版本3.22.32(截止到笔者发稿为止)。其版本名称是mysql-shareware-3.22.32-win,不但免费而且没有所谓的"30天使用期限"。

二.MySQL的安装

(一)在Win98/Winnt下的安装

  到一个目录,运行Setup程序,会提示整个安装的过程。它默认安装到c:\mysql下,如果要安装到其它目录下还有改动一些东西,作为初学者,可以先不管,以默认的目录安装。好了,安装后,进入c:\mysql\bin目录下,运行mysqld-shareware.exe文件在Win98下直接运行,正常情况下,没有什么提示信息。

  1。将下载后的文件解压解压到一个临时目录。
  2。点击setup.exe安装到c:\mysql(默认)。
  3。将mysql_example.cnf拷贝到c:\my.cnf,把文件中的#basedir=d:/mysql/改为basedir=c:\mysql。
  4。进入msdos,到目录c:\mysql\bin。
  5。输入mysqld-shareware -install,此为启动Mysql数据库服务。
  6。mysqladmin -u root -p password 新密码,此为修改root用户的密码(原来默认的密码为空。)
  7。输入mysql -u root -p。
  8.接着,根据提示输入新密码 ,正常情况下会出现几行提示信息并出现提示符号:
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 6268 to server version: 3.22.32
    Type 'help' for help.
    mysql>

到此,你已经成功安装了MySQL。

(二)在Windows2000 下的安装

  1。安装时选默认目录: c:\mysql
  2。把 c:\mysql\my-example.cnf copy 为 c:\my.cnf,并把 c:\mysql\lib\cygwinb19.dll copy 到 winnt\system32。
  3。启动 mysql的方法是:
    c:\mysql\bin\mysqld-shareware --install
    net start mysql
  这么简单,就可以启动了。
  4。更改 超级用户(root) 的密码:
    C:\mysql\bin\mysql mysql
    mysql> UPDATE user SET password=PASSWORD('your password') WHERE user='root';
    mysql> QUIT
    C:\mysql\bin\mysqladmin reload
    使用命令C:\mysql\bin\mysqlshow去看看检测一下。在这里应该显示:
    +-----------+
    | Databases |
    +-----------+
    | mysql |
    | test |
    +-----------+
    看到这些信息这一步就证明没问题了
    再来:
    C:\mysql\bin\mysqlshow --user=root --password=your password mysql
    在这里应该显示:
    Database: mysql
    +--------------+
    | Tables |
    +--------------+
    | columns_priv |
    | db |
    | host |
    | tables_priv |
    | user |
    +--------------+
    一切搞定!

  5。C:\mysql\bin\mysqladmin version status proc
  应该可以看到这些版本信息的:
   mysqladmin Ver 8.0 Distrib 3.22.32, for Win95/Win98 on i586
   TCX Datakonsult AB, by Monty

   Server version 3.22.32-shareware-debug
   Protocol version 10
   Connection localhost via TCP/IP
   TCP port 3306
   Uptime: 1 hour 29 min 30 sec

   Threads: 1 Questions: 72 Slow queries: 0 Opens: 16 Flush tables: 1 Open tables: 0 Memory in use: 16423K Max memory      used: 16490K
   Uptime: 5370 Threads: 1 Questions: 72 Slow queries: 0 Opens: 16 Flush tables: 1 Open tables: 0 Memory in use: 16423K     Max memory used: 16490K
    +----+------+-----------+----+---------+------+-------+------------------+
    | Id | User | Host | db | Command | Time | State | Info |
    +----+------+-----------+----+---------+------+-------+------------------+
    | 35 | ODBC | localhost | | Query | 0 | | show processlist |
    +----+------+-----------+----+---------+------+-------+------------------+
  接着,用show databases命令可以将安装的数据库列出来:
    mysql> show databases;
  你就可以看到:
    +----------+
    | Database |
    +----------+
    | mysql |
    | test |
    +----------+
    2 rows in set (0.00 sec)
  如果一切正常的话,那说明MySQL可以完全工作了!如果要退出程序,输入:exit
    mysql> exit;
    Bye

三.Mysql常识

(一) 字段类型

  1.INT[(M)]
  正常大小整数类型
  2.DOUBLE[(M,D)] [ZEROFILL]
  正常大小(双精密)浮点数字类型
  3.DATE
  日期类型。支持的范围是'1000-01-01'到'9999-12-31'。MySQL以'YYYY-MM-DD'格式来显示DATE值,但是允许你使用字符串或数字把值赋给  DATE列
  4.CHAR(M)
  定长字符串类型,当存储时,总是是用空格填满右边到指定的长度
  5.BLOB TEXT
  BLOB或TEXT类型,最大长度为65535(2^16-1)个字符。
  6.VARCHAR
  变长字符串类型,最常用的类型。

(二)基本操作

  1: 显示数据库
   mysql>SHOW DATABASES;
  2:当前选择的数据库,
   mysql> SELECT DATABASE();
   +------------+
   | DATABASE() |
   +------------+
   | test |
   +------------+
  3.当前数据库包含的表信息:
   mysql> SHOW TABLES;
   +---------------------+
   | Tables in test |
   +---------------------+
   | mytable1 |
   | mytable2 |
   +---------------------+
  4.获取表结构
   mysql> desc mytable1;
   +---------+-------------+------+-----+---------+-------+
   | Field | Type | Null | Key | Default | Extra |
   +---------+-------------+------+-----+---------+-------+
   | s1 | varchar(20) | YES | | NULL | |
   +---------+-------------+------+-----+---------+-------+
  5.创建表
  表是数据库的最基本元素之一,表与表之间可以相互独立,也可以相互关联。创建表的基本语法如下:
   create table table_name
   (column_name datatype {identity |null|not null},
   …)
  其中参数table_name和column_name必须满足用户数据库中的识别器(identifier)的要求,参数datatype是一个标准的SQL类型或由用户数  据库提供的类型。用户要使用non-null从句为各字段输入数据。
  create table还有一些其他选项,如创建临时表和使用select子句从其他的表中读取某些字段组成新表等。还有,在创建表是可用PRIMARY   KEY、KEY、INDEX等标识符设定某些字段为主键或索引等。书写上要注意: 在一对圆括号里的列出完整的字段清单。字段名间用逗号隔开  。 字段名间的逗号后要加一个空格。最后一个字段名后不用逗号。所有的SQL陈述都以分号";"结束。
  例:
   mysql>CREATE TABLE guest (name varchar(10),sex varchar(2),age int(3),career varchar(10));
  6.创建索引
  索引用于对数据库的查询。一般数据库建有多种索引方案,每种方案都精于某一特定的查询类。索引可以加速对数据库的查询过程。创建  索引的基本语法如下:
   create index index_name
   on table_name (col_name[(length)],... )
  例:
   mysql> CREATE INDEX number ON guest (number(10));
  7.执行查询
  查询是使用最多的SQL命令。查询数据库需要凭借结构、索引和字段类型等因素。大多数数据库含有一个优化器(optimizer),把用户的查  询语句转换成可选的形式,以提高查询效率。
  值得注意的是MySQL不支持SQL92标准的嵌套的where子句,即它只支持一个where子句。其基本语法如下:
   SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [HIGH_PRIORITY]
   [DISTINCT | DISTINCTROW | ALL]
   select_expression,...
   [INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
   [FROM table_references
   [WHERE where_definition]
   [GROUP BY col_name,...]
   [HAVING where_definition]
   [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
   [LIMIT [offset,] rows]
   [PROCEDURE procedure_name] ]
  其中where从句是定义选择标准的地方,where_definition可以有不同的格式,但都遵循下面的形式:
  字段名操作表达式
  字段名操作字段名
  在第一种形式下,标准把字段的值与表达式进行比较;在第二种形式下,把两个字段的值进行比较。根据所比较的数据类型,       search_condition中的操作可能选以下几种:
   = 检查是否相等
   != 检查是否不等

   > (或>=) 检查左边值是否大于(或大于等于)右边值
   < (或<=) 检查左边值是否小于(或小于等于)右边值
   [not] between 检查左边值是否在某个范围内
   [not] in 检查左边是否某个特定集的成员
   [not] like 检查左边是否为右边的子串
   is [not] null 检查左边是否为空值
  在这里,可以用通配符_代表任何一个字符,%代表任何字符串。使用关键字、和可以生成复杂的词,它们运行检查时使用  布尔表达式的多重标准集。
  例:
   mysql> select t1.name, t2.salary from employee AS t1, info AS t2 where t1.name = t2.name;
   mysql> select college, region, seed from tournament
   ORDER BY region, seed;
   mysql> select col_name from tbl_name WHERE col_name > 0;
  8.改变表结构
  在数据库的使用过程中,有时需要改变它的表结构,包括改变字段名,甚至改变不同数据库字段间的关系。可以实现上述改变的命令是   alter,其基本语法如下:
  alter table table_name alter_spec [, alter_spec ...]
  例:
   mysql> alter table dbname add column userid int(11) not null primary key auto_increment;
  这样,就在表dbname中添加了一个字段userid,类型为int(11)。
  9.修改表中数据
  在使用数据库过程中,往往要修改其表中的数据,比如往表中添加新数据,删除表中原有数据,或对表中原有数据进行更改。它们的基本  语法如下:
  数据添加:
   insert [into] table_name [(column(s))]
   values (expression(s))
  例:
   mysql>insert into mydatabase values('php','mysql','asp','sqlserver','jsp','oracle');

  10. 表的数据更新

  (1) 一次修改一个字段,再次注意语法。文本需要加引号但数字不要。
   mysql>update table01 set field03='new info' where field01=1;
   Query OK, 1 row affected (0.00 sec)
  (2)一次改变多个字段,记住在每一个更新的字段间用逗号隔开。
   mysql>update table01 set field04=19991022, field05=062218 where field01=1;
   Query OK, 1 row affected (0.00 sec)
  (3) 一次更新多个数据
   mysql>update table01 set field05=152901 where field04>19990101;
   Query OK, 3 rows affected (0.00 sec)
  11. 删除数据
   mysql>delete from table01 where field01=3;
   Query OK, 1 row affected (0.00 sec)
  12.导入数据库表
   (1)创建.sql文件
   (2)先产生一个库如auction.c:\mysql\bin>mysqladmin -u root -p creat auction,会提示输入密码,然后成功创建。
   (3)导入auction.sql文件
    c:\mysql\bin>mysql -u root -p auction < auction.sql。
   通过以上操作,就可以创建了一个数据库auction以及其中的一个表auction。
  13.mysql数据库的授权
   mysql>grant select,insert,delete,create,drop
   on *.* (或test.*/user.*/..)
   to 用户名@localhost
   identified by '密码';
  如:新建一个用户帐号以便可以访问数据库,需要进行如下操作:
   mysql> grant usage
   -> ON test.*
   -> TO testuser@localhost;
   Query OK, 0 rows affected (0.15 sec)
  此后就创建了一个新用户叫:testuser,这个用户只能从localhost连接到数据库并可以连接到test 数据库。下一步,我们必须指定     testuser这个用户可以执行哪些操作:
   mysql> GRANT select, insert, delete,update
   -> ON test.*
   -> TO testuser@localhost;
   Query OK, 0 rows affected (0.00 sec)
  此操作使testuser能够在每一个test数据库中的表执行SELECT,INSERT和DELETE以及UPDATE查询操作。现在我们结束操作并退出MySQL客户  程序:
   mysql> exit
   Bye
  14.授权 MySQL用户密码
  MySQL数据库的默认用户名为"root"(MS SQL Server 的 sa 相似),密码默认为空。在DOS提示符(注意,不是mysql提示符)下输入
  c:\mysql\bin>"mysqladmin -u root -p password newpassword
  回车后会提示你输入原来的密码,由于原来密码为空,直接回车,root用户的密码便改为"newpassword"了。

 

如何将图片储存在MySQL数据库里 

作者:zwh

如果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的!我将告诉你怎样通过HTML表单来储存这些文件,怎样访问和使用这些文件。

  一、本文概述

  本文的主要内容如下:

  * 在MySQL中建立一个新的数据库
  * 一个怎样储存文件的例子程序
  * 一个怎样访问文件的例子程序

  二、在MySQL中建立一个新的database

  首先,你必须在你的MySQL中建立一个新的数据库,我们将会把那些二进制文件储存在这个数据库里。在例子中我会使用下列结构,为了建立数据库,你必须做下列步骤:

  1. 进入MySQL控制器
  2. 输入命令"create database binary_data;"
  3. 输入命令"use binary_data;"

  输入如下命令:

  "CREATE TABLE binary_data ( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,description CHAR(50), bin_data LONGBLOB, filename CHAR(50), filesize CHAR(50), filetype CHAR(50));" (不能断行)

  如果没有意外,数据库 和 表 应该建立好了。
  三、一个怎样储存文件的例子程序

  用这个例子你可以通过Html表单将文件传输到数据库中。

  store.php3

  // store.php3 - by Florian Dittmer

  ?>

  // 如果提交了表单,代码将被执行:

  if ($submit) {

  // 连接到数据库
  // (你可能需要调整主机名,用户名和密码)

  MYSQL_CONNECT( "localhost", "root", "password");
  MySQL_select_db( "binary_data");
  $data = addslashes(fread(fopen($form_data, "r"), filesize($form_data)));
  $result=MYSQL_QUERY( "INSERT INTO binary_data (description,bin_data,filename,filesize,filetype)VALUES (’$form_description’,’$data’,’$form_data_name’,’$form_data_size’,’$form_data_type’)");
  $id= MySQL_insert_id();
  print "This file has the following Database ID: $id";
  MYSQL_CLOSE();
  } else {

  // 否则显示储存新数据的表单

  ?>

  当文件上传至web服务器之后,程序将会告诉你刚刚上传的文件的ID,记住这个ID,待会要用的。

  四、一个怎样访问文件的例子程序

  你可以通过这个程序访问你刚才储存的文件

  // getdata.php3 - by Florian Dittmer

  // 调用方法: getdata.php3?id=

  if($id) {

  // 你可能需要调整主机名,用户名和密码:

  @MYSQL_CONNECT( "localhost", "root", "password");
  @MySQL_select_db( "binary_data");
  $query = "select bin_data,filetype from binary_data where id=$id";
  $result = @MYSQL_QUERY($query);
  $data = @MYSQL_RESULT($result,0, "bin_data");
  $type = @MYSQL_RESULT($result,0, "filetype");
  Header( "Content-type: $type");
  echo $data;
  };
  ?>
 程序必须知道要访问那个文件, 你必须将ID作为一个参数。

  例如: 一个文件在数据库中的ID为2. 你可以这样调用它: getdata.php3?id=2

  如果你将图片储存在数据库里, 你可以向调用图片一样调用它。

  Example: 一个图片文件在数据库中的ID为3. 你可以这样调用它:

  五、怎样储存大于1MB的文件

  如果你想储存大于1MB的文件,你必须对你的程序、PHP设置、SQL设置进行许多修改。

  下面几条也许可以帮助你储存小于24MB的文件:

  1) 修改 store.php3,将 MAX_FILE_SIZE 的值改成 24000000。

  2) 修改你的PHP设置,在一般情况下,PHP只允许小于2MB的文件,你必须将max_filesize(在php.ini中)的值改成24000000

  3) 去掉MYSQL的数据包大小限制,在一般情况下 MYSQL 小于1 MB的数据包。

  4) 你必须用以下参数重启你的MYSQL :/usr/local/bin/safe_MySQLd -O key_buffer=16M -O table_cache=128 -O sort_buffer=4M -O record_buffer=1M -O max_allowed_packet=24M

  5) 如果仍然出错:可能是超时错误,如果你通过一个很慢的连接来储存一个很大的文件,PHP缺省的时间限制为30秒。你可以将max_execution_time(在php.ini中)的值改为-1 。

 

MySQL修改密码方法总结

作者:starseacn(beta)

首先要声明一点,大部分情况下,修改MySQL是需要有mysql里的root权限的,  
所以一般用户无法更改密码,除非请求管理员。  

方法一  
使用phpmyadmin,这是最简单的了,修改mysql库的user表,  
不过别忘了使用PASSWORD函数。  

方法二  
使用mysqladmin,这是前面声明的一个特例。  
mysqladmin -u root -p password mypasswd  
输入这个命令后,需要输入root的原密码,然后root的密码将改为mypasswd。  
把命令里的root改为你的用户名,你就可以改你自己的密码了。  
当然如果你的mysqladmin连接不上mysql server,或者你没有办法执行mysqladmin,  
那么这种方法就是无效的。  
而且mysqladmin无法把密码清空。  

下面的方法都在mysql提示符下使用,且必须有mysql的root权限:  
方法三  
mysql> INSERT INTO mysql.user (Host,User,Password)  
VALUES('%','jeffrey',PASSWORD('biscuit'));  
mysql> FLUSH PRIVILEGES  
确切地说这是在增加一个用户,用户名为jeffrey,密码为biscuit。  
在《mysql中文参考手册》里有这个例子,所以我也就写出来了。  
注意要使用PASSWORD函数,然后还要使用FLUSH PRIVILEGES。  

方法四  
和方法三一样,只是使用了REPLACE语句  
mysql> REPLACE INTO mysql.user (Host,User,Password)  
VALUES('%','jeffrey',PASSWORD('biscuit'));  
mysql> FLUSH PRIVILEGES  

方法五  
使用SET PASSWORD语句,  
mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');  
你也必须使用PASSWORD()函数,  
但是不需要使用FLUSH PRIVILEGES。  


方法六  
使用GRANT ... IDENTIFIED BY语句  
mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';  
这里PASSWORD()函数是不必要的,也不需要使用FLUSH PRIVILEGES。  


注意: PASSWORD() [不是]以在Unix口令加密的同样方法施行口令加密。  

 

如何实现MySQL中的用户管理? 

作者:李冬 

MySQL有一套先进的但非标准的安全/授权系统,掌握其授权机制是开始操作MySQL数据库必须要走的第一步,对于一个熟悉SQL基本操作的人来说,也是MySQL所有的知识中比较难以理解的一个部分。本文通过揭开其授权系统的运作机制,希望大家能够可以更好地操作和使用这个优秀的数据库系统。

本文主要参考了MySQL安装所附的使用手册第六章中的部分内容。如果有任何疑问,请和我联系(lidong@wh.027.net)

1、授权机制的主要作用是什么?

授权机制的基本作用是给某个主机上的用户对某个数据库以select,insert,update和detete的权限。而其额外的功能还包括是否允许匿名使用数据库,使用MysQL的一些特定函数,如:LOAD DATA INFILE之类。在这里请注意,MySQL中的用户名和Unix系统中的用户名并没有什么关系。虽然许多客户端程序允许你可以用当前的用户名进行登录,但是最标准的做法还是通过--user的选项。
 
2、授权机制是如何进行运作的?

在MySQL中主机和用户的联合视为唯一标志。比如说,在主机1和主机2上的用户lee实际上是不同的,他们对MySQL的使用权限也可以是有差别的。而整个授权机制的核心问题就是要解决授予从某个主机上登录的某个用户对某个数据库的使用权限。你可以通过脚本mysqlaccess测试一个主机上用户的对数据库操作的权限。而所有的授权信息都被存储在数据库mysql的user、host和db表中。我们可以通过mysql mysql的指令连接到这个数据库中,并且通过select * from user(或者db,host)显示每个数据表中的内容。user表中所授予的权限是整个授权机制的基本授权,也就是说,user中的定义对于任何一个用户+主机来说都是适用的,除非在db表中另外有所定义,因此,对于用户来说最好是就某个数据库为基础进行授权。而host表的主要目的是维护一个“安全”服务器的列表。而在具体考虑某个用户/主机对某个数据库的权限的的时候,我们还需要研究一下授权机制的的匹配搜索机制:

其次,在授权机制中可以对一个用户的口令进行加密,而且是必须加密,加密的方法是password('口令'),如果直接填写口令的话,会导致数据库无法访问。user表中所授予的权限是整个授权机制的基本授权,也就是说,user中的定义对于任何一个用户+主机来说都是适用的,除非在db表中另外有所定义,因此,对于用户来说最好是就某个数据库为基础进行授权。而host表的主要目的是维护一个“安全”服务器的列表。而在具体考虑某个用户/主机对某个数据库的权限的的时候,我们还需要研究一下授权机制的的匹配搜索机制:

首先,我们需要介绍一下统配符的概念,统配符包括“%”,其意思为任意(的主机、用户或者数据库),而如果一条记录为空的话,也表示任意的意思。其次,在授权机制中可以对一个用户的口令进行加密,而且是必须加密,加密的方法是password('口令'),如果直接填写口令的话,会导致数据库无法访问。
从我们对这三个表的显示我们可以看到,这三个表中的每一条记录包含了对于某个用户的授权情况的描述,MySQL数据库中几个相关的授权机制的数据表被搜索的顺序为:user,db,host。也就是说,我们将首先首先检索user数据表,找到第一个匹配的记录,我们把在user数据表中首先匹配的记录称之为Priv;然后搜索db表,获得相应的授权。如果在db数据表相应记录中host字段的为空,并且Priv记录中主机也被包含在host表的host字段之中,这样的话,对于某个user来说,则可以在user表中加入在host表中的一些为“Y”的权限设定。如果在db表中的host字段不为空的话,那么也就不会对该用户/主机的授权产生什么影响了。
了解了这一点之后,我们需要讨论在各个数据表中的记录的搜索的优先权的问题,也就是说,怎样确定第一匹配的记录,这并不是按照数据表中的记录的自然先后顺序来确定的。在各个数据表内的各条记录的优先权排列如下:
(1)user表:根据先host后user的顺序确定。搜索规则如下:不包含统配符的记录,包含统配符的记录,空记录。而在同样一个host里面,继续按照user来排列,规则和上述的一样。
(2)db表:检索的顺序根据host字段确定:不包含统配符的记录,包含统配符的记录,空记录。
(3)host表:检索的顺序根据host字段确定:不包含统配符的记录,包含统配符的记录,空记录。我们用下面的例子来说明进行匹配搜索的规则:请记住如果你更改了这些数据表,你必须使用mysqladmin reload使其生效。
下面是演示系统是如何进行搜索的:
+-----------+---------+-
| Host | User | ...
+-----------+---------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+---------+-
搜索的顺序应当是:
localhost/root
localhost/any
any/jeffrey
any/root
这样,如果在localhost的用户jeffrey要连接数据库的话,那么其授权应当根据localhost/“任意” 行所规定的权限而非“任意”/jeffrey行所规定的权限,请大家注意这一点,因为如果不合适的配置完全可能会使得你无法正常地使用这个数据库系统。
我们现在来看一个添加一个用户的例子:需要添加一名叫做“custom”用户,他分别从主机'localhost', 'server.domain' 和 'whitehouse.gov'连接到数据库中,他的口令为“stupid”,对于数据库'bankaccount'他只想从“localhost”进行访问,而“customer”数据库则应当被上述3个主机所访问。我们通过以下的sql语句来完成其操作。

shell> mysql mysql.
mysql> insert into user (host,user,password)
values('localhost','custom',password('stupid'));
mysql> insert into user (host,user,password)
values('server.domain','custom',password('stupid'));
mysql> insert into user (host,user,password)
values('whitehouse.gov','custom',password('stupid'));

mysql> insert into db
(host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv)
values
('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> insert into db
(host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv)
values
('%','customers','custom','Y','Y','Y','Y','Y','Y');

3、授权数据表

授权数据表对表的行操作包括select,insert,update和delete,对表和数据库的操作包括create和drop。其它的授权还包括如LOAD DATA INFILE和SELECT INTO OUTFILE和管理命令:shutdown, reload, refresh 和process.三个授权数据表的结构如下所示:
user表
字段 类型 健 默认值
Host char(60) PRI ""
User char(16) PRI ""
Password char(16) - ""
Select_priv enum('N','Y') - N
Insert_priv enum('N','Y') - N
Update_priv enum('N','Y') - N
Delete_priv enum('N','Y') - N
Create_priv enum('N','Y') - N
Drop_priv enum('N','Y') - N
Reload_priv enum('N','Y') - N
Shutdown_priv enum('N','Y') - N
Process_priv enum('N','Y') - N
File_priv enum('N','Y') - N

db表
字段 类型 健 默认值
Host char(60) PRI ""
Db char(64) PRI ""
User char(16) PRI ""
Select_priv enum('N','Y') - N
Insert_priv enum('N','Y') - N
Update_priv enum('N','Y') - N
Delete_priv enum('N','Y') - N
Create_priv enum('N','Y') - N
Drop_priv enum('N','Y') - N

host 表只有在db的数据项中出现host为空的情况下使用。
字段 类型 健 默认值
Host char(60) PRI ""
Db char(64) PRI ""
Select_priv enum('N','Y') - N
Insert_priv enum('N','Y') - N
Update_priv enum('N','Y') - N
Delete_priv enum('N','Y') - N
Create_priv enum('N','Y') - N
Drop_priv enum('N','Y') - N

在数据表中可以使用统配符号。

4、最常见的Access denied出现错误的原因

(1)你是否通过mysql_install_db脚本建立mySQL的授权表,你可以通过mysql -u root进行测试,正确的情况下应该不会发生错误。或者,你是否有一个文件为:user.ISD,通常其位置在install_dir/var/mysql/user.ISD。
(2)最初使用的时候你应该使用mysql -u root mysql以存取数据库,或者以root身份进行操作。
(3)更改了授权之后是否使用了mysqladmin reload进行了更新?
(4)在以测试为目的的时候,你应当选用--without-grant-tables选项启动mysqld服务,你可以在这时更改授权表的相关内容,也可以用mysqlaccess检查你的授权是否到位。
(5)没有使用password("口令")设定了口令,结果也会出现错误,在使用-p的选项的时候,注意-ppassword之间没有空格。

5、如何使得MySQL更加安全?

(1)为每个MySQL用户使用口令。记住,如果你不加设口令的话,其他人可以通过mysql --user other_user database的方式访问你的数据库,在使用MySQL进行检测的时候系统也会给你相应的警告信息。
(2)不要用root方式启动MySQL服务。MySQL可以以任何用户启动。你可以通过添加一个新用户的方式来启动数据库服务。这也不会对系统造成任何影响,因为MySQL的用户和Unix的用户根本来说就使不同的。
(3)不要把'Process_priv','File_priv'等权限授予任何人。
(4)如果你不信任你的DNS,你应当使用IP来取代主机名。在任何情况下都要小心带匹佩符的主机名。以下的一些选项可以影响到你的系统的安全:
--secure
顾名思义,可以使系统根加安全,因为它可以检查IP地址的一致性。(实际连接IP地址和通过解析的IP地址),不过这使得mySQL在防火墙工作的时候很难被防火墙外的人所访问。
--skip-grant-tables
一般情况下不要使用这个选项,这可以试的任何人不受限制地访问你的系统。
--skip-name-resolve
不进行主机名的解析。在授权数据表中的所有主机名必须为ip地址或者'localhost'.
--skip-networking
不允许通过网络进行连接。所有的连接必须通过Unix Socket。

修改MySQL中一个用户的密码

作者:冷风

MySQL中修改一个用户(比如叫"hunte")的密码,可以用如下3个办法:
>>>
#在控制台上输入
bash$ mysql -u root mysql
#用mysql客户程序
mysql> UPDATE user SET password=PASSWORD("new password") WHERE user='hunte';
mysql> FLUSH PRIVILEGES;
mysql> QUIT
<<<

>>>
#在控制台上输入
bash$ mysql -u root mysql
mysql> SET PASSWORD FOR hunte=PASSWORD('new password');
mysql> QUIT
<<<

>>>
#直接在控制台上输入
bash$ mysqladmin -u root "old password" "new password"

分页显示Mysql数据库记录的类

作者:sharetop 

本类没有提供连接数据库的功能,所以需在外部打开相应的数据库。
本类也没有提供显示记录的功能,只是分页读取记录至 Result二维数组中。
需在外部自定义数据显示格式。
***********************************************/
class TViewPage {

var $Table; //表名
var $MaxLine; //每页显示行数

var $Offset; //记录偏移量
var $Total; //记录总数
var $Number; //本页读取的记录数
var $Result; //读出的结果

var $TPages; //总页数
var $CPages; //当前页数

var $Condition; //显示条件 如:where id='$id' order by id desc
var $PageQuery; //分页显示要传递的参数


//******构造函数*************
//参数:表名、最大行数、偏移量

function TViewPage($TB,$ML,$OF=0){
$this->Table=$TB;
$this->MaxLine=$ML;
$this->Offset=$OF;
$this->Condition="";
}

//********设置显示条件*********
//如:where id='$id' order by id desc
//要求是字串,符合SQL语法(本字串将加在SQL语句后)

function SetCondition($s){
$this->Condition=$s;
}

//******设置传递参数************
// key参数名 value参数值
// 如:setpagequery("id",$id);如有多个参数要传递,可多次调用本函数。

function SetPageQuery($key,$value){
$tmp[key]=$key; $tmp[value]=$value;
$this->PageQuery[]=$tmp;
}

//********读取记录***************
// 主要工作函数,根据所给的条件从表中读取相应的记录
// 返回值是一个二维数组,Result[记录号][字段名]

function ReadList() {
$SQL="SELECT Count(*) AS total FROM ".$this->Table." ".$this->Condition;

$result=mysql_query($SQL) or die(mysql_error());
$row=mysql_fetch_Array($result);
$this->Total=$row[total];

if($this->Total>0) { //根据条件 Condition
$SQL="SELECT * FROM ".$this->Table." ".$this->Condition.
" LIMIT ".$this->Offset." , ".$this->MaxLine;

$result=mysql_query($SQL) or die(mysql_error());
$this->Number=mysql_num_rows($result);

while($row=mysql_fetch_Array($result)) $this->Result[]=$row;
}
return $this->Result;
}

//**********显示页数*************
//显示当前页及总页数

function ThePage() {
$this->TPages=ceil($this->Total/$this->MaxLine);
$this->CPages=$this->Offset/$this->MaxLine+1;
echo "第".$this->CPages."页/共".$this->TPages."页";
}

//**********显示翻页按钮*************
//此函数要在ThePage()函数之后调用!!!
//显示首页、下页、上页、未页,并加上要传递的参数

function Page() {
$first=0;
$next=$this->Offset+$this->MaxLine;
$prev=$this->Offset-$this->MaxLine;
$last=($this->TPages-1)*$this->MaxLine;

$k=count($this->PageQuery);
$strQuery=""; //生成一个要传递参数字串
for($i=0;$i<$k;$i++){
$strQuery.="&".$this->PageQuery[$i][key]."=".$this->PageQuery[$i][value];
}

if($this->Offset>=$this->MaxLine)
echo "<A href=$PHP_SELF?offset=".$first.$strQuery.">首页</A>|";
if($prev>=0)
echo "<A href=$PHP_SELF?offset=".$prev.$strQuery.">上一页</A>|";
if($next<$this->Total)
echo "<A href=$PHP_SELF?offset=".$next.$strQuery.">下一页</A>|";
if($this->TPages!=0 && $this->CPages<$this->TPages)
echo "<A href=$PHP_SELF?offset=".$last.$strQuery.">末页</A>";
}

//******end class
}

MySQL用于PHP的库, 对数据库进行操作

作者:冷风

<?
/*
* Utility routines for MySQL.
*/
class MySQL_class {
var $db, $id, $result, $rows, $data, $a_rows;
var $user, $pass, $host;

/* Make sure you change the USERNAME and PASSWORD to your name and
* password for the DB
*/

function Setup ($user, $pass) {
$this->user = $user;
$this->pass = $pass;
}

function Create ($db) {
if (!$this->user) {
$this->user = "USERNAME"; /* 在这里作修改 */
}
if (!$this->pass) {
$this->pass = "PASSWORD"; /* 在这里作修改 */
}
$this->db = $db;
$this->id = @mysql_pconnect($this->host, $this->user, $this->pass) or
MySQL_ErrorMsg("Unable to connect to MySQL server: $this->host : '$SERVER_NAME'");
$this->selectdb($db);
}

function SelectDB ($db) {
@mysql_select_db($db, $this->id) or
MySQL_ErrorMsg ("Unable to select database: $db");
}

# Use this function is the query will return multiple rows. Use the Fetch
# routine to loop through those rows.
function Query ($query) {
$this->result = @mysql_query($query, $this->id) or
MySQL_ErrorMsg ("Unable to perform query: $query");
$this->rows = @mysql_num_rows($this->result);
$this->a_rows = @mysql_affected_rows($this->result);
}

# Use this function if the query will only return a
# single data element.
function QueryItem ($query) {
$this->result = @mysql_query($query, $this->id) or
MySQL_ErrorMsg ("Unable to perform query: $query");
$this->rows = @mysql_num_rows($this->result);
$this->a_rows = @mysql_affected_rows($this->result);
$this->data = @mysql_fetch_array($this->result) or
MySQL_ErrorMsg ("Unable to fetch data from query: $query");
return($this->data[0]);
}

# This function is useful if the query will only return a
# single row.
function QueryRow ($query) {
$this->result = @mysql_query($query, $this->id) or
MySQL_ErrorMsg ("Unable to perform query: $query");
$this->rows = @mysql_num_rows($this->result);
$this->a_rows = @mysql_affected_rows($this->result);
$this->data = @mysql_fetch_array($this->result) or
MySQL_ErrorMsg ("Unable to fetch data from query: $query");
return($this->data);
}

function Fetch ($row) {
@mysql_data_seek($this->result, $row) or
MySQL_ErrorMsg ("Unable to seek data row: $row");
$this->data = @mysql_fetch_array($this->result) or
MySQL_ErrorMsg ("Unable to fetch row: $row");
}

function Insert ($query) {
$this->result = @mysql_query($query, $this->id) or
MySQL_ErrorMsg ("Unable to perform insert: $query");
$this->a_rows = @mysql_affected_rows($this->result);
}

function Update ($query) {
$this->result = @mysql_query($query, $this->id) or
MySQL_ErrorMsg ("Unable to perform update: $query");
$this->a_rows = @mysql_affected_rows($this->result);
}

function Delete ($query) {
$this->result = @mysql_query($query, $this->id) or
MySQL_ErrorMsg ("Unable to perform Delete: $query");
$this->a_rows = @mysql_affected_rows($this->result);
}
}

/* ********************************************************************
* MySQL_ErrorMsg
*
* Print out an MySQL error message
*
*/

function MySQL_ErrorMsg ($msg) {
# Close out a bunch of HTML constructs which might prevent
# the HTML page from displaying the error text.
echo("</ul></dl></ol>n");
echo("</table></script>n");

# Display the error message
$text = "<font color="#ff0000" size=+2><p>Error: $msg :";
$text .= mysql_error();
$text .= "</font>n";
die($text);
}
?>

MYSQL服务维护笔记 

作者:chedong.com

使用MYSQL服务的一些经验,主要从以下几个方面考虑的MYSQL服务规划设计。  
1 MYSQL服务的安装/配置的通用性;  
2 系统的升级和数据迁移方便性;  
3 备份和系统快速恢复;  

MYSQL服务器的规划  
=================  
为了以后维护,升级备份的方便和数据的安全性,最好将MYSQL程序文件和数据分别安装在“不同的硬件”上。  
/  
/usr <== 操作系统 }==> 硬盘1  
/home/mysql <== mysql应用程序  
...  
/data/app_1/ <== 应用数据和脚本 }==> 硬盘2  
/data/app_2/  
/data/app_3/  

mysql服务的安装和服务的启动:  
MYSQL一般使用当前STABLE的版本,尽量不使用--with-charset=选项,我感觉with-charset只在按字母排序的时候才有用,这些选项会对数据的迁移带来很多麻烦。  
configure --prefix=/home/mysql  
make  
make install  

服务的启动和停止  
================  
1 复制缺省的mysql/var/mysql到 /data/app_1/目录下,  
2 MYSQLD的启动脚本:start_mysql.sh  
#!/bin/sh  
rundir=`dirname "$0"`  
echo "$rundir"  
/home/mysql/bin/safe_mysqld --user=mysql --pid-file="$rundir"/mysql.pid --datadir="$rundir"/var "$@"  
-O max_connections=500 -O wait_timeout=600 -O key_buffer=32M --port=3402 --socket="$rundir"/mysql.sock &  

注释:  
--pid-file="$rundir"/mysql.pid --socket="$rundir"/mysql.sock --datadir="$rundir"/var  
目的都是将相应数据和应用临时文件放在一起;  
-O 后面一般是服务器启动全局变量优化参数,有时候需要根据具体应用调整;  
--port: 不同的应用使用PORT参数分布到不同的服务上去,一个服务可以提供的连接数一般是MYSQL服务的主要瓶颈;  

修改不同的服务到不同的端口后,在rc.local文件中加入:  
/data/app_1/start_mysql.sh  
/data/app_2/start_mysql.sh  
/data/app_3/start_mysql.sh  
注意:必须写全路径  

3 MYSQLD的停止脚本:stop_mysql.sh  
#!/bin/sh  
rundir=`dirname "$0"`  
echo "$rundir"  
/home/mysql/bin/mysqladmin -u mysql -S"$rundir"/mysql.sock shutdown  

使用这个脚本的好处在于:  
1 多个服务启动:只需要修改脚本中的--port=参数。单个目录下的数据和服务脚本都是可以独立打包的。  
2 所有服务相应文件都位于/data/app_1/目录下:比如:mysql.pid mysql.sock,当一台服务器上启动多个服务时,多个服务不会互相影响。但都放到缺省的/tmp/下则有可能被其他应用误删。  
3 当硬盘1出问题以后,直接将硬盘2放到一台装好MYSQL的服务器上就可以立刻恢复服务(如果放到my.cnf里则还需要备份相应的配置文件)。  

服务启动后/data/app_1/下相应的文件和目录分布如下:  
/data/app_1/  
start_mysql.sh 服务启动脚本  
stop_mysql.sh 服务停止脚本  
mysql.pid 服务的进程ID  
mysql.sock 服务的SOCK  
var/ 数据区  
mysql/ 用户库  
app_1_db_1/ 应用库  
app_2_db_2/  
...  
/data/app_2/  
...  

查看所有的应用进程ID:  
cat /data/*/mysql.pid  

查看所有数据库的错误日志:  
cat /data/*/var/*.err  

个人建议:MYSQL的主要瓶颈在PORT的连接数上,因此,将表结构优化好以后,相应单个MYSQL服务的CPU占用仍然在10%以上,就要考虑将服务拆分到多个PORT上运行了。  

服务的备份  
==========  
尽量使用MYSQL DUMP而不是直接备份数据文件,以下是一个按weekday将数据轮循备份的脚本:备份的间隔和周期可以根据备份的需求确定  
/home/mysql/bin/mysqldump -S/data/app_1/mysql.sock -umysql db_name | gzip -f>/path/to/backup/db_name.`data +%w`.dump.gz  
因此写在CRONTAB中一般是:  
* 6 * * * /home/mysql/bin/mysqldump -S/data/app_1/mysql.sock -umysql db_name | gzip -f>/path/to/backup/db_name.`data +\%w`.dump.gz  
注意:  
1 在crontab中'%'需要转义成'\%'  
2 根据日志统计,应用负载最低的时候一般是在早上6点  

先备份在本地然后传到远程的备份服务器上,或者直接建立一个数据库备份帐号,直接在远程的服务器上备份,远程备份只需要将以上脚本中的-S /path/to/msyql.sock改成-h IP.ADDRESS即可。  

数据的恢复和系统的升级  
======================  
日常维护和数据迁移:在数据盘没有被破坏的情况下  
硬盘一般是系统中寿命最低的硬件。而系统(包括操作系统和MYSQL应用)的升级和硬件升级,都会遇到数据迁移的问题。  
只要数据不变,先装好服务器,然后直接将数据盘(硬盘2)安装上,只需要将启动脚本重新加入到rc.local文件中,系统就算是很好的恢复了。  

灾难恢复:数据本身被破坏的情况下  
确定破坏的时间点,然后从备份数据中恢复。  

应用的设计要点  
==============  

非用数据库不可吗?  
数据库的确可以简化很多应用的结构设计,但本身也是一个系统资源消耗比较大的应用。所以很多应用如果没有很高的实时统计需求的话,完全可以先记录到文件日志中,定期的导入到数据库中做后续统计分析。如果还是需要记录2维表结构,结构足够简单的话可以使用DBM结构。即使需要使用数据库的,应用如果没有太复杂的数据完整性需求的化,完全可以不使用那些支持外键的商业数据库,  
数据库服务的主要瓶颈:单个服务的连接数  
对于一个应用来说,如果数据库表结构的设计能够按照数据库原理的范式来设计的话,并且已经使用了最新版本的MYSQL,并且按照比较优化的方式运行了,那么最后的主要瓶颈一般在于单个服务的连接数,即使一个数据库可以支持并发500个连接,最好也不要把应用用到这个地步,因为并发连接数过多数据库服务本身用于调度的线程的开销也会非常大了。所以如果应用允许的话:让一台机器多跑几个MYSQL服务分担。将服务均衡的规划到多个MYSQL服务端口上:比如app_1 ==> 3301 app_2 ==> 3302...app_9 ==> 3309。一个1G内存的机器跑上10个MYSQL是很正常的。让10个MYSQLD承担1000个并发连接效率要比让2个MYSQLD承担1000个效率高的多。当然,这样也会带来一些应用编程上的复杂度;  
使用单独的数据库服务器(不要和前台WEB服务抢内存),MYSQL拥有更多的内存就可能能有效的进行结果集的缓存;  
应用尽量使用PCONNECT和polling机制,用于节省MYSQL服务建立连接的开销;  
表的横向拆分:让最常被访问的10%的数据放在一个小表里,90%的历史数据放在一个归档表里,数据中间通过定期“搬家”和定期删除无效数据来节省。这样对于应用来说总是在10%数据中进行选择,比较有利于数据的缓存,不要指望MYSQL中对单表记录数在10万级以上还有比较高的效率。  
表的纵向拆分(过渡范化):将所有的定长字段(char, int等)放在一个表里,所有的变长字段(varchar,text,blob等)放在另外一个表里,2个表之间通过主键关联,这样,定长字段表可以得到很大的优化(甚至可以使用HEAP表类型,数据完全在内存中存取),这里也说明另外一个原则,对于我们来说,尽量使用定长字段可以通过空间的损失换取访问效率的提高。MYSQL之所以支持多种表类型,实际上是针对不同应用提供了不同的优化方式;  
仔细的检查应用的索引设计,甚至在服务启动中加入 --log-slow-queries[=file]用于跟踪分析应用瓶颈。  
   

参考文档:  

MYSQL的命令行选项请参考:  
http://www.mysql.com/doc/C/o/Command-line_options.html  

Mysql初步使用 

作者:zhangabo

SQL(结构化查询语言)是世界上最流行的和标准化的数据库语言。大家用的最多的可能是Microsoft的SQL Server,其功之强大是有目共睹的,但是它的体积非常庞大,而且对硬件要求比较高。以SQL Server 7.0来说,微软的要求是DEC Alpha或兼容系统,Intel Pentium 166MH或以上机型,建议使用 Pentium PRO或PENTIUM II芯片的计算机。如果安装的SQL Server 7.0企业版,那么至少要求64M的内存,如果是其他版本,则至少需要32M内存。

  对某些想学习SQL的人来说,Microsoft SQL Server并不是最佳选择,我给大家介绍一个高效的SQL服务器-MySQL。
MySQL支持多种操作系统,如下所示:
  有原生线程的AIX 4.x
  包括 MIT-pthreads 包的BSDI 2.x
  有原生线程的BSDI 3.0、3.1和4.x
  有原生线程的DEC UNIX 4.x
  包括MIT-pthreads包的FreeBSD 2.x
  有原生程的FreeBSD 3.x
  包括 MIT-pthreads 包的 HP-UX 10.20
  有原生线程的 HP-UX 11.x 。
  有 LinuxThreads 0.7.1 的 Linux 2.0 + 或glibc2.0.7
  MacOS X 服务器
  NetBSD 1.3/1.4 Intel 和 NetBSD 1.3 Alpha ( 需要 GNU make)
  包括 MIT-pthreads 包的 OpenBSD 2.x
  OS/2 Wrap 3、FixPack 29和OS/2 Wrap 4、FixPack 4
  有原生线程的SGI Irix 6.x
  SPARC和x86上有原生线程的Solaris 2.5、2.6和2.7
  包括 MIT-pthreads 包的SunOS 4.x
  有最新FSU Pthreads移植包的SCO OpenServer
  SCO UnixWare 7.0.1
  Tru64 Unix

  MySQL是一个真正的多用户、多线程SQL数据库服务器。MySQL是由一个客户机/服务器结构的实现,它由一个服务器守护程序mysqld和很多不同的客户程序和库组成。
  SQL是一种标准化的语言,它使得存储、更新和存取信息更容易。例如,你能SQL语言为一个网站检索产品信息及存储顾客信息。同时MySQL足够快速和灵活以便允许你存储记录文件和图像。
  MySQL 主要目标是快速、健壮和易用。最早是因为我们需要这样一个SQL服务器,它能处理任何能提供不昂贵硬件平台上的数据库厂家的一个数量级上的大数据库,但速度更快,MySQL被开发出来。自从 1996 年以来,我们一直都在使用MySQL,其环境是有超过 40 个数据库,包含 10,000个表,其中超过500个表超过7 百万行,这大约有100 个吉字节的关键应用数据。
  大家可以从MySQL主页http://www.mysql.com得到最新的Windows版本,目前最新的版本是Mysql-3.23.36-win,ODBC驱动程序的最新版本是myodbc-2.50.36-win95.国内有一个镜像站点   http://www.freecode.com.cn/mirror/mysql/。国内的许多站点也可以下载,比如教育网内的许多大学都有起最新的版本提供下载,如ftp://166.111.136.3 , ftp://ftp.cdit.edu.cn , ftp://ftp.dlut.edu.cn ,ftp://ftp.pku.edu.cn等等。

  我选择基于win32的版本介绍怎么使用MySQL.
  所先你要到以上介绍的站点下载一个比较新的版本,下载回来一般是压缩包,解压到某一目录下并运行setup.exe. 缺省地,MySQL-Win32被配置安装在"C:\mysql"。如果你想要在其它地方安装MySQL,选择你想安装的目录,安装完成即可。安装完成之后安装目录一般包含以下字目录:bench,bin,data,Docs,examples,include,lib,scripts,share.bench下存放配置文件,bin下存放客户程序和mysql服务器,data下存放你所创建的数据库和系统数据库以及记录文件,lib是库文件,Docs下是一些介绍mysql的文档include下的文件是mysql的接口头文件。
  MySQL使用 TCP/IP 把一个客户连接到一个服务器。(这将允许在你的网络上任何机器连接你的MySQL服务器)。因此,你必须在启动MySQL前在你的机器上安装TCP/IP,你可以在你的Windows CDROM上找到TCP/IP 。如果你正在使用一个旧的Win95版本(例如OSR2),很有可能你有一个老的Winsock包!MySQL需要Winsock 2!你可从微软得到最新的Winsock。Win98有新的Winsock 2库作为缺省,这样上述不适用于Win98。
  你可以用三种不同方式启动你的MySQL服务器:
  Mysqld ,用完整调试和自动存储器分配检查编译;
  Mysql-opt, 对Pentium 处理器优化 ,
  Mysqlc,具有命令历史功能(可以用上下箭头翻阅历史记录,免得每次使用都要重新输入命令).
  为了启动mysqld服务器,你应该启动一个MSDOS窗口并键入:
X:\mysql\bin\mysqld/mysql-opt/mysqlc(X为目标驱动器)
这将在一个没有窗口的背景启动mysqld。
你可以这样杀死MySQL服务器,执行:
C:\mysql\bin\mysqladmin -u root shutdown。
  你还可以用一个第三方应用程序winmysqladmin来管理Mysql,这个软件也可以从许多站点得到。
  如果你想从其他地方连接到本地数据库,你还需要安装ODBC驱动程序myodbc.
  通过执行下列命令,你能测试MySQL是否正在工作:
C:\mysql\bin\mysqlshow
C:\mysql\bin\mysqlshow -u root mysql
C:\mysql\bin\mysqladmin version status proc
C:\mysql\bin\mysql test
  用下面这个语句可以设置root口令:
C:\mysql\bin\mysqladmin reload
C:\mysql\bin\mysqladmin -u root password your_password
  对共享版软件,可以这样设置root口令:
C:\mysql\bin\mysql mysql
mysql> UPDATE user SET password=PASSWORD('your password') WHERE user='root';
mysql> QUIT
C:\mysql\bin\mysqladmin reload

  全部设置好以后,你就可以使用mysql了,运行:
x:\mysql\bin\mysql -h localhost -u root -p
  然后根据提示输入你的root密码,出现提示符mysql>,现在你便可以输入命令进行操作了。如:
show databases; 显示现有数据库
use databasename;打开名为databasename的数据库
show tables;显示数据库下的表
create table tablename (column1,column2,…);创建名为tablename的表,包含括号中的几个字段
select,update,insert into ,delete create index,create view等命令操纵mysql进行查询。
  你也可以从远端登录到本地数据库,只要将-h后的localhost改为服务器的ip地址即可,进入之后的操作是一样的。

MYSQL初学者使用指南

作者:fanqiang.com

(上篇)   
有很多朋友虽然安装好了mysql但却不知如何使用它。在这篇文章中我们就从连接MYSQL、修改密码、增加用户等方面来学习一些MYSQL的常用命令。   
一、连接MYSQL。   
格式: mysql -h主机地址 -u用户名 -p用户密码   
1、例1:连接到本机上的MYSQL。   
首先在打开DOS窗口,然后进入目录 mysqlbin,再键入命令mysql -uroot -p,回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL的提示符是:mysql>   
2、例2:连接到远程主机上的MYSQL。假设远程主机的IP为:110.110.110.110,用户名为root,密码为abcd123。则键入以下命令:   
mysql -h110.110.110.110 -uroot -pabcd123   
(注:u与root可以不用加空格,其它也一样)   
3、退出MYSQL命令: exit (回车)   
二、修改密码。   
格式:mysqladmin -u用户名 -p旧密码 password 新密码   
1、例1:给root加个密码ab12。首先在DOS下进入目录mysqlbin,然后键入以下命令   
mysqladmin -uroot -password ab12   
注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。   
2、例2:再将root的密码改为djg345。   
mysqladmin -uroot -pab12 password djg345   
三、增加新用户。(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)   
格式:grant select on 数据库.* to 用户名@登录主机 identified by "密码"   
例1、增加一个用户test1密码为abc,让他可以在任何主机上登录,并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL,然后键入以下命令:   
grant select,insert,update,delete on *.* to test1@"%" Identified by "abc";   
但例1增加的用户是十分危险的,你想如某个人知道test1的密码,那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了,解决办法见例2。   
例2、增加一个用户test2密码为abc,让他只可以在localhost上登录,并可以对数据库mydb进行查询、插入、修改、删除的操作(localhost指本地主机,即MYSQL数据库所在的那台主机),这样用户即使用知道test2的密码,他也无法从internet上直接访问数据库,只能通过MYSQL主机上的web页来访问了。   
grant select,insert,update,delete on mydb.* to test2@localhost identified by "abc";   
如果你不想test2有密码,可以再打一个命令将密码消掉。   
grant select,insert,update,delete on mydb.* to test2@localhost identified by "";   


(下篇)   
在上篇我们讲了登录、增加用户、密码更改等问题。下篇我们来看看MYSQL中有关数据库方面的操作。注意:你必须首先登录到MYSQL中,以下操作都是在MYSQL的提示符下进行的,而且每个命令以分号结束。   

一、操作技巧   
1、如果你打命令时,回车后发现忘记加分号,你无须重打一遍命令,只要打个分号回车就可以了。也就是说你可以把一个完整的命令分成几行来打,完后用分号作结束标志就OK。   
2、你可以使用光标上下键调出以前的命令。但以前我用过的一个MYSQL旧版本不支持。我现在用的是mysql-3.23.27-beta-win。   

二、显示命令   
1、显示数据库列表。   
show databases;   
刚开始时才两个数据库:mysql和test。mysql库很重要它里面有MYSQL的系统信息,我们改密码和新增用户,实际上就是用这个库进行操作。   
2、显示库中的数据表:   
use mysql; //打开库,学过FOXBASE的一定不会陌生吧   
show tables;   
3、显示数据表的结构:   
describe 表名;   
4、建库:   
create database 库名;   
5、建表:   
use 库名;   
create table 表名 (字段设定列表);   
6、删库和删表:   
drop database 库名;   
drop table 表名;   
7、将表中记录清空:   
delete from 表名;   
8、显示表中的记录:   
select * from 表名;   

三、一个建库和建表以及插入数据的实例   
drop database if exists school; //如果存在SCHOOL则删除   
create database school; //建立库SCHOOL   
use school; //打开库SCHOOL   
create table teacher //建立表TEACHER   
(   
id int(3) auto_increment not null primary key,   
name char(10) not null,   
address varchar(50) default '深圳',   
year date   
); //建表结束   
//以下为插入字段   
insert into teacher values('','glchengang','深圳一中','1976-10-10');   
insert into teacher values('','jack','深圳一中','1975-12-23');   

注:在建表中(1)将ID设为长度为3的数字字段:int(3)并让它每个记录自动加一:auto_increment并不能为空:not null而且让他成为主字段primary key(2)将NAME设为长度为10的字符字段(3)将ADDRESS设为长度50的字符字段,而且缺省值为深圳。varchar和char有什么区别呢,只有等以后的文章再说了。 (4)将YEAR设为日期字段。   
如果你在mysql提示符键入上面的命令也可以,但不方便调试。你可以将以上命令原样写入一个文本文件中假设为school.sql,然后复制到c:\下,并在DOS状态进入目录\mysql\bin,然后键入以下命令:   
mysql -uroot -p密码 < c:\school.sql  
如果成功,空出一行无任何显示;如有错误,会有提示。(以上命令已经调试,你只要将//的注释去掉即可使用)。  

四、将文本数据转到数据库中  
1、文本数据应符合的格式:字段数据之间用tab键隔开,null值用\n来代替.  
例:  
3 rose 深圳二中 1976-10-10  
4 mike 深圳一中 1975-12-23  
2、数据传入命令 load data local infile "文件名" into table 表名;  
注意:你最好将文件复制到\mysql\bin目录下,并且要先用use命令打表所在的库 。  

五、备份数据库:(命令在DOS的\mysql\bin目录下执行)  
mysqldump --opt school>school.bbb   
注释:将数据库school备份到school.bbb文件,school.bbb是一个文本文件,文件名任取,打开看看你会有新发现。   

后记:其实MYSQL的对数据库的操作与其它的SQL类数据库大同小异,您最好找本将SQL的书看看。我在这里只介绍一些基本的,其实我也就只懂这些了,呵呵。最好的MYSQL教程还是“晏子“译的“MYSQL中文参考手册“不仅免费每个相关网站都有下载,而且它是最权威的。可惜不是象"PHP4中文手册"那样是chm的格式,在查找函数命令的时候不太方便。  

MySQL优化简明指南

作者:晏子

一、在编译时优化MySQL  
如果你从源代码分发安装MySQL,要注意,编译过程对以后的目标程序性能有重要的影响,不同的编译方式可能得到类似的目标文件,但性能可能相差很大,因此,在编译安装MySQL适应仔细根据你的应用类型选择最可能好的编译选项。这种定制的MySQL可以为你的应用提供最佳性能。

技巧:选用较好的编译器和较好的编译器选项,这样应用可提高性能10-30%。(MySQL文档如是说)

1.1、使用pgcc(Pentium GCC)编译器  
该编译器(http://www.goof.com/pcg/)针对运行在奔腾处理器系统上的程序进行优化,用pgcc编译MySQL源代码,总体性能可提高10%。当然如果你的服务器不是用奔腾处理器,就不必用它了,因为它是专为奔腾系统设计的。

1.2、仅使用你想使用的字符集编译MySQL  
MySQL目前提供多达24种不同的字符集,为全球用户以他们自己的语言插入或查看表中的数据。却省情况下,MySQL安装所有者这些字符集,热然而,最好的选择是指选择一种你需要的。如,禁止除Latin1字符集以外的所有其它字符集:


--------------------------------------------------------------------------------
%>./configure -with-extra-charsets=none [--other-configuration-options]  
--------------------------------------------------------------------------------

1.3、将mysqld编译成静态执行文件  
将mysqld编译成静态执行文件而无需共享库也能获得更好的性能。通过在配置时指定下列选项,可静态编译mysqld。


--------------------------------------------------------------------------------
%>./configure -with-mysqld-ldflags=-all-static [--other-configuration-options]  
--------------------------------------------------------------------------------

1.4、配置样本  
下列配置命令常用于提高性能:


--------------------------------------------------------------------------------
%>CFLAGS="-O6 -mpentiumpro -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared  
--------------------------------------------------------------------------------

二、调整服务器  
确保运用正确的编译固然重要,但这只是成功的第一步,配置众多的MySQL变量同样对服务器的正常运行起关键作用。你可以将这些变量的赋值存在一个配置文件中,以确保它们在每次启动MySQL时均起作用,这个配置文件就是my.cnf文件。

MySQL已经提供了几个my.cnf文件的样本,可在/usr/local/mysqld/share/mysql/目录下找到。这些文件分别命名为my-small.cnf、 my-medium.cnf、my-large.cnf和my-huge.cnf,规模说明可在描述配置文件适用的系统类型标题中找到。如果在只有相当少内存的系统上运行MySQL,而且只是偶尔的用一下,那么my-small.cnf会比较理想,因为它命令mysqld只使用最少的资源。类似地,如果你计划构建电子商务超市,而且系统拥有2G内存,那么你可能要用到mysql-huge.cnf文件了。

为了利用这些文件中的一个,你需要复制一个最适合需求的文件,改名为my.cnf。你可以选择使用配置文件三种作用范围的一种:

Global:将my.cnf文件复制到服务器的/etc目录下,这使得配置文件中的变量作用于全局,即对所有服务器上的MySQL数据库服务器有效。  
Local:将my.cnf文件复制到[MYSQL-INSTALL-DIR]/var/目录下,使得my.cnf作用于特定的服务器。[MYSQL-INSTALL-DIR]表示MySQL安装目录。  
User:你可以再限制作用于特定的用户,将my.cnf复制到用户的根目录下。  
究竟如何设置my.cnf中的这些变量呢?更进一步说,你可以设置哪一个变量。虽然所用变量对MySQL服务器相对通用,每一个变量与MySQL的的某些组件有更特定的关系。如变量max_connects归在mysqld类别下。执行下列命令即可知道:


--------------------------------------------------------------------------------
%>/usr/local/mysql/libexec/mysqld --help  
--------------------------------------------------------------------------------

它显示大量的选项及与mysqld相关的变量。你可以很容易地在该行文字之下找出变量:


--------------------------------------------------------------------------------
Possible variables for option --set-variable (-O) are  
--------------------------------------------------------------------------------

然后你可以如下设置my.cnf中的那些变量:  

--------------------------------------------------------------------------------
set-variable = max_connections=100  
--------------------------------------------------------------------------------

它设置MySQL服务器的最大并发连接数为100。要确保在my.cnf文件中的[mysqld]标题下插入变量设置。  
三、表类型

很多MySQL用户可能很惊讶,MySQL确实为用户提供5种不同的表类型,称为DBD、HEAP、ISAM、MERGE和MyIASM。DBD归为事务安全类,而其他为非事务安全类。

3.1、事务安全

DBD  
Berkeley DB(DBD)表是支持事务处理的表,由Sleepycat软件公司(http://www.sleepycat.com)开发。它提供MySQL用户期待已久的功能-事务控制。事务控制在任何数据库系统中都是一个极有价值的功能,因为它们确保一组命令能成功地执行。

3.2、非事务安全

HEAP  

HEAP表是MySQL中存取数据最快的表。这是因为他们使用存储在动态内存中的一个哈希索引。另一个要点是如果MySQL或服务器崩溃,数据将丢失。  

ISAM  

ISAM表是早期MySQL版本的缺省表类型,直到MyIASM开发出来。建议不要再使用它。  

MERGE  

MERGE是一个有趣的新类型,在3.23.25之后出现。一个MERGE表实际上是一个相同MyISAM表的集合,合并成一个表,主要是为了效率原因。这样可以提高速度、搜索效率、修复效率并节省磁盘空间。  

MyIASM  

这是MySQL的缺省表类型。它基于IASM代码,但有很多有用的扩展。MyIASM比较好的原因:  

MyIASM表小于IASM表,所以使用较少资源。  
MyIASM表在不同的平台上二进制层可移植。  
更大的键码尺寸,更大的键码上限。  
3.3、指定表类型

你可在创建表时指定表的类型。下例创建一个HEAP表:


--------------------------------------------------------------------------------

mysql>CREATE TABLE email_addresses TYPE=HEAP (
    ->email char(55) NOT NULL,
    ->name char(30) NOT NULL,
    ->PRIMARY KEY(email) );


--------------------------------------------------------------------------------

BDB表需要一些配置工作,参见http://www.mysql.com/doc/B/D/BDB_overview.html。  

3.4、更多的表类型  

为了使MySQL管理工作更有趣,即将发布的MySQL 4.0将提供两种新的表类型,称为Innobase和Gemeni。  

4、优化工具  

MySQL服务器本身提供了几条内置命令用于帮助优化。  

4.1、SHOW  

你可能有兴趣知道MySQL服务器究竟更了什么,下列命令给出一个总结:  


--------------------------------------------------------------------------------
mysql>show status;  
--------------------------------------------------------------------------------

它给出了一个相当长的状态变量及其值的列表。有些变量包含了异常终止客户的数量、异常终止连接的数量、连接尝试的次数、最大并发连接数和大量其他有用的信息。这些信息对找出系统问题和低效极具价值。  
SHOW还能做更多的事情。它可以显示关于日志文件、特定数据库、表、索引、进程和权限表中有价值的信息。详见MySQL手册。

4.2、EXPLAIN

当你面对SELECT语句时,EXPLAIN解释SELECT命令如何被处理。这不仅对决定是否应该增加一个索引,而且对决定一个复杂的Join如何被MySQL处理都是有帮助的。

4.3、OPTIMIZE

OPTIMIZE语句允许你恢复空间和合并数据文件碎片,对包含变长行的表进行了大量更新和删除后,这样做特别重要。OPTIMIZE目前只工作于MyIASM和BDB表。  
  

 

MySQL数据目录结构

作者:fanqiang.com

从概念上讲,大多数关系数据库系统是相似的:它们有一系列数据库组成,每个数据库包含一系列数据库表,但每个系统有各自组织其管理的数据方式,MySQL也不例外。   

缺省地,所有由MySQL服务器mysqld管理的数据存储在一个称为MySQL数据目录的地方,所有数据库都存放在哪儿,也包括提供服务器操作信息的状态文件。如果你对一个MySQl安装执行管理任务,你应该熟知数据目录的布局及用途。   

本文介绍下列专题:   

如何确定数据目录的位置。   
服务器如何组织并提供对数据库和它管理的表的访问。   
在哪里找到由服务器生成的状态文件记忆它们包含什么内容。   
如何改变缺省地点或数据目录或单独数据库的组织结构。   
1、数据目录的位置   
一个缺省数据目录被编译进了服务器,如果你从一个源代码分发安装MySQL,典型的缺省目录为/usr/local/var,如果从RPM文件安装则为/var/lib/mysql,如果从一个二进制分发安装则是/usr/local/mysql/data。   

在你启动服务器,通过使用一个--datadir=/path/to/dir选项可以明确指定数据目录位置。如果你想把数据目录置于其它缺省位置外的某处,这很有用。   

作为一名MySQL管理员,你应该知道你的数据目录在哪里。如果你运行多个服务器,你应该是到所有数据目录在哪里,但是如果你不知道确切的位置,由多种方法找到它:   

使用mysqladmin variables从你的服务器直接获得数据目录路径名。查找datadir变量的值,在Unix上,其输出类似于:   
%mysqladmin variables   

+----------------------+----------------------+   
| variable_name | Value |   
+----------------------+----------------------+   
| back_log | 5 |   
| connect_timeout | 5 |   
| basedir | /var/local/ |   
| datadir | /usr/local/var/ |   
....   
在Windows上,输出可能看上去像这样:   
c:\mysqladmin variables   

+----------------------+----------------------+   
| variable_name | Value |   
+----------------------+----------------------+   
| back_log | 5 |   
| connect_timeout | 5 |   
| basedir | c:\mysql\ |   
| datadir | c:\mysql\data\ |   
....   
如果你有多个服务器在运行,它们将在不同的TCP/IP端口或套接字上监听,通过提供连接服务器正在监听的端口或套接字的--port或--socket选项,你可以轮流获得它们每一个的数据目录信息:   

%msqladmin --port=port_name variables   

%mysqladmin --socket=/path/to/socket variables   

mysqladmin命令可运行在任何你能从其连接服务器的主机上,如果你想在一个远程主机连接服务器,使用一个--host=host_name选项:   

%mysqladmin --host=host_name variables   

在Windows上,你可以通过使用--pipe强制一个命令管道连接和--socket=pipe_name指定管道名来连接监听一个命令管道的NT服务器:   

c:\mysqladmin --pipe --socket=pipe_name variables   

你可以使用ps命令查看任何正在运行mysqld 进程的命令行。   
试一下下列命令之一并寻找--datadir:   

%ps axww | grep mysql BSD风格   

%ps -ef | grep mysqld System V风格   

如果你的系统运行多个服务器,ps命令可能特别有用,因为你能马上发现多个数据目录位置,缺点是必须在服务器上运行,而且可能没有有用的信息产生,除非在mysqld命令行上明确指定了--datadir选项。   

如果MySQL是从一个源代码分发安装的,你可以检查其配置信息确定数据目录位置。例如,位置可从顶级Makefile中获得,但是注意,位置是Makefile中的localstatedir值,不是datadir,而且,如果分发位于一个NFS挂载的文件系统并用来为多个主机构建MySQL,配置信息反映了分发被最新构建的主机,这可能不能提供你感兴趣的主机的数据目录信息。   
如果上述方式失败,你可以用find寻找数据库文件,下列命令寻找“.frm”文件,它是任何MySQL安装的一部分:   

% find / -name ".frm" -print   

在下文各例中,用DATADIR表示MySQL数据目录位置。   
2、数据目录结构   
MySQL数据目录包含了服务器管理的所有数据目录,这些文件被组织成一个树状结构,通过利用Unix或Windows文件系统的层次结构直接实现。   

每个数据库对应于数据目录下的一个目录。   
在一个数据库中的表对应于数据目录下的文件。   
数据目录也包含由服务器产生的几个状态文件,如日志文件。这些文件提供了关于服务器操作的重要信息。对管理特别在出了问题而试图确定问题原因时很有价值。例如,如果某个特定查询杀死服务器,你可以通过检查日志文件判别捣乱的查询。   

2.1 MySQL服务器怎样提供对数据的访问   
在数据目录下的一切由一个单独的实体-MySQL服务器mysqld管理,客户程序绝不直接操作数据。相反,服务器提供数据可访问的切入点,它是客户程序与它们想使用的数据之间的中介。   

当服务器启动时,如果有需要,它打开日志文件,然后通过监听网络连接位数据目录呈现一个网络接口。要访问数据,客户程序建立对服务器的一个连接,然后以MySQL查询传输请求来执行希望的操作。服务器执行每一个操作并将结果发回用户。服务器是多线程的并能服务多个同时的客户连接。然而,因为修改操作一个执行一个,实际效果是顺序化请求,以使两个客户决不能在同一时刻改变同一记录。   

在正常的情况下,让服务器作为数据库访问的唯一仲裁者提供了避免可从同时访问数据库表的多个进程的破坏的保证。管理员应该知道有时服务器没有对数据目录的独裁控制。   

当你在一个单个数据目录上运行多个服务器。一般倪云新一个服务器管理主机上的所有数据库,但是有可能运行多个服务器。如果这完成提供对多个独立数据目录的访问,没有相互影响的问题,但哟也能启动多个服务器并指向同一个目录。一般地,这不是一个好主意。如果你试图这样,最好是你的系统提供良好的文件锁定功能,否则服务器将不能正确协作。如果你将多个服务器同时写入日志文件,你也冒着你的日志文件称为混乱的根源的风险。   
在你运行isamchk和myisamchk时。isamchk和myisamchk实用程序用于表的维护、诊错和修复,就想你想的那样,因为这些程序可以修改表内容,允许它们与服务器正在操作的同时对表操作,这样能导致表损坏。理解如何限制这种相互影响是很重要的,这样你不会损坏你的表。   
2.2 数据目表示   
每个MySQL服务器管理的数据库有自己的数据库表,它是数据目录下的一个子目录,其名字与它表示的数据库相同。例如数据库my_db对应于数据库目录DATADIR/my_db。   

这种表示允许多个数据库级的语句在其实现中十分简单。CREATE DATABASE db_name在数据目录中创建一个db_name空目录,具有只允许MySQL服务器用户(运行服务器的Unix用户)的属主和模式,这等价于下列手工在服务器主机上创建数据库:   

%mkdir DATADIR/db_name   
%chmod 700 DADADIR/db_name   
用一个空目录表示一个新数据库的最简单方法与其它数据库甚至为一个空数据库创建大量的控制文件或系统文件正好相反。   

DROP DATABASE语句实现同样简单。DROP DATABASE db_name删除数据库中的db_name目录和所有表文件,这几乎与下列命令一样:   

%rm -rf DATADIR/db_name   
(差别是服务器只删除具有已知用于表的后缀名的文件。如果你在数据库目录创建了其它文件。则服务器保留它们,而且目录本身不被删除。   

SHOW DATABASE基本上不做什么,只是列出位于数据目录中的目录名。有些数据库系统保持一个主表,用于维护所有数据库,但在MySQL无此构件。由于赋予数据目录结构的简洁性,数据库列表隐含在数据目录的内容中,而且这样的表不必有额外的开销。   

2.3 数据库表的表示   
每个数据库在数据库目录中有3个文件:一个样式(描述文件)、一个数据文件和一个索引文件。每个文件的基本名是表名,文件名扩展名代表文件类型。扩展名如下表。数据和索引文件的扩展名指出表使用老式IASM索引或新式MyISAM索引。   

表 MySQL文件类型   
文件类型 文件名扩展名 文件内容   
样式文件 .frm 描述表的结构(它的列、列类型、索引等)。   
数据文件 .ISD(ISAM)   
或.MYD(MyISAM) 包含数据文件上的所有索引的索引树。   
索引文件 .ISM(ISAM)   
或.MYI(MyISAM) 该索引文件依赖表是否有索引而存在。   

当你发出一条CREATE TABLE tbl_name时语句定义表的结构时,服务器创建一个名为tbl_name.frm的文件,它包括该结构的内部编码,同时也创建一个空数据和索引文件,初始化为包含指出无记录和无索引的信息(如果CREATE TABLE语句包括索引指定,索引文件反映出这些索引)。对应于表的文件的属主和模式被设置为只允许MySQL服务器用户访问。   

当你发出一条ALTER TABLE tbl_name语句时,服务器重新编码tbl_name.frm,并修改数据和索引文件的内容以反映语句指定的结构改变。对于CREATE INDEX和DROP INDEX也是一样,因为它们被服务器视为与ALTER TABLE等价。DROP TABLE通过删除对应于表的三个文件来实现。   

虽然你可以通过删除数据库目录中对应于表的三个文件,但不能手工创建或修改一个表,如,如果my_db是当前数据库,DROP TABLE my_tbl大概等价于下列命令。   

% rm -rf DATADIR/my_db/my_tbl.*   

SHOW TABLE my_db的输出只是列出my_db数据库目录中的.frm文件的基文件名。有些数据库系统一个注册表,列举所有包含在一个数据库中的表,MySQL不是,因为不必要,“注册表”隐含在数据目录的结构中。   

2.4 操作系统对数据库和表命名的限制   
MySQL对命名数据库和表有一个原则:   

名字可以由当前字符集中的任何字母数字字符组成,下划线和美元符$也可以。   
名字最长为64个字符。   
然而,因为数据库和表的名字对应于目录和文件名,服务器运行的操作系统可能强加额外的限制。   

首先,数据库和表名仅限于对文件名合法的字符,如$在MySQL的原则中是允许的,但是如果你的操作系统不允许,则你不能在目录或表名中使用它。实际上,这对Unix或Windows不是所担心的,最大的难度是在执行数据库管理时直接在shell中引用名字,例如,如果你命名一个数据库如$my_db,包含一个美元符,任何从shell中对该名字的引用可能被shell解释为对一个变量的引用:   

%ls $my_db   
my_db:undefined variable   

对此,你必须转义$字符或用引号禁止其特殊含义:   

%ls \$my_db   
%ls $my_db   

如果你用引号,一定要用单引号,而双引号并不禁止变量解释。   

其次,虽然MySQL允许数据库和表名最长到64个字符,但名字的长度受限于你的操作系统限定的长度,一般这不是一个问题(虽然老的System V强制14个字符)。在这种情况下,你数据库名的上限为14个字符,而表名上限为10个字符,因为表示表的文件名有一个点(.)和三个字符的扩展名。   

第三,文件系统的大小写敏感性影响到你如何命名和引用数据库和表名。如果文件系统是大小写敏感的(如Unix),两个名字my_tbl和MY_TBL是不同的表。如果文件系统不是大小写敏感的(如Windows),这两个名字指的是相同的表。如果你用一个Unix服务器开发数据库,并且如果你有可能转移到Windows,你应该记住这一点。   

2.5 MySQL状态文件   
除了数据库目录,MySQL数据目录还包含很多状态文件,这些文件总结在下表中。大多数文件的缺省名从服务器主机名生成,在下表中表示为HOSTNAME。   

表 MySQL状态文件   
文件类型 缺省名 文件内容   
进程ID HOSTNAME.pid 服务器进程的ID   
出错日志 HOSTNAME.err 启动和关闭事件和出错情况   
一般日志 HOSTNAME.log 连接/断开事件和查询信息   
更新日志 HOSTNAME.nnn 修改表结构级内容的所有查询文本   

当服务器启动时,它将其进程ID写入进程ID(PID)文件中,而在它关闭时,删除该文件。PID文件是允许服务器本身被其他进程找到的工具。例如,如果你运行mysql.server,在系统关闭时,关闭MySQL服务器的脚本检查PID文件以决定它需要向哪个进程发出一个终止信号。   

出错日志由safe_mysqld创建,作为服务器标准出错输出的重定向,它包含任何邪到stderr的消息。这意味着只有你通过调用safe_mysqld启动服务器,出错文件才存在(无论如何,它是一个启动服务器的最好方法,因为如果它由于出错而退出,safe_mysqld将重启服务器。)。   

一般日志和更新日志是可选的。你可以只开启你需要的日志类型,用--log和--log-update服务器选项。   
一般日志提供服务器操作的一般信息:谁从哪里连接服务器和他们发出什么查询。更新日志提供查询信息,但只有修改数据库内容的查询。更新日志内容被写成SQL语句,可以将它们提供给mysql客户程序来执行。如果你遇上崩溃,并且必须倒回备份文件,更新日志就很有用,因为你能重复执行自崩溃时的更新,通过将更新日志反馈给服务器,这允许你将数据库恢复到崩溃发生时的状态。   

下面是一个简单的例子,信息出现在一般日志中,它是一个创建一个在数据库test中表,插入一行,然后删除表的会话:   

990509 7:37:09 492 Connect Paul@localhost on test   
492 Query show databases   
492 Query show tables   
492 Field List tbl_1   
492 Field List tbl_2   
...   
990509 7:34:22 492 Query CREATE TABLE my_tbl (val INT)   
990509 7:34:34 492 Query INSERT INTO my_tbl values (1)   
990509 7:34:38 492 Query DROP TABLE my_tbl   
990509 7:34:40 492 Quit   
一般日志包含日期和时间、服务器进程ID、事件类型和事件信息栏目。   

同一个会话出现在更新日志中看上去像这样:   

use test;   
CREATE TABLE my_tbl (val int);   
INSERT INTO my_tbl VALUES(1);   
DROP TABLE my_tbl;   
对更新日志,用--log-long-format选项获得一个扩展形式的日志,扩展日志提供有关谁何时发出每一条查询,这使用更多的磁盘空间,但如果你想知道谁在做什么,而不用将更新日志对照一般日志的内容找到连接事件。   

对上面的会话,扩展更新日志产生这样的信息:   

# Time: 990507 7:32:42   
# User@Host: paul [paul] @ localhost []   
use test;   
CREATE TABLE my_tbl (val int);   
# User@Host: paul [paul] @ localhost []   
INSERT INTO my_tbl VALUES(1);   
# Time: 990507 7:32:43   
# User@Host: paul [paul] @ localhost []   
DROP TABLE my_tbl;    
保证你的日志文件安全并且不让任意用户读取是个好主意。一般日志和更新日志都能包含诸如口令等的敏感信息,因为它们包含查询文本。如:   

990509 7:23:31 4 Query UPDATE user SET Password=PASSWORD("secret")   
WHERE user="root"   
对于检查和设置数据目录的权限,请见《MySQL安全性指南》。使数据目录安性的指令包含下列命令:   

% chmod 700 DATADIR   

以拥有数据目录的Unix用户运行此命令。确保服务器也以此用户运行,否则该命令不仅将其它人拒之门外,它也阻止服务器访问你的数据库。   

状态文件出现在数据目录的顶级目录,就象数据库目录,所以你可能担心这些文件名是否与数据库名冲突或出错(如在服务器执行SHOW DATABASES语句时)。答案是不。状态和日志文件信息存储在文件中,而数据库是目录,所以可执行程序能用一个简单的stat()调用区分它们。如果你看一下数据目录,你可以区分状态文件和数据库目录,用ls -l并检查模式的第一个字符是一个"_"还是一个"d"。   

你也可以简单地看一下名字,所有状态文件名包含一个点("."),而数据库目录没有(.在数据库名中是无效字符)。   

MySQL服务器的启动与停止

作者:晏子

一、以非特权用户运行MySQL服务器
在讨论如何启动MySQL服务器之前,让我们考虑一下应该以什么用户身份运行MySQL服务器。服务器可以手动或自动启动。如果你手动启动它,服务器以你登录Unix(Linux)的用户身份启动,即如果你用paul登录Unix并启动服务器,它用paul运行;如果你用su命令切换到root,然后运启动服务器,则它以root运行。然而,大多数情况下你可能不想手动启动服务器,最有可能是你安排MySQL服务器在系统引导时自动启动,作为标准引导过程的一部分,在Unix下,该引导过程由系统的Unix用户root执行,并且任何在该过程中运行的进程均以root权限运行。

你应该牢记MySQL服务器启动过程的两个目标:

你想让服务器以某个非root用户运行。一般地,你想限制任何运行进程的能力,除非确实需要root权限,而MySQL不需要。  
你想让服务器始终以同一个用户运行,此时用一个用户而其他时候以另一个不同的用户运行服务器是很不方便的,这造成了为文件和目录以具有不同属主的数据目录下被创建,并可能导致服务器不能访问数据库或表,这看你以哪个用户运行。统一用同一个用户运行服务器是你避免这个问题。  
要一个普通的非特权用户运行服务器,按照下列步骤:

选择一个用于运行服务器的用户,mysqld可以用任何用户运行。但在概念上较清晰的是为MySQL操作创建一个单独的用户。你也可以特别为MySQL选择一个用户组。本文使用mysqladm和mysqlgrp分别作为用户名和用户组名。
如果你已在自己的账号下安装好了MySQL且没有系统上的特殊管理权限,你将可能在你自己的用户ID下运行服务器。在这种情况下,用你自己的登录名和用户组代替mysqladm和mysqlgrp。
如果你在RedHat Linux上用rpm文件安装MySQL,该安装将自动创建一个名为mysql的账号,用该账号代替mysqladm。  
如果必要,用系统通常的创建用户的过程创建服务器账号,你需要用root做它。  
如果服务器在运行,停止它。  
修改数据目录和任何子目录和文件的属主,这样使得mysqladm用户拥有它们。例如,如果数据目录是/usr/local/var,你可以如下设置mysqladm的属主(你需要以root运行这些命令):

#cd /usr/local/var
#chown -R mysqladm.mysqlgrp

修改数据目录和任何子目录和文件的权限,使得它们只能由mysqladm用户访问。如果数据目录是/usr/local/var,你可以设置由mysqladm拥有的任何东西:

# cd /usr/local/var
# chmod -R go-rwx  
当你设置数据目录及其内容的属主和模式时,注意符号连接。你需要顺着它们并改变它们指向的文件或目录的属主和模式。如果连接文件的目录位于不属于你的地方,会有些麻烦,你可能需要root身份。

在你完成了上述过程后,你应该确保总是在以mysqladm或root登录时启动服务器,在后者,确定指定--user=mysqladm选项,使服务器能将其用户ID切换到mysqladm(同时也适用于系统启动过程)。

--user选项在MySQL 3.22中引入,如果你有老版本,你可以使用su命令告诉系统在以root运行时在特定的用户下运行服务器。

二、启动服务器的方法
在我们确定了用于运行服务器的账号后,你可以选择如何安排启动服务器。你可以从命令行手动或在系统引导过程中自动地运行它。对于启动服务器由三种主要方法:

直接调用mysqld。
这可能是最不常用的方法,建议不要多使用,因此本文不详细介绍。  
调用safe_mysqld脚本。
safe_mysqld试图确定服务器程序和数据目录的位置。然后用反映这些值的选项调用服务器。safe_mysqld将标准出错设备从服务器重定位到数据目录下的一个出错文件,使得有它的一条记录。在启动服务器后,safe_mysqld也监视它并且如果它死掉则重启它。safe_mysqld常用于BSD风格的Unix系统。
如果你以root或在系统引导期间启动sqfe_mysqld,出错日志由root拥有,这可能在你以后试图用一个非特权用户调用safe_mysqld时将导致“permission denied”(权限拒绝)错误,删除出错日志再试一下。  
调用mysql.server脚本。
这个脚本通过有意用于System V的启动和停止系统上的safe_mysqld.mysql.server来启动服务器,该系统包含几个包含在机器进入或退出一个给定运行级别时被点用的脚本目录。它可以用一个start或stop参数点用以表明你是想启动还是想停止服务器。  
safe_mysqld脚本安装在MySQL安装目录的bin目录下,或可在MySQL源代码分发的scripts目录下找到。mysql.server脚本安装在MySQL安装目录下的share/mysqld目录下或可以在MySQL源代码分发的support_files目录下找到。如果你想使用它们,你需要将它们拷贝到适当的目录下。

对BSD风格的系统(FreeBSD,OpenBSD等),通常在/etc目录下有几个文件在引导时初始化服务,这些文件通常有以“rc”开头的名字,且它有可能由一个名为“rc.local”的文件(或类似的东西),特意用于启动本地安装的服务。在这样的系统上,你可能将类似于下列的行加入rc.local文件中以启动服务器(如果safe_mysqld的目录在你的系统上不同,修改它即可):

if [ -x /usr/local/bin/safe_mysqld ]; then
  /usr/local/bin/safe_mysqld &
fi
对于对于System V风格的系统,你可以通过将mysql.server放在/etc下适当的启动目录下来安装它。如果你运行Linux并从一个RPM文件安装MySQL,这些已经为你做好了,否则将脚本安装在主启动目录下,并将指向它的连接放在适当的运行级别目录下。你也可以使脚本只能由root启动。  

启动文件的目录布局各系统不同,所以你需要检查一下看看你的系统如何组织它们。例如在Linux PPC上,目录是/etc/rc.d和/etc/rc.d/rc3.d,这样你可以这样安装脚本:

#cp mysql.server /etc/rc.d/init.d
#cd /etc/init.d
#chmod 500 mysql.server
#cd /etc/rc.d/rc3.d
#ln -s ../init.d/mysql.server S99mysql
在solaris上,主脚本目录是/etc/init.d,并且运行级别目录是/etc/rd2.d,所以命令看上去像这样:

#cp mysql.server /etc/rc.d/init.d
#cd /etc/init.d
#chmod 500 mysql.server
#cd /etc/rc2.d
#ln -s ../init.d/mysql.server S99mysql
在系统启动时,S99mysql脚本将自动用一个start参数调用。如果你有chkconfig命令(Linux上有),你可以由它帮助安装mysql.server脚本而不是象上面那样手工运行上述命令。

2.1 指定启动选项
如果你想在服务器启动时指定额外的启动选项,你可有两种方法。你可以修改你使用的启动脚本(safe_mysqld或mysql.server)并直接在调用服务器的行上指定选项,或在一个选项文件中指定选项。建议你如果可能在一个全局选项文件中指定选项,它通常位于/etc/my.cnf(Unix)或c:\my.cnf(Windows)。

某些种类的信息无法以服务器选项指定。对于这些你可能需要修改safe_mysqld。例如,如果你的服务器不能正确选择本地时区而以GMT返回时间值,你可以设置TZ环境变量给它一个指示。如果你用safe_mysqld或mysql.server启动服务器,你可以将一个时区设置加到safe_mysqld。找到启动服务器的行并在该行前加入下列命令:

TZ=US/Central
export TZ
上面命令的语法是Solaris的,对于其他系统语法可能不同,请查阅相关手册。如果你确实修改了你的启动脚本,要记住下次你安装MySQL时(如升级到新版本),你的修改将失去,除非你首先在别处复制了启动脚本。在安装了新版本后,比较新旧版本的脚本,看看你需要重建什么改变。

2.2 在启动时检查你的表
除了安排你的服务器在系统引导时启动,你可能要安装myisamchk和isamchk脚本,以在服务器启动前检查你的表。你可能在一个崩溃后重启,有可能表已经损害,在启动前检查它是一个发现问题的好方法。

三、停止服务器
要手工启动服务器,使用mysqladmin:

%mysqladmin shutdown

要自动停止服务器,你不需做特别的事情。BSD系统一般通过向进程发一个TERM信号停止服务,它们或者正确应答它或被粗鲁地杀死。mysqld在它收到这个信号时以终止作为应答。对于用mysql.server启动服务器的System V风格的系统,停止进程将用一个stop参数调用该脚本,告诉服务器终止,当然假定你已安装了mysql.server。

四、如果你不能连接服务器,如何重新获得对服务器的控制
在某些情况下,你可能由于不能连接它而手工重启服务器。当然,这有点矛盾。因为一般你通过连接服务器而手工关掉它,那么这种情况如何会出现。

首先,MySQL root口令可以已经设置为你不知道的值,这可能发生在你修改口令时,例如,如果你在输入新口令时偶然键入一个不可见的控制字符。你也可能忘记口令。

其次,连接localhost通常通过一个Unix域套接字文件进行,一般是/tmp/mysql.sock。如果套接字文件被删除了,本地客户就不能连接。这可能发生在你的系统运行一个cron任务删除了/tmp下的临时文件。

如果你因为丢失套接字文件而不能连接,你可以简单地通过重启服务器重新创建得到它。因为服务器在启动时重新创建它。这里的骗局是你不能用套接字建立连接因为它不见了,你必须建立一个TCP/IP连接,例如,如果服务器主机是pit.snake.net,你可以这样连接:

%mysqladmin -p -u root -h pit.snake.net shutdown

如果套接字文件被一个cron任务删除,问题将重复出现,除非你修改cron任务或使用一个或使用一个不同的套接字文件,你可以使用全局选项文件指定一个不同的套接字,例如,如果数据目录是/usr/local/var,你可以通过将下列行加入/etc/my.cnf中,将套接字文件移到那里:

[mysqld]
socket=/usr/local/var/mysql.sock

[client]
socket=/usr/local/var/mysql.sock
对服务器和客户均指定路径名,使得它们都使用同一个套接字文件。如果你只为服务器设置路径,客户程序将仍然期望在原位置执行套接字,在修改后重启服务器,使它在新位置创建套接字。

如果你由于忘记root口令或已经将它设置为不同于认为的值而不能连接,你需要重新获得对服务器的控制,是你能再次设置口令:

中断服务器
如果你以root登录服务器主机,你可以用kill命令终止服务器。你可以使用ps命令或通过寻找服务器的PID文件(通常在数据目录中)找出服务器进程的ID。
最好是首先尝试用一个向服务器发出一个TERM信号的正常kill看它是否将以正常终止应答。这种方式下,表和日志将正确地被清空。如果服务器阻塞并且不应答一个正常终止信号,你可以用kill -9强制终止它。这是最后的手段了,因为这可能有未清空的修改,而且你冒着让表处于一个不一致状态的风险。
如果你用kill -9终止服务器,要确保在启动服务器前用myisamchk和isamchk检查你的表。  
用--skip-grant-table选项重启服务器。
这告诉服务器不使用授权表验证连接,这允许你以root连接而无须口令。在你已经连接后,改变root口令。  
用mysqladmin flush-privileges告诉服务器再次使用授权表启动
如果你的mysqladmin版本不认识flash-privileges,试一试reload。  
五、运行多个服务器
大多数再一台给定的机器上运行单个MySQL服务器,但在很多情况下,运行多个服务器是很有用的:

你可能想测试一个服务器的新版本,而保留你正在运行的生产服务器。在这种情况下,你会运行不同的服务器代码。  
操作系统一般限制每个进程的打开文件句柄数量。如果你的系统很难提高这个限制,运行多个服务器是解决限制的一种方法。在这种情况下,你可能运行统一服务器的多个实例。  
ISP经常为其客户提供自己的MySQL安装,有必要涉及单独的服务器。在这种情况下,你可能运行同一版本的多个实例或不同版本,如果不同的客户想要不同版本的MySQL。  
很自然地,运行多个服务器比只运行一个服务器要复杂得多。如果你安装多个版本,你不能在同一个地方安装所有东西。当服务器运行时,某些参数必须或很可能对每个服务器是唯一的,它们包括服务器在哪安装、其数据目录的路径名、TCP/IP端口和UNIX域套接字路径名以及用于运行服务器的UNIX账号(如果你不再同一账号下运行所有服务器)。如果你决定运行多个服务器,一定要注意你使用的参数,是你不至于丢失对所发生的事情的踪迹。

5.1 配置和安装多个服务器
如果你要运行不同版本的服务器而不是同一版本的多个实例,你必须在不同地点安装它们。如果你安装二进制分发(不用RPM),它们将安装在包含不同版本号的目录名下。如果你从源代码安装,最简单的方法是在每个版本运行configure配置MySQL安装过程中使用--with-prefix选项使得不同分发分开,这将使得所有东西安装在一个单独的目录下,你可以将目录域分发版本号联系起来,如,你可以象这样配置一个MySQL分发,其中version是MySQL版本号:

%.configure --with-prefix=/usr/local/mysql-version
--with-prefix选项也决定了服务器的一个唯一数据目录。你可能想加上其它服务器特定的选项,如TCP/IP端口号和套接字路径名(--with-tcp-port和--with-unix-socket)。

如果你想运行同一版本服务器的多个实例,任何必须基于一个服务器特定设置的选项将需要在运行时指定。

5.2 多服务器的启动过程
启动多个服务器比使用一个服务器要复杂。因为safe_mysqld和mysql.server均在单个服务器设置上工作得最好。建议你仔细研究一下safe_mysqld并用它作为你的启动过程的基础,使用你修改的版本,你能针对你自己的需要更精确地裁剪它。

你必须处理的一个问题是如何在选项文件(my.cnf)中指定选项。对于多服务器,你不能对于每个不同的服务器设置使用/etc/my.cnf,你只能对所有服务器相同的设置使用该文件。如果服务器有一个不同的编译进去的数据目录位置,你可以在每个服务器数据目录中的my.cnf中指定所有服务器要使用的设置,而使用DATADIR/my.cnf指定服务器特定的设置,这里DATADIR以服务器不同而不同。

另一种指定服务器选项的方法是用--default-file=path_name作为命令行的第一个选项,告诉服务器从名为path_name中的文件中读取选项,这样你可以把一个服务器选项放在一个对该服务器唯一的文件中,然后告诉服务器在启动时读取该文件。注意,如果你指定这个选项,将不使用通常的选项文件如/etc/my.cnf的任何一个。

关于mysql中文排序的方法

作者:baitie

方法1  
----  
"mysql在查询字符串时是大小写不敏感的,在编绎mysql时一般以ISO-8859字符集作为默认的字符集,因此在比较过程中
中文编码字符大小写转换造成了这种现象,比较应急的方法是对于包含中文的字段加上"binary"属性,使之作二进制比较,
例如将"name char(10)"改成"name char(10)binary"."  
(已试验成功)  

方法2  
-----  
编译mysql时使用--with--charset=gbk  
(未测试)  

MySQL 文件系统

作者:徐永久

这个文件系统还处于实现中,还不是正式产品。

这是一款正在开发中的Linux 文件系统,能把Linux 上的
MySQL 数据库作为文件系统来处理。开发小组希望能得到
更多的建议,下面的文章翻译自:
http://no.spam.ee/~tonu/mysqlfs.html

--------------------------------
实际上,这不是通常意义上的文件系统,它没有磁盘空间,
而是使用MySQL 守护程序来存储数据。可以把SQL 表和
一些函数通过文件系统来实现。

一、怎样实现?

让我们来看使用实例:

[root@localhost /root]# mount -t corbafs -o `cat /tmp/mysqlcorbafs.ior` none
/mnt/mysql/

[root@localhost /root]# mount
/dev/hda3 on / type ext2 (rw)
none on /proc type proc (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/hda1 on /mnt/win type vfat (rw,mode=777)
/dev/hda4 on /mnt/linux type vfat (rw,noexec,nosuid,nodev,mode=777)
none on /mnt/mysql type corbafs
(rw,IOR:01e50d401b00000049444c3a436f72626146532f46696c6553797374656d3a312e
300000010000000000000030000000010100000a0000003132372e302e302e310008041800
0000000000009224bc335663462a01000000ef7ae13c0943c59f)

[root@localhost /root]# ls -la /mnt/mysql/

total 0

-r-xr-xr-x 1 root root 4096 dets 29 22:21 .uptime
dr-xr-xr-x 1 root root 4096 dets 29 22:21 test
dr-xr-xr-x 1 root root 4096 dets 29 22:21 mysql

[root@localhost /root]# cat /mnt/mysql/.uptime

1994

[root@localhost /root]# cat /mnt/mysql/mysql/user/Host

cpq.spam.ee
cpq.spam.ee
localhost
localhost
localhost
localhost
localhost
localhost

[root@localhost /root]# cat /mnt/mysql/mysql/user/Insert_priv
N
N
N
N
N
N
Y
Y

[root@localhost /root]# umount /mnt/mysql/

二、为什么要这样做呢?

在一些情形下,这样做能让工作更加轻松。MySQL 和文件系统都能叫做数据库,但是有
着绝然不同的概念和优缺点。在文件系统里,对象能很快而且很容易找到,即使改变名
字也能很快找到。每一个初学者大概都应该学会move/copy/rename/delete这样的操作。
但是SQL 不一样,
他通过应用程序来操纵存储在文件系统上的数据。而MySQL 文件系统把SQL 做到了用户
级。用户能用他们知道的方式来操作数据库。

-任何一个新产品需要通过网络存取数据的话,必须支持一些协议以及可能的其他办法通
过网络存取文件系统。MySQL 表就可以通过这样的方式来存取,即使MySQL 没有移植到
对应的平台。

-备份和版本控制,普通的文件系统通过任何备份软件就可以实现。数据可以通过diff  
来比较并且用cvs 来控制版本。

-更短的编程时间,有时候人们需要保存简单的数据,像当前日期或者站点名字,这些数
据很少改变,普通的方法需要使用:

连接服务器-> 选择数据库 -> 执行命令-> 存储结果

而使用 MySQL 文件系统后,只需要一句话:(PHP实现)

include(¨/mountpoint/database/table/field¨);

或者,换一种方式表达:

include(¨/mnt/mysql/sitedata/topic/todaytopic¨);


这样就很容易理解,也占用了较少的空间。还可以通过SAMBA 来共享 /mnt/mysql,达到
直接修改SQL 数据库
的目的。能直接写文本到数据库,或者使用拷贝/粘贴功能把图片放入数据库,这要比用
Perl 或者PHP 写几百行程序省力多了。


三、性能如何?

在发表这篇文章的时候,这个文件系统还处于原型开发阶段,因此,速度还不是很理想。
如果到了正式发布的时候,一些数据库功能会比使用 SQL 要快。 当然,很多还是没法和
SQL 相比,无论是性能上还是功能上,很多复杂的查询依然需要通过SQL 语句来完成。但
是,这样节省了很多开发和培训的时间,所以在效率上来说也是一种节省。

四、支持的表类型:
目前这个文件系统支持所有的表类型:MyISAM,DBD,HEAP,ISAM。

五、其他的特色:

在第一步开发中实现的还只是只读,很快会有能读写的版本出来。目前的计划是把数据库
对象映射成文件和目录对象。让我们来看看例子:


--8<-----------------------------
#建立表

CREATE TABLE invoice (
invoice_id int(10) unsigned NOT NULL auto_increment,
invoice_no int(10) unsigned DEFAULT '0' NOT NULL,
payee char(40) DEFAULT '' NOT NULL,
PRIMARY KEY (invoice_id),
KEY payee (payee)
);

# 插入数据

INSERT INTO invoice VALUES (1,100,'Company AB');
INSERT INTO invoice VALUES (2,101,'Company CD');
INSERT INTO invoice VALUES (3,102,'Company EF');

--8<-----------------------------

因为 MySQL 没有办法使用记录号,所以我们必须建立主键。
就有了以下的目录结构:

/mountpoint/database/table/primary_key/field

这样,每个列出现在不同的文件行之中,文件树的结构如下:

/mnt/mysql/mydata/invoice/1/invoice_id
/mnt/mysql/mydata/invoice/1/invoice_no
/mnt/mysql/mydata/invoice/1/payee
/mnt/mysql/mydata/invoice/2/invoice_id
/mnt/mysql/mydata/invoice/2/invoice_no
/mnt/mysql/mydata/invoice/2/payee
/mnt/mysql/mydata/invoice/3/invoice_id
/mnt/mysql/mydata/invoice/3/invoice_no
/mnt/mysql/mydata/invoice/3/payee

另外,还有第二个办法可以使用:

/mountpoint/database/table/.table

/mountpoint/database/table/primary_key/.record
/mnt/mysql/mydata/invoice/.table
/mnt/mysql/mydata/invoice/1/.record
/mnt/mysql/mydata/invoice/1/invoice_id
/mnt/mysql/mydata/invoice/1/invoice_no
/mnt/mysql/mydata/invoice/1/payee
/mnt/mysql/mydata/invoice/2/.record
/mnt/mysql/mydata/invoice/2/invoice_id
/mnt/mysql/mydata/invoice/2/invoice_no
/mnt/mysql/mydata/invoice/2/payee
/mnt/mysql/mydata/invoice/3/.record
/mnt/mysql/mydata/invoice/3/invoice_id
/mnt/mysql/mydata/invoice/3/invoice_no
/mnt/mysql/mydata/invoice/3/payee


这些文件是隐含的,以防重复,主要用来方便地通过文本文件浏览器来查看。

现在,在那些需要使用SQL 语句搜索最小,最大,最后等数据,可以通过符号连接来实
现了:

/mountpoint/database/table/primary_key/.max
或者
/mnt/mysql/mydata/invoice/invoice_id/.max
或者指向
/mountpoint/database/table/field

/mnt/mysql/mydata/invoice/3

同样的就可以返回一行的 min/max/sum/avg 等数值。
这能很快并且很容易地实现。

/mnt/mysql/mydata/.keys/
/mnt/mysql/mydata/.keys/invoice_id/
/mnt/mysql/mydata/.keys/payee/

符号连接到主键:
/mnt/mysql/mydata/.keys/.primary_key/  
实际上指向
/mnt/mysql/mydata/.keys/invoice_id/

还有一些隐藏文件提供键类型:
/mnt/mysql/mydata/.keys/invoice_id/.type
/mnt/mysql/mydata/.keys/payee/.type

第一个文内容为:¨PRIMARY KEY¨ 第二个为 ¨KEY¨ 。

另外还可以用索引来排序记录,如果读取下面的目录:

/mnt/mysql/mydata/.keys/payee/asc/

PHP 的readdir() 函数就以升序返回数据的符号连接。

另外还有一些全局函数:

/mountpoint/.version
/mountpoint/.last_insert_id
/mountpoint/.uptime
/mountpoint/database/.raid (0/1)
/mountpoint/database/.type (ISAM/MyISAM/HEAP/DBD)
/mountpoint/database/.tables
/mountpoint/database/table/.created
/mountpoint/database/table/.last_updated
/mountpoint/database/table/.last_checked
/mountpoint/database/table/.count


六、写权限?

在开发的第二阶段,会有措施执行SQL 语句。现在的思路是:

采用目录:
/mountpoint/database/.command/

然后执行命令,把SQL 语句作为目录建立。
或者建立目录把SQL 语句作为文件放入这个目录。

两个方案都有优点,第一个方案可以重新使用SQL 语句,但是这样的目录名实在不敢令
人苟同。第二个方案采用信号量文件,语句执行完毕就删除这个文件,没有任务使用时,
目录也被删除。对于那些慢速的查询响应,可以选择timeout 的时间。

七、权限管理
在权限管理方面,可以使用Unix 的权限管理方式,这样的方案看来是最好的。