PHP操作MYSQL数据库初步

时间:2022-12-11 10:17:14

一.SQL语言基础

1) 关于database的库操作

1.show databases; 可以用来显示所有库名,如果要显示特定的库,可以使用show databases like ' ……' ; 引号中使用通配符来进行对内容的删选,通配符起代替其他字符作用,相当于省略号,常用的通配符有 % 和  _  两种,其中%可以代替一个或多个字符,包括空字符,而 _ 只能代替一个字符且不能是空字符。例如对于名字为 test 的库,可以用' %t '     ,  ' t% '  ,   ' %test%  '    ,   '_est '   ,   '  t_s_ ' 这些通配符查找到,但是'_test_'是不可以的,因为_不能代替空字符,另外值得注意的是库名是大小写敏感的。

2. show create database 数据库名 ; 可以用来看某个库的创建信息,包括所用的字符集等等。
3. create database 数据库名;  可以用来创建数据库,库名由英文数字下划线组成,不需要写在引号里。如果这个库已经存在,这样写就会报错,这时可以使用create database if not exists 库名 ;  来写,这样即时库存在也不会报错,只会报一个警告。另外尽量不要用保留字作为库名,一定要用库名时需要用反引号包裹起来,如create database `match`;  。 如果要制定库的字符集,可以用create database 库名 default charset = 字符集名 ;来写,字符集名为utf8或gbk,如果不指定字符集,则默认字符集为服务器的字符集,即为安装mysql时选择的那个字符集。
4.alter database 库名 选项 ; 来修改数据库,库的选项只有字符集和配对方式,它们保存在数据库文件中的db.opt 文件中,一般只改字符集,系统自动进行配对,如create database 库名 default charset = gbk ;  即可修改库的字符集。
5.drop database if exists 库名 ; 用来删除数据库,没有这个库会报警告,如果不加 if exists且没有这个库的话就会报错。删除要慎重,一旦删除的话库的所有信息全部销毁。
2) 关于table的表操作
1.要创建表,先要 use 库名 ; 来选定某个数据库,然后用create table 表名 (  字段定义  ) ;来创建表,如create table st_info (st_id int ,  st_name varchar(20) ); 即可创建一个表。
2.查看表名,同样先要选定是哪个库,使用 show tables; 查看所有表,也可以用show table like '……' ;使用通配符查看特定表,和库的查看是相同的,同样也可以 show create table 表名 ;  查看表的创建信息,或者在最后加  \G 逐行显示,不加分号。
3.desc 表名;  或者  describe 表名;或者  show columns from 库名 . 表名;    来查看表结构,包括字段类型,主key等等。
4. 关于对字段的修改:  alter table 表名 modify 更改字段属性;  来实现对字段的属性进行修改,如 alter table st_info modify st_name varchar(40); 或使用chang来修改字段名,alter table 表名 change 旧字段名 新字段名  字段属性;来达到改字段名的目的;还可以通过 alter table 表名 add 新字段名 char(1) after 某个字段;  来添加一个新字段;或者通过alter table 表名 drop 字段名; 来删除某个字段。
5.复制表结构: create table 新表名 like 被复制的表名;   可以一个表为模版复制出一个新的表,只有表结构是相同的,新表里是没有内容,如果想要新表中内容也相同,可以用 create table 新表名 select * from  被复制的表名;  即可连同数据一同复制到新表中。
6.更改表名:rename table 旧表名 to 新表名;  也可以使用rename来交换表名:rename table a to t ,b to a, t to b;
7.删除表: drop table if exists 表名;
3) 关于数据的操作
1.插入数据:插入数据有三种方式,第一种是 insert into 表名(字段1, 字段2 ,字段3 ) values (值1.1,值1.2,值1.2) , ( 值2.1 , 值2.2,值2.3) , (值3.1,值3.2,值3.3); 需要注意的是如果字段的类型是字符串的或者日期,一定要加引号,而且数据和字段的位置必须一一对应,如果要一下子添加多组数据,values只需要写一次即可,我们也可以只插入部分字段,其余的则填充默认值(NULL),默认值是有创建表时定义的;第二种方法是 insert into 表名 set 字段1=值1, 字段2=值2, 字段3=值3;  set只有写一次即可,同样要注意引号,也可以只插入部分字段;第三种方法是使用insert into 表名 (字段1,字段2)select 字段3,字段4 from 其他表;表示从其他表中获取一些字段的数据加入表中,其中字段1字段2是新表中的字段名,要求与被复制表的字段类型一致。
2.替换数据:replace into 语法与插入数据的insert into 语法类似,只不过是把insert改成replace而已,同样是三种方式,包括字段列表values值列表,字段set值和用select从其他表中获取数据。但是replace不是单纯的修改也不是单纯的添加数据,它的功能受主键和唯一索引影响,主键和唯一索引字段中数据不可以重复,比如学号字段中不可以出现两个相同的学号,主键在表结构中key字段中的值为PRI(primary),唯一索引的值为UNI(unique),设置主键和唯一索引可以在创建表时就设定好,或者后期另外设定,如下:
create table st_info(st_id int primary key,st_name varchar(20) unique key, area varchar(20)); //建表时直接设置主键和唯一索引

