PHP和MySQL爱考的10道题
来自《PHP程序员面试笔试宝典》,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书。
一、如何进行数据库优化?
数据库优化的过程可以使用以下的方法进行:
1)选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置NOT NULL,例如'省份、性别',最好设置为ENUM。
2)使用连接(JOIN)来代替子查询。
① 删除没有任何订单客户:DELETE FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)。
② 提取所有没有订单客户:SELECT FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)。
③ 提高b的速度优化:SELECT FROM customerinfo LEFT JOIN orderid customerinfo. customerid=orderinfo.customerid WHERE orderinfo.customerid IS NULL。
3)使用联合(UNION)来代替手动创建的临时表。创建临时表:SELECT name FROM 'nametest' UNION SELECT username FROM 'nametest2'。
4)事务处理。保证数据完整性,例如添加和修改。同时,如果两者成立,则都执行,一者失败都失败:
mysql_query("BEGIN");
mysql_query("INSERT INTO customerinfo (name) VALUES ('$name1')";
mysql_query("SELECT * FROM 'orderinfo' where customerid=".$id");
mysql_query("COMMIT");
5)锁定表,优化事务处理。用一个SELECT语句取出初始数据,通过一些计算,用UPDATE语句将新值更新到表中。包含有WRITE关键字的LOCK TABLE语句可以保证在UNLOCK TABLES命令被执行之前,不会有其他的访问来对customerinfo表进行插入、更新或者删除的操作。
mysql_query("LOCK TABLE customerinfo READ, orderinfo WRITE");
mysql_query("SELECT customerid FROM 'customerinfo' where id=".$id);
mysql_query("UPDATE 'orderinfo' SET ordertitle='$title' where customerid=".$id);
mysql_query("UNLOCK TABLES");
6)使用外键,优化锁定表。把customerinfo里的customerid映射到orderinfo里的customerid,任何一条没有合法的customerid的记录不会写到orderinfo里。
CREATE TABLE customerinfo
(
customerid INT NOT NULL,
PRIMARY KEY(customerid)
)TYPE = INNODB;
CREATE TABLE orderinfo
(
orderid INT NOT NULL,
customerid INT NOT NULL,
PRIMARY KEY(customerid,orderid),
FOREIGN KEY (customerid) REFERENCES customerinfo
(customerid) ON DELETE CASCADE
)TYPE = INNODB;
注意:'ON DELETE CASCADE',该参数保证当customerinfo表中的一条记录删除的话同时也会删除order。
表中的该用户的所有记录,注意使用外键时要定义数据库引擎为INNODB。
二、选择正确的存储引擎?
在MySQL中有两个存储引擎:MyISAM和InnoDB,每个引擎都有利有弊。
MyISAM适合于一些需要大量查询的应用,但其对于有大量写操作的支持并不是很好。甚至只是需要update一个字段,整个表都会被锁起来,而其他进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。
InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。但是它支持“行锁”,于是在写操作比较多的时候,会更优秀。并且,它还支持更多的高级应用,例如事务。
三、【真题231】 用什么方法检查PHP脚本的执行效率(通常是脚本执行时间)和数据库SQL的效率(通常是数据库query时间),并定位和分析脚本执行和数据库查询的瓶颈所在?
参考答案:检查PHP脚本的执行效率的方法如下:可以在检查的代码开头记录一个时间,然后在代码的结尾也记录一个时间,结尾时间减去开头时间取这个时间的差值,从而检查PHP的脚本执行效率,记录时间可以使用microtime()函数。
检查数据库SQL的效率的方法如下:可以通过explain显示MySQL如何使用索引来处理select语句及连接表,帮助选择更好的索引和写出更优化的查询语句。然后启用slow query log记录慢查询,通过查看SQL的执行时间和效率来定位分析脚本执行的问题和瓶颈所在。
四、 以下代码的运行结果为( )。
<?php
mysql_connect('localhost','root',"");
$result = mysql_query("SELECT id,name FROM tb1");
while($row = mysql_fetch_array($result,MySQL_ASSOC)){
echo' ID:' .$row[0].' Name:' .$row[];
}
?>
A.报错 B.循环换行打印全部记录
C.无任何结果 D.只打印第一条记录
参考答案:A。
分析:因为代码中没有指明要操作的数据库名,所以会报错。
所以,本题的答案为A。
五、考虑如下数据表和查询,如何添加索引能提高查询速度?( )
CREATE TABLE MYTABLE (
ID INT,
NAME VARCHAR (100),
ADDRESS1 VARCHAR (100),
ADDRESS2 VARCHAR (100),
ZIPCODE VARCHAR (10),
CITY VARCHAR (50),
PROVINCE VARCHAR (2)
)
SELECT ID, VARCHAR FROM MYTABLE WHERE ID BETWEEN 0 AND 100 ORDER BY NAME, ZIPCODE
A.给 ID 添加索引
B.给 NAME 和 ADDRESS1 添加索引
C.给ID 添加索引,然后给 NAME 和 ZIPCODE 分别添加索引
D.给ZIPCODE 和 NAME 添加索引
参考答案:C。
分析:给ID字段设置索引能提高 where 条件执行的效率,给 NAME 和 ZIPCODE设索引则能使排序更快。
六、 如何高效操作MySQL?
MySQL对于PHP甚至是所有开发者都是非常基础和重要的模块,对于熟悉的LAMP体系架构,我们需要构建稳定可靠的系统,数据库环境是必不可少和关键的地方。在使用MySQL过程中,有以下建议:
1)使用InnoDB数据库引擎。MySQL常用的有MyISAM和InnoDB两种,MyISAM不支持外键约束或者事务处理。当插入或更新一条记录时,整个数据表都被锁定了,随着使用量的增加,性能会非常差。
2)使用MySQLi面向对象的数据库操作方法。PHP5支持了面向对象的访问数据库方法。具体的优点前面已经讲过,此处不再赘述。
3)对于用户输入进行验证。用户输入的内容是一个很大的变量之一,要防止SQL注入或黑客登录等安全隐患。
4)MySQL未使用utf-8字符集。utf-8字符集解决了很多国际化的问题,需要尽量使用此字符集,防止字符的问题出现。
5)通过SQL来替代PHP逻辑处理。通常来说,执行一个查询比在结果中使用PHP语言来迭代处理更有效率。所以,需要尽量通过SQL来替代PHP逻辑处理,提高效率。
6)优化数据库查询。几乎绝大部分PHP性能问题都是数据库引起的,经常出现的慢查询等SQL查询问题可能会让系统崩溃。需要对数据库进行优化查询。
7)要正确使用数据类型。
MySQL提供了诸如numeric、string和date等的数据类型。如果想存储一个时间,那么使用date或者datetime类型。如果这个时候用integer或者string类型,那么将会使得SQL查询非常复杂。
很多人倾向于擅自自定义一些数据的格式,例如,使用string来存储序列化的PHP对象。这样的话数据库管理起来可能会变得简单些,但会使得MySQL成为一个糟糕的数据存储而且之后很可能会引起故障。
8)不要在查询中使用“*”。这会返回表中所有数据,这是懒惰的表现,会在降低效率和出错概率上都大大提高。
9)合理使用索引技术。不使用或过度使用索引都会造成性能降低。如果在每个字段都加了索引,那么当执行修改操作时,索引都需要重新生成,会对性能影响较大。不使用索引,同样会造成全表查询,降低效率。使用索引一般性原则是这样的:select语句中的任何一个where子句表示的字段都应该使用索引。
10)记得备份。数据库必须进行备份,常见的有主从、主主数据库等系统架构形式。
七、【真题222】 以下说法正确的是( )。
A.使用索引能加快插入数据的速度
B.良好的索引策略有助于防止跨站攻击
C.应当根据数据库的实际应用合理设计索引
D.删除一条记录将导致整个表的索引被破坏
参考答案:C。
分析:索引的作用主要是帮助数据库快速查找到对应的数据,并不能加快插入数据的速度,所以,选项A错误。
索引不能够帮助防止跨站攻击,所以,选项B错误。
创建合理的索引需要分析数据库的实际用途并找出它的弱点。优化脚本中的冗余查询同样也能提高数据库效率。索引是占用物理空间的,所以在实际的应用中是要合理设计使用索引的。所以,选项C正确。
索引是一种表结构,删除一条数据也不会影响到整个表的索引,并且索引不一定是数字,也可以是字符串。所以,选项D错误。
八、如何对MySQL的系统内核优化?
大多数MySQL都部署在Linux系统上,所以,操作系统的一些参数也会影响到MySQL性能,以下参数的设置可以对Linux内核进行适当优化。
l net.ipv4.tcp_fin_timeout = 30 #TIME_WAIT超时时间,默认是60s
l net.ipv4.tcp_tw_reuse = 1 #1表示开启复用,允许TIME_WAIT socket重新用于新的TCP连接,0表示关闭
l net.ipv4.tcp_tw_recycle = 1 #1表示开启TIME_WAIT socket快速回收,0表示关闭
l net.ipv4.tcp_max_tw_buckets = 4096 #系统保持TIME_WAIT socket最大数量,如果超出这个数,系统将随机清除一些TIME_WAIT并打印警告信息
l net.ipv4.tcp_max_syn_backlog = 4096 #进入SYN队列最大长度,加大队列长度可容纳更多的等待连接
在Linux系统中,如果进程打开的文件句柄数量超过系统默认值1024,就会提示“too many files open”信息,所以,要调整打开文件句柄限制。
# vi /etc/security/limits.conf #加入以下配置,*代表所有用户,也可以指定用户,重启系统生效
* soft nofile 65535
* hard nofile 65535
# ulimit -SHn 65535 #立刻生效
九、什么是数据库权限?
关于MySQL的权限简单的理解就是MySQL允许用户做权利以内的事情,不可以越界。例如只允许一个用户执行SELECT操作,那么它就不能执行UPDATE操作;只允许一个用户从某台机器上连接MySQL,那么它就不能从除那台机器以外的其他机器连接MySQL。
那么MySQL的权限是如何实现的呢?这就要说到MySQL的两阶段的验证,下面详细来介绍。第一阶段:服务器首先会检查是否允许连接。因为创建用户的时候会加上主机限制,可以限制成本地、某个IP、某个IP段以及任何地方等,只允许你从配置的指定地方登录。后面在实战的时候会详细介绍关于主机的限制。第二阶段:如果能连接,那么 MySQL 会检查发出的每个请求,看是否有足够的权限实施它。例如,要更新某个表或者查询某个表,MySQL会检查对某个表或者某个列是否有权限。再例如,要运行某个存储过程,MySQL会检查对存储过程是否有执行权限等。
MySQL权限控制原则:
1)只授予能满足需要的最小权限,防止用户干坏事。例如,用户只是需要查询,那就只给SELECT权限就可以了,不要给用户赋予UPDATE、INSERT或者DELETE权限。
2)创建用户的时候限制用户的登录主机,一般是限制成指定IP或者内网IP段。
3)初始化数据库的时候删除没有密码的用户。安装完数据库的时候会自动创建一些用户,这些用户默认没有密码。
4)为每个用户设置满足密码复杂度要求的密码。
5)定期清理不需要的用户。回收权限或者删除用户。
示例1:创建一个只允许从本地登录的超级用户feihong,并允许将权限赋予别的用户,密码为123。
GRANT ALL PRIVILEGES ON *.* TO feihong@'localhost' IDENTIFIED BY '123' WITH GRANT OPTION;
GRANT命令说明:
ALL PRIVILEGES 是表示所有权限,也可以使用SELECT、UPDATE等权限。
ON 用来指定权限针对哪些库和表。
*.* 中前面的*号用来指定数据库名,后面的*号用来指定表名。
TO 表示将权限赋予某个用户。
feihong@'localhost' 表示feihong用户,@后面接限制的主机,可以是IP、IP段、域名以及%,%表示任何地方。注意:这里%有的版本不包括本地,以前碰到过给某个用户设置了%允许任何地方登录,但是在本地登录不了,这个和版本有关系,遇到这个问题再加一个localhost的用户就可以了。
IDENTIFIED BY 指定用户的登录密码。
WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人。注意:经常有人在创建操作用户的时候不指定WITH GRANT OPTION选项,导致后来该用户不能使用GRANT命令创建用户或者给其他用户授权。
备注:可以使用GRANT重复给用户添加权限,权限叠加,例如,先给用户添加了一个SELECT权限,然后又给用户添加了一个INSERT权限,那么该用户就同时拥有了SELECT和INSERT权限。
示例2:创建一个网站用户(程序用户)。
创建一个一般的程序用户,这个用户可能只需要SELECT、INSERT、UPDATE、DELETE、CREATE TEMPORARY TABLES等权限,如果有存储过程还需要加上EXECUTE权限,那么一般是指定内网网段192.168.100网段。
GRANT USAGE,SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ,CREATE TEMPORARY TABLES,EXECUTE ON 'test'.* TO webuser@'192.168.100.%' IDENTIFIED BY 123';
示例3:创建一个普通用户(仅有查询权限)。
GRANT USAGE,SELECT ON 'test'.* TO public@'192.168.100.%' IDENTIFIED BY 'test';
示例4:查看权限。
使用如下命令可以方便地查看到某个用户的权限:
SHOW GRANTS FOR 'webuser'@'192.168.100.%';
示例5:删除用户。
注意删除用户不要使用DELETE直接删除,因为使用DELETE删除后用户的权限并未删除,新建同名用户后又会继承以前的权限。正确的做法是使用DROP USER命令删除用户,例如,要删除'webuser'@'192.168.100.%'用户采用如下命令:
DROP USER 'webuser'@'192.168.100.%';
示例6:回收权限。
将前面创建的webuser用户的DELETE权限回收,使用如下命令:
REVOKE DELETE ON test.* FROM 'webuser'@'192.168.100.%';
十、【真题220】 MySQL数据库中的字段类型varchar和char的主要区别是什么?哪种字段的查找效率要高,为什么?
参考答案:varchar是变长,节省存储空间,char是固定长度。查找效率char型比varchar快,因为varchar是非定长,必须先查找长度,然后进行数据的提取,比char定长类型多了一个步骤,所以效率低一些。
购买链接:京东购买
以上就是PHP+mysql面试中经常爱考和爱问的几个笔试面试问题。
题目来自《PHP程序员面试笔试宝典》,里面涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书。
更多PHP面试笔试真题可以浏览:www.shuaiqi100.com
更多有趣有料的PHP面试笔试资料可以关注:“琉忆编程库”
或者浏览:www.shuaiqi100.com 获取。
PHP程序员面试笔试宝典下载:https://pan.baidu.com/s/1-ES2ZI3z5Lhv-zTKFmJDSQ