预览模式: 普通 | 列表

Mysql数据库正规化和设计技巧(2)

第二级正规化形式

  1.为应用在多条记录的字段建立独立的表格

  2.通过一个foreign key来关联这些表格的值

  我们将url的值放在一个独立的表格中,这样我们就可以在以后加入更多的数据,而无需担心产生重复的值。我们还通过主键值来关联这些字段:

  users

  userId name company company_address

  1 Joe ABC 1 Work Lane

  2 Jill XYZ 1 Job Street

  urls

  urlId relUserId url

  1 1 abc.com

  2 1 xyz.com

  3 2 abc.com

  4 2 xyz.com

  如上所示,我们创建了独立的表格,users表中的主键userid现在与url表中的foreign key relUserId关联。现在的情况好象已经得到了明显的改善。不过,如果我们要为ABC公司加入一个员工记录呢?或者更多,200个?这样我们就必须重复使用公司名和地址,这明显不够冗余。因此我们将应用第三级正规化方法:

  第三级正规化形式

  1.消除不依赖于该键的字段

  公司名及地址与User Id都是没有关系的,因此它们应用拥有自己的公司Id:

  users

  userId name relCompId

  1 Joe 1

  2 Jill 2

  companies

  compId company company_address

  1 ABC 1 Work Lane

  2 XYZ 1 Job Street

  urls

  urlId relUserId url

  1 1 abc.com

  2 1 xyz.com

  3 2 abc.com

  4 2 xyz.com

  这样我们就将companies表中的主键comId和users表中名字为relCompId的foreign key关联起来,就算为ABC公司加入200个员工,在companies中也只有一条记录。我们的users和urls表可以不断地扩大,而无需担心插入不必要的数据。大部分的开发者都认为经过三步的正规化就足够了,这个数据库的设计已经可以很方便地处理整个企业的负担,此看法在大多数的情况下是正确的。

  我们可以留意一下url的字段--你注意到数据的冗余了吗?如果给用户用户输入这些url数据的HTML页面是一个文本框,可任意输入的话,这并没有问题,两个用户输入同样收藏夹的概率较少,不过,如果是通过一个下拉式的菜单,只让用户选择两个url输入,或者更多一点。这种情况下,我们的数据库还可以进行下一级别的优化--第四步,对于大多数的开发者来说,这一步都是忽略的,因为它要依赖一个很特别的关系--一个多对多的关系,这在我们的应用中是还没有遇到过的。

Mysql数据库正规化和设计技巧(1)

在动态网站的设计中,数据库设计的重要性不言而喻。如果设计不当,查询起来就非常吃力,程序的性能也会受到影响。无论你使用的是mySQL或者Oracle数据库,通过进行正规化的表格设计,可以令你的PHP代码更具可读性,更容易扩展,从而也会提升应用的性能。

  简单说来,正规化就是在表格设计时,消除冗余性和不协调的从属关系。在本文中,我将通过五个渐进的过程来告诉你在设计中应该了解的正规化技巧。从而建立一个可行而且
效率高的数据库。本文也会详细分析一下可以利用的关系类型。

  这里假定我们要建立一个用户信息的表格,其中要存储用户的名字、公司、公司地址和一些个人的收藏夹或url。在开始时,你可能定义一个如下的表格结构:

  零状态形式

  users

  name company company_address url1 url2

  Joe ABC 1 Work Lane abc.com xyz.com

  Jill XYZ 1 Job Street abc.com xyz.com

  由于没有进行任何的正规化处理,我们将这种形式的表称为零状态形式的表。留意其中的url1和url2字段---如果我们在应用中需要第三个url呢?这样你就要在表格中多加一列,很明显,这不是一个好办法。如果你要创建一个富有扩展性的系统,你就要考虑使用第一个正规化的形式,并且应用到该表格中。

  第一级正规化形式

  1.消除每个表格中重复的组

  2.为每套相关的数据建立一个独立的表格

  3.使用一个主键来标识每套相关的数据

  以上的表格明显违反了上面第一条的规定,那么第三条的主键又是什么意思呢?很简单,它只是在每个记录中加入一个唯一的、自动增加的整型值。通过这个值,就可以将两个姓名一样的记录区分开来。通过应用第一级正规化形式,我们得到了以下的表格:

  users

  userId name company company_address url

  1 Joe ABC 1 Work Lane abc.com

  1 Joe ABC 1 Work Lane xyz.com

  2 Jill XYZ 1 Job Street abc.com

  2 Jill XYZ 1 Job Street xyz.com

  现在我们的表格可以说已经处在第一级正规化的形式了,它已经解决了url字段的限制问题,不过这样的处理后又带来了一个新的问题。每次在user表中插入一条记录的时候,我们都必须重复所有的公司和用户数据。这样不仅令数据库比以前大了,而且很容易出错。因此还要经过第二级正规化处理