alter table st_info add primary key (st_id);//设置主键

alter table st_info add unique key (st_name);//设置唯一索引

alter table st_info drop primary key; //取消主键

alter table st_info drop index st_name; //取消某个字段的唯一索引

使用了replace into 语句后,如果写如的数据在主键和唯一索引字段中没有和以前的数据重复的,就会直接添加这条数据(普通索引可以重复,也就是说如果表没有主键和唯一索引那么replace 与insert效果相同);如果和主键或唯一索引字段中的某个旧数据重复,就会先删除含有重复数据的旧的数据,然后把添加这条新数据(如果一条数据主键重复,另一条数据唯一索引重复,则删除两条数据,添加一条数据,也就是说replace可能使数据行数减少)

3.查询数据:select 字段1,字段2 from 表名;  可以用来查询某几个字段的所有数据,如果要查询所有字段的所有数据可以用 select * from 表名; 如果要查询部分数据,可以在后面添加where条件,如 select * from st_info where id<5;

4.修改数据:update 表名 set 字段1=新值,字段2=新值 where id=3; where后面是条件,指明要修改哪条数据,如果不写where的话就会把所有数据全部修改。
5.删除数据:delete from 表名 where id=3; where后面同样是条件,必须要写,否则将删除所有数据。还可以使用order by 字段 limit 1来限制,如delete st_info order by st_id limit 1; 表示删除st_id字段的正序排列(从小到大)的第一个数据,delete st_info order desc by st_id limit 2; 表示删除st_id字段的逆序排列(从大到小)的前两个数据。
6.快速删除所有数据:truncate 表名; 其做法是先删除整个表,然后再重建一个相同的表结构的表,不会返回受影响的行数,能让自增长的字段恢复初值;而利用delete不写where也可以实现删除所有数据的功能,但是后者是一条一条删除,速度慢,且不会让自增长的字段恢复初值。

4) 关于字符集的设置

首先用 show variables like 'character_set%'; 查看字符集,其中character_set_client是客户端发送给服务器的编码,character_set_results是服务器返回给客户端的编码,当客户端实际编码与character_set_client不同时,插入数据时会产生乱码;当客户端实际编码与character_set_results不同时,显示数据时会产生乱码。

可以使用set character_set_result  = 编码 ; 或者set character_set_client  = 编码 ;使发送编码和返回编码符合客户端的实际编码,或者用 set names 编码 ; 可以一下改变两个编码。另外表和字段的编码不会影响插入和显示,数据库会根据客户端的编码自动进行转换。

二.PHP访问MySQL初步

1) 连接MySQL服务器

1.resource mysql_connect ('hostname' , ' username' , 'password' ) ;其中三个参数分别为MySQL服务器的主机名或IP,例如本地为 localhost :3306,或者127.0.0.1,其中3306是默认端口号可以省略,后两个参数为登入服务器的用户名和密码。函数的返回值是一个连接标识符,连接不同的主句应设置不同的连接标识符来区分,如果错误返回false。
<?php
$link=mysql_connect('localhost','root','root')or die("连接数据库服务器错误!" .mysql_error());
//mysql_error()用来返回上一个mysql语句产生错误文本信息
if($link){
echo "数据连接成功!";
}
?>

2) 关闭MySQL服务器

mysql_close($link);用来关闭MySQL服务器,通常系统会自动回收,但如果一次返回的结果集较大或网站访问量较多则需要手动释放。

3) mysql_query()函数执行SQL语句
总的语法格式为 mysql_query("SQL语句" , 连接标识符 ) ; 如果SQL语句是select 则返回查询到的结果的资源标识符,然而这个资源标识符是不能直接使用的,要配合 mysql_fetch_array()等语句读才能读出内容,失败返回false;如果SQL语句是insert,delete,update等,则返回true,失败返回false。另外,在" "中的SQL语句结束后不需要加分号。
一般连接数据库后要立即mysql_query("set name gbk" , $link); 统一编码,在修改表前要先选定数据库,可以在mysql_query();中使用use语句,也可以使用mysql_select_db("数据库名" , 连接标识符) ;来选择数据库。

4) mysql_fetch语句从资源标识符中获取信息,实现索引

