开启mysqli扩展

从PHP 5.0开始,不仅可以使用早期的mysql数据库扩展函数,而且还可以使用新的扩展mysqli技术实现与MySQL数据库的信息交流。PHP的 mysqli扩展被封装到一个类中,它是一种面向对象的技术,只能在PHP 5和MySQL 4.1(或更高的版本)环境中使用,(i)表示改进,其执行速度更快。使用mysqli扩展和传统的过程化方法相比更方便也更高效。利用mysqli扩展 技术不仅可以调用MySQL的存储过程、处理MySQL事务,而且还可以使访问数据库工作变得更加稳定。

喜欢过程化编程的用户也不用担心,mysqli也有过程式的方式,提供了一个传统的函数式接口,只不过开始贯以mysqli的前缀,其他都差不多。 如果mysqli以过程式的方式操作的话,有些函数必须指定资源,比如说 mysqli_query(资源标识,SQL语句)。并且资源标识的参数是放在前面的,而mysql_query(SQL语句,’可选’)的资源标识是放 在后面的,并且可以不指定,它默认是上一个打开的连接或资源。本书将重点介绍他的面向对象的用法,如果更喜欢以过程化方式编写程序,使用前面介绍的 mysql功能扩展模块就可以了。这里,希望读者使用面向对象的方式编程,这样可以编写出更容易阅读和理解的代码。

启用mysqli扩展模块

与mysql功能扩展模块类似,mysqli接口也不是PHP的一个集成组件,如果想使用这个功能扩展模块,需要显示配置PHP才能使用此扩展。在 不同平台下的配置有所不同,如果在Linux平台中启用mysqli扩展,必须在编译PHP时加上–with-mysqli选项。如果在Windows 平台中启用mysqli扩展,需要通过一个DLL文件提供相应的扩展。不管使用的是哪一个操作系统平台,都必须在php.ini文件里启用这个扩展,以确 保PHP能够找到所有必要的DLL。可以在php.ini文件中找到下面一行,取消前面的注释,如果没有找到就添加这样一行:

  1. extension=php_mysqli.dll              //在php.ini文件中启用这一行

关于配置PHP的更多信息,请参见本书第2章的环境安装。另外,可以在PHP脚本文件中,调用phpinfo()函数检查PHP版本是否支持mysqli接口。如果找到如图13-1所示的结果,则所用的PHP版本中支持mysqli接口。

图13-1  使用phpinfo()函数检查mysqli扩展模块的支持

mysqli 扩展不仅提供了mysql模块的所有功能,也相应地增加了一些新特性。mysqli扩展模块包括mysqli、mysqli_result和 mysqli_stmt三个类,通过这三个类的搭配使用,就可以连接MySQL数据库服务器和选择数据库、查询和获取数据,以及使用预处理语句简化了重复 执行的查询语句。

EXPLAIN

使用explain语句去查看分析结果,如
explain select * from test1 where id=1;
会出现:
id  selecttype  table  type possible_keys  key key_len  ref rows  extra各列

其中,

type=const表示通过索引一次就找到了,
key=primary的话,表示使用了主键 
type=all,表示为全表扫描,
key=null表示没用到索引;
type=ref,因为这时认为是多个匹配行,在联合查询中,一般为REF

2 MYSQL中的组合索引
假设表有id,key1,key2,key3,把三者形成一个组合索引,则
如:
  where key1=….
  where key1=1 and key2=2
  where key1=3 and key3=3 and key2=2
根据最左原则,这些都是可以使用索引的哦

  from test where key1=1 order by key3
用explain分析的话,只用到了normal_key索引,但只对where子句起作用,而后面的order by需要排序

3 使用慢查询分析:
在my.ini中:
long_query_time=1
log-slow-queries=d:\mysql5\logs\mysqlslow.log

把超过1秒的记录在慢查询日志中
可以用mysqlsla来分析之。也可以在mysqlreport中,有如
DMS 分别分析了select ,update,insert,delete,replace等所占的百份比