使用apache模块.将soft.php?id=123变为/soft/123.html

使用apache模块.将soft.php?id=123变为/soft/123.html

http://wwww.aaaaaaaaa.com/bbb.asp?id=888
的地址形式改为
http://wwww.aaaaaaaaa.com/888.htm
或者
http://wwww.aaaaaaaaa.com/yourname/888.htm
当然可以按照你的要求随便变.
APACHE的 MOD_rewrite模块.
大家可以看一个演示的一个 PHP学习论坛
http://www.phpx.com/happy/
这个论坛的版面和帖子,就是运用了这个技术,地址静态化.但是是假的.
这个技术哪里好?
可以让baidu, google等收入你的站点所有页面.
收入地址就是你的假静态地址.当然别人看不出你是假的.而且这个技术隐藏了你背后执行的程序.
你可以把
/soft/1234.html 重写传递给 soft.php?id=1234
当然你改一下名 换成 softxfewafew.php?id=1234
表面还是 soft/1234.html但是你 APACHE内部执行了你重写的文件.
从根本上可以防止别人从程序本身入侵.

下面我写怎么样重写.分为 WINDOWS和LIUNX2种
都是操作
APACHE安装文件夹内的 CONF文件夹里面的httpd.conf
打开以后,找到
#LoadModule rewrite_module "modules/mod_rewrite.so"
把#去掉.
然后找到虚拟主机配置
在虚拟主机中加入
RewriteEngine On
RewriteRule ^/soft/([0-9]+).html$ /soft.php?id=$1
//解释
//WWW.玉米.COM/SOFT/1234.HTML
//重写为
//WWW.玉米.COM/soft.php?id=1234
//这里ID是可以变的 你给它 1 就是传递1
RewriteRule ^/([0-9]+).html$ /soft.php?id=$1
//解释
//WWW.玉米.COM/1234.HTML
//重写为
//WWW.玉米.COM/soft.php?id=1234
RewriteRule ^/([0-9]+)_([0-9]+).html$ /soft.php?id=$1&catid=$2
//解释
//WWW.玉米.COM/1234_2222.HTML
//重写为
//WWW.玉米.COM/soft.php?id=1234&catid=2222
当然随便你怎么换!
这就是 WIN下的.
LIUNX下是一样的 但是要加
开始
结束
重写都加在虚拟主机设置中.
如果没有虚拟主机,那加在最后!
说的应该算详细清楚了.
(摘自:www.meyu.net)

MySQL数据库安全配置

1、前言

MySQL 是完全网络化的跨平台关系型数据库系统,同时是具有客户机/服务器体系结构的分布式数据库管理系统。它具有功能强、使用简便、管理方便、运行速度快、安全可靠性强等优点,用户可利用许多语言编写访问MySQL 数据库的程序,特别是与PHP更是黄金组合,运用十分广泛。

由于MySQL是多平台的数据库,它的默认配置要考虑各种情况下都能适用,所以在我们自己的使用环境下应该进行进一步的安全加固。作为一个MySQL的系统管理员,我们有责任维护MySQL数据库系统的数据安全性和完整性。

MySQL数据库的安全配置必须从两个方面入手,系统内部安全和外部网络安全,另外我们还将简单介绍编程时要注意的一些问题以及一些小窍门。

2、系统内部安全

首先简单介绍一下MySQL数据库目录结构。MySQL安装好,运行了mysql_db_install脚本以后就会建立数据目录和初始化数据库。如果我们用MySQL源码包安装,而且安装目录是/usr/local/mysql,那么数据目录一般会是/usr/local/mysql/var。数据库系统由一系列数据库组成,每个数据库包含一系列数据库表。MySQL是用数据库名在数据目录建立建立一个数据库目录,各数据库表分别以数据库表名作为文件名,扩展名分别为MYD、MYI、frm的三个文件放到数据库目录中。