1.array mysql_fetch_array(资源标识符);可以用来从资源标识符中获取信息,这个资源标识符是通过mysql_query()的返回值得到的,函数的返回值即是所需要数据,以数组的形式呈现,如果这个资源里有多条记录,那么一句$info=mysql_fetch_array();只能读入一条记录,再写一次$info=mysql_fetch_array();才能读入第二条记录,所以这个语句要配合do while使用,例如 do{ print_r( $info );} while ($info = mqsql_fetch_array(资源标记符) ); 也就是说while每循环一次,mysql_fetch_array()就会指向下一条记录,没有记录,返回false,退出循环。

2.object mysql_fetch_object(资源标识符);与my_fetch_array()的用法基本相同,同样一句只能返回一条记录,唯一不同是返回的是一个对象,可以用$info->id这样来调用。
3.array mysql_fetch_row(资源标识符);与mysql_fetch_array()的用法也基本一致,只不过返回的数组的下标不同,是以$row[0] , $row[1] 这样表示的。
4.int mysql_num_rows(资源标识符);可以返回资源结果集中的记录数目。
eg:索引
<?php
$link=mysql_connect("localhost","root","password");
mysql_select_db(database,$link);
mysql_query("use database");
mysql_query("set names gbk");
$result=mysql_query("select * from table");
$info=mysql_fetch_array($result);

if($_POST[Submit]=="查询"){
$txt=$_POST[txt];
$result=mysql_query("select * from table where name like '%" .$txt. "%'");
$info=mysql_fetch_array($result);
$num=mysql_num_rows($result);
if($info==false){
echo"不存在!";
}
}


do{
?>
<tr>
<td><?php echo $info[id] ?></td>
<td><?php echo $info[name] ?></td>
</tr>

<?php
}
while($info=mysql_fetch_array($result));

if($num!=0){
echo"找到条".$num."记录";
}
?>

5.利用update实现动态编辑,修改删除与添加查询稍有不同,因为要进行编辑时要根据id来选择编辑哪条记录,所以要多一个传id的动作,可以简便的通过URL传递id再用$_GET[id]接收,全部可以分为三个页,显示页,修改界面业和功能页。

 显示页:

<table width="500" cellpadding="0" cellspacing="0" border="0" align="center" >
<tr>
<td align="center">查询公告信息</td>
</tr>
<tr><td height="20"></td></tr>
<tr>
<form name="form_search" method="post" action="">
<td>
查询关键字   <input type="text" name="txt_search" id="txt_search" size="40">  <input type="submit" name="sub_search" value="搜索">
</td>
</form>
</tr>
<tr><td height="20"></td></tr>
<tr>
<td>
<table cellpadding="0" cellspacing="0" border="1" width="480" align="center">
<tr align="center">
<td>公共标题</td>
<td>公告内容</td>
<td>编辑</td>
</tr>

<?php
mysql_connect("localhost","root","root")or die("数据库服务连接错误!".mysql_error());
mysql_query("use database");
mysql_query("set names gbk");
$result=mysql_query("select * from tb_affiche");
$info=mysql_fetch_array($result);
if($_POST[sub_search]=="搜索"){
$txt_search=$_POST[txt_search];
$result=mysql_query("select * from tb_affiche where title like '%". $txt_search ."%'");
$info=mysql_fetch_array($result);
}
do{
?>
<tr>
<td> <?php echo $info[title] ?> </td>
<td> <?php echo $info[content] ?> </td>
<td>
<a href="modify.php ? id=<?php echo $info[id]; ?> ">//在<a>中通过url传递id值,需要用$_GET[id]接收
<img src="update.gif" border="0">
</a>
</td>
</tr>
<?php
}
while($info=mysql_fetch_array($result));


?>


</table>
</td>
</tr>
</table>


修改界面页:
<?php
mysql_connect("localhost","root","root")or die("数据库服务连接错误!".mysql_error());
mysql_query("use database");
mysql_query("set names gbk");
$id=$_GET[id];
$result=mysql_query("select*from tb_affiche where id=$id");
$info=mysql_fetch_array($result);

?>

<form name="form" method="post" action="modify_ok.php">
<table width="500" cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="center">编辑公告信息</td>
</tr>
<tr>
<td>
公告主题:<input type="text" name="txt_title" id="txt_title" size="40" >
<input type="hidden" name="id" value=" <?php echo $info[id]; ?>">//隐藏域,用于通过post来传递id值,但这里不能直接用value="$info[id]",因为不在php语句中
</td>
</tr>
<tr>
<td>
公告内容 <textarea name="txt_content" > <?php echo $info[content] ?> </textarea>
</td>
</tr>
<tr>
<td>
<input type="submit" name="submit" value="修改">
</td>
</tr>
</table>
</form>

修改功能界面:

<?php
$link=mysql_connect("localhost","root","root")or die("连接失败".mysql_error());
mysql_select_db("database",$link);
mysql_query("set names gbk");