4 MYISAM和INNODB的锁定
myisam中,注意是表锁来的,比如在多个UPDATE操作后,再SELECT时,会发现SELECT操作被锁定了,必须等所有UPDATE操作完毕后,再能SELECT 

innodb的话则不同了,用的是行锁,不存在上面问题。
 
5 MYSQL的事务配置项
innodb_flush_log_at_trx_commit=1
表示事务提交时立即把事务日志写入磁盘,同时数据和索引也更新

innodb_flush_log_at_trx_commit=0
事务提交时,不立即把事务日志写入磁盘,每隔1秒写一次
innodb_flush_log_at_trx_commit=2
事务提交时,立即写入磁盘文件(这里只是写入到内核缓冲区,但不立即刷新到磁盘,而是每隔1秒刷新到盘,同时更新数据和索引 

explain用法
EXPLAIN tbl_name
或:
EXPLAIN [EXTENDED] SELECT select_options

前者可以得出一个表的字段结构等等,后者主要是给出相关的一些索引信息,而今天要讲述的重点是后者。

举例
mysql> explain select * from event;
+—-+————-+——-+——+—————+——+———+——+——+——-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+——+———+——+——+——-+
| 1 | SIMPLE | event | ALL | NULL | NULL | NULL | NULL | 13 | |
+—-+————-+——-+——+—————+——+———+——+——+——-+
1 row in set (0.00 sec)

各个属性的含义
id
select查询的序列号

select_type
select查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询。

table
输出的行所引用的表。

type
联合查询所使用的类型。
type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般来说,得保证查询至少达到range级别,最好能达到ref。

possible_keys
指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段不是适合索引。

key
显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL。

key_len
显示MySQL决定使用的键长度。如果键是NULL,长度就是NULL。文档提示特别注意这个值可以得出一个多重主键里mysql实际使用了哪一部分。

ref
显示哪个字段或常数与key一起被使用。

rows
这个数表示mysql要遍历多少数据才能找到,在innodb上是不准确的。

Extra
如果是Only index,这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。
如果是where used,就是使用上了where限制。
如果是impossible where 表示用不着where,一般就是没查出来啥。
如果此信息显示Using filesort或者Using temporary的话会很吃力,WHERE和ORDER BY的索引经常无法兼顾,如果按照WHERE来确定索引,那么在ORDER BY时,就必然会引起Using filesort,这就要看是先过滤再排序划算,还是先排序再过滤划算。

常见的一些名词解释
Using filesort
MySQL需要额外的一次传递,以找出如何按排序顺序检索行。

Using index
从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。

Using temporary
为了解决查询,MySQL需要创建一个临时表来容纳结果。

ref
对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取

ALL
完全没有索引的情况,性能非常地差劲。

index
与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

SIMPLE
简单SELECT(不使用UNION或子查询)

对于SQL优化开发这需要牢记的原则

比如下边的sql语句:

mysql>SELECT * FROM table WHERE a>’0′ AND b<‘1’ ORDER BY c LIMIT 10;

事实上无论a>’0’还是b<‘1’在前,得到的结果都是一样的,但查询速度大不相同,尤其是对大表进行操作时。

开发者需要牢记的原则是:最先出现的条件,一定是过滤和排除掉最多结果的条件;第二出现的次之;以此类推。因而,表中不同字段的值的分布,对查询速度有很大影响。而ORDER BY中的条件,只与索引有关,与条件顺序无关。

除了条件顺序优化以外,针对固定或者相对固定的SQL查询语句,还可以通过针对索引结构进行优化,进而实现相对高的查询速度。原则是:在大多数情况下,根据WHERE条件的先后顺序和ORDER BY 的排序字段的先后顺序而建立的联合索引,就是与这条SQL语句匹配的最有索引结构。尽管事实的茶品中不能只考虑一条SQL语句,也不能不考虑空间占用太多的索引。

摘自细说php

Mysql错误 ERROR 1036 (HY000): Table ‘ is read only

起因:最近新项目网站搬家到新服务器,感觉直接复制data下的文件比省事,所以就直接将data文件放到服务器对应的mysql下(一般linux中mysql的data文件在/var/lib/mysql/目录下)!

解决办法:由于项目新接手过来,不知道密码是多少,于是想直接在msyql命令里改一下密码,结果总是出现“ERROR 1036 (HY000): Table ‘ is read only”,这个鸟词(不明白啥意思),查了一下,就是因为这个mysql的文件权限问题,改吧(就按照其他正确的数据库权限来改),并且改完后需要重启mysql

再找到mysqladmin文件(应该在这个目录/usr/bin/mysqladmin)执行如下命令:

然后输入密码

ok

在到mysql命令下更改密码,没有问题!

linux下rpm方法安装mysql

由于公司网站和数据库不在同一个服务器上,公司不想使用两个服务器(原因你懂得),只想把网站和数据库都放到一个服务器上,那么就要把数据库导回到网站服务器上,所以需要在web服务器上安装mysql,但是以查看web服务器以前安装过mysql,所以选择了rpm方法安装(也是从网上找的),一下是整理的思路和安装过程。

1:系统是否安装MySQL

如果mysql已经安装过就会出现

如图:

那么用命令删除掉以前的安装版本

注意:如果删除不掉肯定是有依赖包导致的。

 

2:安装

创建mysql文件夹,到官网下载对应你想要的mysql版本

得到如下文件夹

(1):安装mysql服务端,输入以下命令:

会出现如下提示:(如何修改密码)

表示mysql安装完成

(2):检测mysql 3306是否安打开,输入以下命令

查询结果如图:

证明MySQL服务已经启动。

(3):安装mysql客户端,同理输入以下命令

warning: MySQL-client-5.1.73-1.glibc23.x86_64.rpm: V3 DSA signature: NOKEY, key ID 5072e1f5

Preparing…    ########################################### [100%]

MySQL-client  ########################################### [100%]

显示安装完毕。

(4):按照刚才安装完服务端后的提示来修改密码了!

(5):尝试连接数据库

mysql -u root -h localhost -p

3:配置文件问题(无法找到my.cnf文件)

Linux下用rpm包安装的MySQL是不会安装/etc/my.cnf文件的,至于为什么没有这个文件而MySQL却也能正常启动和作用,在这有两个说法

第一种说法,my.cnf只是MySQL启动时的一个参数文件,可以没有它,这时MySQL会用内置的默认参数启动

第二种说法,MySQL在启动时自动使用/usr/share/mysql目录下的my-medium.cnf文件,这种说法仅限于rpm包安装的MySQL,

解决方法,只需要复制一个/usr/share/mysql目录下的。cnf文件到/etc目录,并改名为my.cnf即可。

IP地址存储在mysql中用什么字段

php处理ip地址的函数有:

ip2long()是把ip地址转换成整型 如:echo ip2long(‘192.168.1.1’); //结果是3232235777
long2ip()将整型的数值转换成ip地址如:echo long2ip(‘3232235777’); //结果就是323223577
那么就是说ip2long这个php函数可以将正常的ip地址转换成无符号的整型数据存放到数据库中,正常的varchar类型存储需要15个字节,而int类型只需4个字节,所以节省了一定的空间!
****需要注意的一点在32与64位操作系统的电脑上ip2long()函数返回是有一个最大值区间的:如下
32 bits ip2long(): -2147483648 ~ 214748364764
64 bits ip2long(): 0 ~ 4294967295
在32为机器上如果ip2long()返回值大于最大值( 214748364764)那么返回的将是一个负数值,根据官方给出的解决办法
$ip_long = bindec(decbin(ip2long($ip)));

$ip_long = = sprintf(“%u”, ip2long($ip));