MySQL的授权表给数据库的访问提供了灵活的权限控制,但是如果本地用户拥有对库文件的读权限的话,攻击者只需把数据库目录打包拷走,然后拷到自己本机的数据目录下就能访问窃取的数据库。所以MySQL所在的主机的安全性是最首要的问题,如果主机不安全,被攻击者控制,那么MySQL的安全性也无从谈起。其次就是数据目录和数据文件的安全性,也就是权限设置问题。

从MySQL 主站一些老的binary发行版来看,3.21.xx版本中数据目录的属性是775,这样非常危险,任何本地用户都可以读数据目录,所以数据库文件很不安全。3.22.xx版本中数据目录的属性是770,这种属性也有些危险,本地的同组用户既能读也能写,所以数据文件也不安全。3.23.xx版本数据目录的属性是700,这样就比较好,只有启动数据库的用户可以读写数据库文件,保证了本地数据文件的安全。

如果启动MySQL数据库的用户是mysql,那么象如下的目录和文件的是安全的,请注意数据目录及下面的属性:

shell>ls -l /usr/local/mysql
total 40
drwxrwxr-x 2 root root 4096 Feb 27 20:07 bin
drwxrwxr-x 3 root root 4096 Feb 27 20:07 include
drwxrwxr-x 2 root root 4096 Feb 27 20:07 info
drwxrwxr-x 3 root root 4096 Feb 27 20:07 lib
drwxrwxr-x 2 root root 4096 Feb 27 20:07 libexec
drwxrwxr-x 3 root root 4096 Feb 27 20:07 man
drwxrwxr-x 6 root root 4096 Feb 27 20:07 mysql-test
drwxrwxr-x 3 root root 4096 Feb 27 20:07 share
drwxrwxr-x 7 root root 4096 Feb 27 20:07 sql-bench
drwx------ 4 mysql mysql 4096 Feb 27 20:07 var
shell>ls -l /usr/local/mysql/var
total 8
drwx------ 2 mysql mysql 4096 Feb 27 20:08 mysql
drwx------ 2 mysql mysql 4096 Feb 27 20:08 test
shell>ls -l /usr/local/mysql/var/mysql
total 104
-rw------- 1 mysql mysql 0 Feb 27 20:08 columns_priv.MYD
-rw------- 1 mysql mysql 1024 Feb 27 20:08 columns_priv.MYI
-rw------- 1 mysql mysql 8778 Feb 27 20:08 columns_priv.frm
-rw------- 1 mysql mysql 302 Feb 27 20:08 db.MYD
-rw------- 1 mysql mysql 3072 Feb 27 20:08 db.MYI
-rw------- 1 mysql mysql 8982 Feb 27 20:08 db.frm
-rw------- 1 mysql mysql 0 Feb 27 20:08 func.MYD
-rw------- 1 mysql mysql 1024 Feb 27 20:08 func.MYI
-rw------- 1 mysql mysql 8641 Feb 27 20:08 func.frm
-rw------- 1 mysql mysql 0 Feb 27 20:08 host.MYD
-rw------- 1 mysql mysql 1024 Feb 27 20:08 host.MYI
-rw------- 1 mysql mysql 8958 Feb 27 20:08 host.frm
-rw------- 1 mysql mysql 0 Feb 27 20:08 tables_priv.MYD
-rw------- 1 mysql mysql 1024 Feb 27 20:08 tables_priv.MYI
-rw------- 1 mysql mysql 8877 Feb 27 20:08 tables_priv.frm
-rw------- 1 mysql mysql 428 Feb 27 20:08 user.MYD
-rw------- 1 mysql mysql 2048 Feb 27 20:08 user.MYI
-rw------- 1 mysql mysql 9148 Feb 27 20:08 user.frm

如果这些文件的属主及属性不是这样,请用以下两个命令修正之:

shell>chown -R mysql.mysql /usr/local/mysql/var
shell>chmod -R go-rwx /usr/local/mysql/var

用root 用户启动远程服务一直是安全大忌,因为如果服务程序出现问题,远程攻击者极有可能获得主机的完全控制权。MySQL从3.23.15版本开始时作了小小的改动,默认安装后服务要用mysql用户来启动,不允许root用户启动。如果非要用root用户来启动,必须加上--user=root的参数 (./safe_mysqld --user=root &)。因为MySQL中有LOAD DATA INFILE和SELECT ... INTO OUTFILE的SQL语句,如果是root用户启动了MySQL服务器,那么,数据库用户就拥有了root用户的写权限。不过MySQL还是做了一些限制的,比如LOAD DATA INFILE只能读全局可读的文件,SELECT ... INTO OUTFILE不能覆盖已经存在的文件。