$txt_title=$_POST[txt_title];//通过post分别获取txt_text,txt_content和id的值
$txt_content=$_POST[txt_content];
$id=$_POST[id];

$result=mysql_query("update tb_affiche set title=$txt_title, content=$txt_content where id=$id");
if($result!=false){
echo " <script> alert('修改成功'); window.location.href='index.php' </script> ";
}
?>

6.分页算法:首先算法有如下几个变量,每页显示的记录数$page_size,由设计者自行规定;记录总数$total,可以用select count(*) from table;来获取总的记录数,当然得到的是一个结果集标识符,还需要mysql_fetch_array()或者mysql_result()转换;页面总数$page_count= $total / $page_size,得到的可能是一个浮点数,再用ceil()转换成整数;最后一个,也是最总要的一个参数,$offset,它表示的是本页面(倒序)从第几个记录开始显示,首先我们显示这些记录用的select语句为 

select * from table order by id desc limit $offset, $page_size;  请注意limit后面的两个参数,第一个参数表示从第几个记录开始搜索,从0开始;第二个参数表示一次列出几个记录,也就是说limit 0,1 是显示第一个(倒序后,也就是id最大的那个),limit 1,1是显示第二个。

我们假设共有16个记录,每页能显示4个记录,一共有4页,页数分别1,2,3,4,我们可以得到如下表格(序号=16-1-id ,从0开始,id从1开始)

页号 1                 2                 3              4                
limit的两个参数 0,4 4,4 8,4 12,4
序号 0 4 8 12
序号 1 5 9 13
序号 2 6 10 14
序号 3 7 11 15

根据这个表格我们可以很轻易得出limit的第一个参数$offset 与当前页号$page 之间的关系,即 $offset = ($page-1) * $page_size ,这是分页算法的关键。

得到$offset后利用select * from table order by id desc limit $offset , $page_size ;即可得到本页面所有的记录的结果集,一一显示即可。下一步是制作上一页和下一页的超链接分页条,在大部分页面中都要显示首页,上一页,下一页,尾页这四个超链接,只有在首页只显示下一页和尾页,在尾页只显示首页和上一页,而这两者又是互补的,所以可以巧妙的利用两个if语句,即当不为首页时显示首页和上一页,当不为尾页时显示下一页和尾页,即可完成所有判断工作。另外,虽然返回的依然是这个界面,但在<a>中需要传递新的page值,这样才能改变显示的记录,新page值用$_GET[page]接收,这样便完成了分页的效果。

以下为分页代码:

<table width="500" cellpadding="0" cellspacing="0" border="1" align="center" style="text-align:center">
<tr align="center">
<td colspan="2" height="30">学生信息分页显示</td>
</tr>
<tr align="center" bgcolor="#EBEEF3">
<td>姓名</td>
<td>性别</td>
</tr>

<?php
$link=mysql_connect("localhost","root","root")or die("服务器连接失败!".mysql_error);
mysql_select_db("db_database18",$link)or die("数据库连接失败!".mysql_error);
mysql_query("set names gbk");
$page=$_GET[page];//接收分页条链接url中传来的新page值
if($page==""){$page=1;}//如果第一次打开,page默认值为1
$page_size=2;
$result_total=mysql_query("select count(*) as total from tb_member");//返回值为total=总记录数,as是别名
$total=mysql_result($result_total,0,"total");//返回一个数据,第一个参数结果集标识符,第三个为字段名(列),第二个表示行数(从0开始)
$page_count=ceil($total/$page_size);//ceel()是得到大于等于浮点数的一个整数
$offset=($page-1)*$page_size;//得到limit的一个参数,分析见上
$sql=mysql_query("select * from tb_member order by M_ID desc limit $offset,$page_size");
$info=mysql_fetch_array($sql);
do{
?>

<tr>
<td> <?php echo $info[M_Name]; ?></td>
<td> <?php echo $info[M_Sex]; ?></td>
</tr>

<?php
}
while($info=mysql_fetch_array($sql));//逐行显示
?>
<table width="500" cellspacing="0" cellpadding="0" border="0" align="center">
<tr><td height="10"><td><tr>
<tr style="font-size:13px" >
<td width="40%" style="text-align:center">
<?php echo "页次:".$page."/".$page_count."页 记录:".$total."条"; ?>
<td style="text-align:right">
<?php
if($page!=1){
echo"<a href=index.php?page=1>首页</a> ";//通过URL传递新的page值
$page_last=$page-1;
echo"<a href=index.php?page=$page_last>上一页</a> ";
}

if($page!=$page_count){
$page_next=$page+1;
echo "<a href=index.php?page=$page_next>下一页</a> ";
echo "<a href=index.php?page=$page_count>尾页</a>";
}

?>

</td>
</td>
</tr>


</table>