本地的日志文件也不能忽视,包括shell的日志和MySQL自己的日志。有些用户在本地登陆或备份数据库的时候为了图方便,有时会在命令行参数里直接带了数据库的密码,如:

shell>/usr/local/mysql/bin/mysqldump -uroot -ptest test>test.sql
shell>/usr/local/mysql/bin/mysql -uroot -ptest

这些命令会被shell记录在历史文件里,比如bash会写入用户目录的.bash_history文件,如果这些文件不慎被读,那么数据库的密码就会泄漏。用户登陆数据库后执行的SQL命令也会被MySQL记录在用户目录的.mysql_history文件里。如果数据库用户用SQL语句修改了数据库密码,也会因.mysql_history文件而泄漏。所以我们在shell登陆及备份的时候不要在-p后直接加密码,而是在提示后再输入数据库密码。
另外这两个文件我们也应该不让它记录我们的操作,以防万一。

shell>rm .bash_history .mysql_history
shell>ln -s /dev/null .bash_history
shell>ln -s /dev/null .mysql_history

上门这两条命令把这两个文件链接到/dev/null,那么我们的操作就不会被记录到这两个文件里了。

3、外部网络安全

MySQL数据库安装好以后,Unix平台的user表是这样的:

mysql> use mysql;
Database changed
mysql> select Host,User,Password,Select_priv,Grant_priv from user;
+-----------+------+----------+-------------+------------+
| Host | User | Password | Select_priv | Grant_priv |
+-----------+------+----------+-------------+------------+
| localhost | root | | Y | Y |
| redhat | root | | Y | Y |
| localhost | | | N | N |
| redhat | | | N | N |
+-----------+------+----------+-------------+------------+
4 rows in set (0.00 sec)

Windows平台的user表是这样的:
mysql> use mysql;
Database changed
mysql> select Host,User,Password,Select_priv,Grant_priv from user;
+----

gb2312转utf-8

<?
// Program by Donald,Milddragon Studio.
// Email: wilddragon#sina.com
// gb2312.txt请用google搜索下载

//初始化gb2312--unicode数组对应表作为全程变量,以提高处理速度
$____global_codetable=array();
$____global_filename=pathinfo($_SERVER["SCRIPT_FILENAME"]);
$____global_filename=$____global_filename["dirname"]."/gb2312.txt";
$____global_tmp=file($____global_filename);
while(list($key,$value)=each($____global_tmp))
{
if (strcmp($value{0},'#')!=0)
$____global_codetable[hexdec(substr($value,2,4))]=substr($value,9,4);
}
reset($____global_tmp);
while(list($key,$value)=each($____global_tmp))
{
if (strcmp($value{0},'#')!=0)
$____global_codetable2[hexdec(substr($value,9,4))]=hexdec(substr($value,2,4));
}
unset($____global_filename);
unset($____global_tmp);


/*
将带 㾏協格式的文本(可以包含其它ASCII字符)转换成gb2312格式的文本;
可以用于XML编码的转换
需要注意的是,函数不改变xml中关于编码的声明
*/
function unicode2gb($un)
{
if(!trim($un))
return $un;
$gb="";
global $____global_codetable2;
while(strlen($un)>0)
{
$p=strpos($un,"&#");
if ($p===FALSE)//串中已无unicode字符
{
  $gb.=$un;
  return $gb;
}
else
{
  if ($p!=0)//串中unicode字符前缀不是第一个字符
  {
  $gb.=substr($un,0,$p);
  $un=substr($un,$p);
  }
  $p=strpos($un,";");
  if ($p===FALSE)//此前缀非unicode前缀,串中已无unicode字符
  {
      $gb.=$un;
      return $gb;
  }
  else
  {
  $code=substr($un,2,$p-2);
  $un=substr($un,$p+1);
  if (strcasecmp($code{0},"x")==0)//unicode码16进制表示
  {
  $code=hexdec(substr($code,1));
  }else
  {
  $code=intval($code);
  }
      $code=0x8080|$____global_codetable2[$code];
  $gb.=chr((($code & 0xFF00)>>8) & 0xFF);
  $gb.=chr($code & 0xFF);
  }
}
}
return $gb;
}
/*
将 gb2312格式的文本(可以包含其它ASCII字符)转化为 带 㾏協格式的unicode文本;
可以用于XML编码的转换
需要注意的是,函数不改变xml中关于编码的声明
*/
function gb2unicode($gb)
{
  if(!trim($gb))
    return $gb;
  $utf="";
  global $____global_codetable;
  while(strlen($gb)>0)
  {
  if (ord(substr($gb,0,1))>127)
    {
      $this=substr($gb,0,2);
      $gb=substr($gb,2);
      $code=$____global_codetable[hexdec(bin2hex($this))&0x7F7F];
      $utf.="".$code.";";
    }
  else
    {
      $utf.=substr($gb,0,1);
      $gb=substr($gb,1);
    }
  }
  return $utf;
}

/*
将utf8格式的文本转化为gb2312格式的文本;这与上述的unicode2gb不同,是二进制格式的转换
*/
function utf82gb($utf8)
{
  if(!trim($utf8))
    return $utf8;
  global $____global_codetable2;
  $gb="";
  while(strlen($utf8)>0)
  {
$c=substr($utf8,0,1);
$d=ord($c);
if (($d&0x80) == 0)//1位
{
$gb.=$c;
$utf8=substr($utf8,1);
}
else
if (($d&0xC0)==0x80)//错位
{
$utf8=substr($utf8,1);
}
else
if (($d&0xE0)==0xC0)//2位
{
$utf8=substr($utf8,2);
}
else
if (($d&0xF0)==0xE0)//3位
{
$d1=ord($utf8{1}) & 0x3F;
$d2=ord($utf8{2}) & 0x3F;
$d=$d & 0x0F;
$d=($d<<12) + ($d1 <<6) + $d2;
      $code=0x8080|$____global_codetable2[$d];
$gb.=chr((($code & 0xFF00)>>8) & 0xFF);
$gb.=chr($code & 0xFF);
$utf8=substr($utf8,3);
}
else
if (($d&0xF8)==0xF0)//4位
{
$d1=ord($utf8{1}) & 0x3F;
$d2=ord($utf8{2}) & 0x3F;
$d3=ord($utf8{3}) & 0x3F;
$d=$d & 0x07;
$d=($d<<18) + ($d1 <<12) + ($d2 << 6) +$d3;
//$code=0x8080+getgb($d);
      $code=0x8080|$____global_codetable2[$d];
$gb.=chr((($code & 0xFF00)>>8) & 0xFF);
$gb.=chr($code & 0xFF);
$utf8=substr($utf8,4);
}
else
{
$utf8=substr($utf8,1);
}
  }
  return $gb;
}
/*
将gb2312格式的文本转化为utf8格式的文本;这与上述的gb2unicode不同,是二进制格式的转换
*/
function gb2utf8($gb)
{
  if(!trim($gb))
    return $gb;
  global $____global_codetable;
  $utf8="";
  while(strlen($gb)>0)
  {
if (ord(substr($gb,0,1))>127)
{
      $code=substr($gb,0,2);
      $gb=substr($gb,2);
      //echo "gb=$code;";
      $code=bin2hex($code);
      //echo "code=$code;";
      $code=hexdec($code)&0x7F7F;
      //echo "newcode=".dechex($code);
      $code=$____global_codetable[$code];
      //echo "unicode=$code";
      $code=hexdec($code);
      //11位:6+5
      if (($code&0x7FF)==$code)
      {
      $utf8.=chr(0xC0|((($code&0x7C0)>>6)&0x3F));
      $utf8.=chr(0x80|($code&0x3F));
      }else
      //16位:12+4
      if (($code&0xFFFF)==$code)
      {
      $utf8.=chr(0xE0|((($code&0xF000)>>12)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0)>>6)&0x3F));
      $utf8.=chr(0x80|($code&0x3F));
      //echo "16位==$utf8; ";
      }
      else
      //21位:18+3
      if (($code&0x1FFFFF)==$code)
      {
      $utf8.=chr(0xF0|((($code&0x1C0000)>>18)&0x3F));
      $utf8.=chr(0x80|((($code&0x3F000)>>12)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0)>>6)&0x3F));
      $utf8.=chr(0x80|($code&0x3F));
      }
      /*
      else
      //26位:24+2
      if (($code&0x3FFFFFF)==$code)
      {
      $utf8.=chr(0xF8|((($code&0x3000000)>>24)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0000)>>18)&0x3F));
      $utf8.=chr(0x80|((($code&0x3F000)>>12)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0)>>6)&0x3F));
      $utf8.=chr(0x80|($code&0x3F));
      }
      else
      //31位:30+1
      if (($code&0x7FFFFFFF)==$code)
      {
      $utf8.=chr(0xFC|((($code&0x40000000)>>30)&0x3F));
      $utf8.=chr(0x80|((($code&0x3F000000)>>24)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0000)>>18)&0x3F));
      $utf8.=chr(0x80|((($code&0x3F000)>>12)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0)>>6)&0x3F));
      $utf8.=chr(0x80|($code&0x3F));
      }
      //36位
      else
      {
      //首字节全部作为前缀,无数据
      $utf8.=chr(0x80|((($code&0xC0000000)>>30)&0x3F));
      $utf8.=chr(0x80|((($code&0x3F000000)>>24)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0000)>>18)&0x3F));
      $utf8.=chr(0x80|((($code&0x3F000)>>12)&0x3F));
      $utf8.=chr(0x80|((($code&0xFC0)>>6)&0x3F));
      $utf8.=chr(0x80|($code&0x3F));
      }
      */
}
else
{
$utf8.=substr($gb,0,1);
$gb=substr($gb,1);
}
}
return $utf8;
}
?>

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状态进入目录mysqlin,然后键入以下命令:
mysql -uroot -p密码 < c:school.sql
如果成功,空出一行无任何显示;如有错误,会有提示。(以上命令已经调试,你只要将//的注释去掉即可使用)。
四、将文本数据转到数据库中
1、文本数据应符合的格式:字段数据之间用tab键隔开,null值用 来代替.
例:
3 rose 深圳二中 1976-10-10
4 mike 深圳一中 1975-12-23
2、数据传入命令 load data local infile "文件名" into table 表名;
注意:你最好将文件复制到mysqlin目录下,并且要先用use命令打表所在的库。
五、备份数据库:(命令在DOS的mysqlin目录下执行)
mysqldump --opt school>school.bbb
注释:将数据库school备份到school.bbb文件,school.bbb是一个文本文件,文件名任取,打开看看你会有新发现。
后记:其实MYSQL的对数据库的操作与其它的SQL类数据库大同小异,您最好找本将SQL的书看看。我在这里只介绍一些基本的,其实我也就只懂这些了,呵呵。最好的MYSQL教程还是“晏子“译的“MYSQL中文参考手册“不仅免费每个相关网站都有下载,而且它是最权威的。可惜不是象 "PHP4中文手册"那样是chm的格式,在查找函数命令的时候不太方便

让你的网站首页自动选择语言转跳

我见到很多网站在首页上做一些链接,让用户来选择将要访问的各自的语言页面,让中国人选择“中文”,韩国人选择“朝鲜语”,等等。那么能不能做程序来自动帮助选择呢?
答案是肯定的,大家都在用google,你用中文系统打开google的首页,打开的自然是中文首页,而不会是其他语言。因为google会自动判断用户系统使用的首选语言是什么。
怎样才能做到像google那样呢,其实很简单,
在浏览器发给web服务器的 HTTP Headers Information 中包含了这样一个信息 Accept-Language
这个信息就是,浏览器中 工具->Internet选项->常规 下的 语言, 它就是用来设置浏览器可接受的语言首选项的, 它可以是多种可接受语言的优先排序列。

下面以PHP为例,
用户可接受的语言信息,放在$_SERVER['HTTP_ACCEPT_LANGUAGE']里,
变量信息是类似这样的 "zh-cn", 如果是多语言列,是类似 "zh-cn,en;q=0.8,ko;q=0.5,zh-tw;q=0.3"
下面的问题可以迎刃而解了。
<?php
error_reporting(E_ALL ^ E_NOTICE);

// 分析 HTTP_ACCEPT_LANGUAGE 的属性
// 这里只取第一语言设置 (其他可根据需要增强功能,这里只做简单的方法演示)

preg_match('/^([a-z-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
$lang = $matches[1];

switch ($lang) {
        case 'zh-cn' :
                header('Location: http://cn.example.com/');
                break;
        case 'zh-tw' :
                header('Location: http://tw.example.com/');
                break;
        case 'ko' :
                header('Location: http://ko.example.com/');
                break;
        default:
                header('Location: http://en.example.com/');
                break;
}

?>

PHP程序员一般都忽略了的几点精华

我发现很多的PHP程序员,尤其是学习还不是很久的,都不知道PHP的精华所在。Perl当年如何在商界出名?其强大的正则表达式。而PHP呢?他是一门从Unix下发展起来的语言,当然也就继承了Perl的很多特点,同时C的优点都有。快速、简洁、明了,尤其是C程序员,PHP是至爱,我就是深爱着 “PHP”(都忘了女友了:))。这里,我想来写一篇PHP的变量、数组应用技巧和PHP的正则表达式、PHP的模板应用,以后有时间再写PHP与 COM、PHP与XML的完全结合。

1、变量、数组的应用技巧
(1)很多人用得不多的数组函数。foreach、list、each。分别举几个例子,应该就能知道了。例:
<?php
$data = array('a' => 'data1', 'b' => 'data2', 'c' => 'data3');
while(list($subscript, $value) = each($data))
{
echo "$subscript => $value :: ";
echo "$subscript => $value<br>";
}

reset($data);
foreach($data as $subscript => $value)
{
echo "$subscript => $value :: ";
echo "$subscript => $value<br>";
}
(2)函数的变量、变量的变量、变量的“指针”:看下例:
<?php
//变量的变量
$var = "this is a var";
$varname = "var";
echo $$varname;
//函数的变量
function fun1($str) {
echo $str;
}
$funname = "fun1";
$funname("This is a function !");
?>
变量的“指针”。这个指针加上了双引号,表明他不是真正的指针。看看下例:
<?php
function($a) {
$a ++;
}
$c = 0;
function($c);
echo $c; //$c仍为0
function(&$a) {
$a ++;
}
$c = 0;
echo $c; //$c为1
?>

之所以称其为“指针”,就是因为他有了和C语言中指针相同的功能。但这又不是真正的指针,只能够是这样的去理解。

2、正则表达式
正则表达式是一个非常大的题目,Perl的正则表达式的强大是闻了名的。而PHP也不弱,他继承了Perl的正则表达式法则,还有自己的一套法则。这里只说PHP自己的正则表达式。
正则表达式是最基本的元素。简单地说就是一套规则,用于去判定其它的元素是不是符合自身的规则,或者说是不是有相同的特征描述。
正则表达式的开始符:^,结尾符$,这两个符号间的是匹配的元素。如检查一个电话号码是不是打往北京的号,用正则表达式表示就是“^010$”。只要前3位区号是010,就是北京的号,后面的电话号码就不用管了。然后,用正则表达式匹配函数ereg来判断,例:
<?php
$pattern = "^010$";
$phone = "01080718828";
if(ereg($pattern, $phone))
echo "打往北京的号";
else
echo "不是打往北京的号";
?>

这就是正则表达式。北京的电话都是8位数字的,那我要知道这个号码是不是正确了?假如他按了9位号呢?如果判断正误?这就要用到正则表达式的字符簇。那么上例的正则表达式就要这样写:^010[0-9]{8}$,就能同时判断号码是不是符合规则。正则表达式有很多的应用,像LBB、VBB论坛在发贴时的所谓 VBB代码LBB代码的解析,都是用正则表达式完成的。

3、模板
知道了正则表达式的功能,那么就可以知道模板了。什么是模板?举个例子吧?一般写网页用到了后台程序的时候,都是在网页里面插入程序代码。如PHP。这就是HTML和PHP的混写。这样的优点是读取速度快,缺点是如果大家分工合作做网站,那么非程序员就不会改网了。
而用模板,则可以达到分工的最合理化。美工只做页面,程序只写后台,然后再合起来。优秀的Jsp提供了自定义标签的功能很好地完成了模板功能。而主流的 PHP如何做到呢?就是利用正则表达式来做到的。可以去网上下载一个PHPLIB,里面的PHP目录下有一个template.inc的源代码文件,那就是用PHP实现模板套用的类。

由于篇幅有限,这里只是简单地说一说这些内容,如果真的想学的话,还请看专门的教材。如光要讲清楚正则表达式就可以写上一本小书。
本站立志于收集各类技术文档资料,便于本人和广大网友查询检索,任何转载文章均尽力标明来源,无论单位或个人认为本站存在侵权内容均可与本站联系,任何此类反馈信息一经有效身份证明、权属证明及详细侵权情况证明后,将立即清除!对于转载内容,本站不为其版权负责,其任何言论均与本站无关!