PHP+mysql真题
PHP+mysql真题
来自《PHP程序员面试笔试宝典》,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书。
【真题215】 按要求写出SQL实现。
1)创建新闻发布系统,表名为message,有如下字段:
id 文章id
title 文章标题
content 文章内容
category_id 文章分类id
hits 点击量
参考答案:
CREATE TABLE 'message'(
'id' int(10) NOT NULL auto_increment,
'title' varchar(200) default NULL,
'content' text,
'category_id' int(10) NOT NULL,
'hits' int(20),
PRIMARY KEY('id');
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
2)同样上述新闻发布系统:表comment记录用户回复内容,字段如下:
comment_id 回复id
id 文章id,关联message表中的id
comment_content 回复内容
现通过查询数据库需要得到以下格式的文章标题列表,并按照回复数量排序,回复最高的排在最前面。
文章id 文章 标题 点击量 回复 数量
用一个SQL语句完成上述查询,如果文章没有回复,则回复数量显示为0。
参考答案:
SELECT message.id id,message.title title,IF(message.'hits' IS NULL,0,message. 'hits') hits,
IF(comment. 'id' is NULL,0,count(*)) number FROM message LEFT JOIN
comment ON message.id=comment.id GROUP BY message. 'id';
上述内容管理系统,表category保存分类信息,字段如下:
category_id int(4) not null auto_increment;
category_name varchar(40) not null;
3)用户输入文章时,通过选择下拉菜单选定文章分类,写出如何实现这个下拉菜单。
参考答案:
function categoryList()
{
$result=mysql_query("select category_id,categroy_name from category")
or die("Invalid query: " . mysql_error());
print("<select name='category' value=''>/n");
while($rowArray=mysql_fetch_array($result))
{
print("<optionvalue='".$rowArray['category_id']."'>".$rowArray['categroy_name']."</ option>/n");
}
print("</select>");
}
【真题216】 使用PHP写一段简单查询,查出所有姓名为“张三”的内容并打印出来。
表名User
Name Tel Content Date
张三 13333663366 大专毕业 2006-10-11
张三 13612312331 本科毕业 2006-10-15
张四 021-55665566 中专毕业 2006-10-15
参考答案:根据上面的题目完成代码:
$mysql_db=mysql_connect("local","root","pass");
@mysql_select_db("DB",$mysql_db);
$result = mysql_query("SELECT * FROM 'user' WHERE name='张三'");
while($rs = mysql_fetch_array($result)){
echo $rs["tel"].$rs["content"].$rs["date"];
}
【真题217】 考虑如下SQL语句,哪个选项能对返回记录的条数进行限制?( )(双选)
SELECT * FROM MY_TABLE
A.如果可能,那么把查询转换成存储例程
B.如果程序允许,那么给查询指定返回记录的范围
C.如果可能,那么添加 where 条件
D.如果DBMS允许,那么把查询转换成视图
参考答案:B、C。
分析:有两个方法能限制返回记录的条数——使用 where 条件或limit关键字指定查询返回的记录的范围。
通常情况下,如果没有特殊需要,那么尽量不要用 select *,这会浪费大量的数据缓存。
【真题218】 执行以下 SQL 语句后将发生( )。
BEGIN TRANSACTION
DELETE FROM MYTABLE WHERE ID=1
DELETE FROM OTHERTABLE
ROLLBACK TRANSACTION
A.OTHERTABLE 中的内容将被删除
B.OTHERTABLE 和 MYTABLE 中的内容都会被删除
C.OTHERTABLE 中的内容将被删除,MYTABLE 中 ID 是 1 的内容将被删除
D.数据库没有变化
参考答案:D。
分析:这个查询是一个事务,并且这个事务的最后有回滚,数据库不会有变化。
【真题219】 以下查询的输出结果是( )。
SELECT COUNT(*) FROM TABLE1 INNER JOIN TABLE2 ON TABLE1.ID <> TABLE2.ID
A.TABLE1 和 TABLE2 不相同的记录
B.两个表中相同的记录
C.TABLE1 中的记录条数乘以 TABLE2 中的记录条数再减去两表中相同的记录条数
D.两表中不同记录的条数
参考答案:C。
分析:本题描述了一种在使用JOIN时常犯的概念性错误。很多人可能觉得这个查询将返回两个表中非共有记录。但实际上数据库却认为是“读出所有 ID 非共有的记录”。DBMS将读取左边表中所有的记录加上右边表中 ID 非共有的记录。因此,该查询将读取TABLE1 中的每条记录乘以TABLE2中的每条记录再减去两表中相同的记录条数。
【真题222】 以下说法正确的是( )。
A.使用索引能加快插入数据的速度
B.良好的索引策略有助于防止跨站攻击
C.应当根据数据库的实际应用合理设计索引
D.删除一条记录将导致整个表的索引被破坏
参考答案:C。
分析:索引的作用主要是帮助数据库快速查找到对应的数据,并不能加快插入数据的速度,所以,选项A错误。
索引不能够帮助防止跨站攻击,所以,选项B错误。
创建合理的索引需要分析数据库的实际用途并找出它的弱点。优化脚本中的冗余查询同样也能提高数据库效率。索引是占用物理空间的,所以在实际的应用中是要合理设计使用索引的。所以,选项C正确。
索引是一种表结构,删除一条数据也不会影响到整个表的索引,并且索引不一定是数字,也可以是字符串。所以,选项D错误。
【真题223】 下列关于全文检索技术的说法中,不正确的是( )。
A.Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL做全文搜索,它可以提供比数据库本身更专业的搜索功能
B.Solr是新一代的全文检索组件,它比Lucene的搜索效率高很多,还能支持HTTP的访问方式,PHP调用Solr也很方便
C.MySQL中把一个字段建立FULLTEXT索引,就可以实现全文检索,目前MyISAM和InnoDB的table都支持FULLTEXT索引
D.Lucene附带的二元分词分析器CJKAnalyzer切词速度很快,能满足一般的全文检索需要
参考答案:B。
分析:Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL、PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。
Solr是一个独立的企业级搜索应用服务器,用户可以通过HTTP请求访问,它是采用JAVA5开发,基于Lucene的全文搜索服务器,同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。并且Solr比Lucene的搜索效率高很多,但是PHP调用Solr并不方便,选项B的说法错误。
MySQL中的MyISAM和InnoDB都是支持FULLTEXT全文索引的。全文搜索引擎可以在不使用模板匹配操作的情况下查找单词或短语。
真题153:PHP连接MySQL的方法
1.建立连接MySQL服务器
在PHP中,首先要与MySQL服务器建立连接后才能连接数据库,用于连接MySQL服务器的函数是mysql_connect()函数,语法格式如下:
resource mysql_connect([string $server [, string $username [, string $password [, bool $new_link [, int $client_flags ]]]]])
如果使用同样的参数第二次调用mysql_connect()函数,那么将不会建立新连接,而将返回已经打开的连接标志。参数$new_link指定在这种情况下是否建立新的连接,值为TRUE表示建立新的连接,值为FALSE时返回已经建立连接的句柄,默认值为FALSE。
PHP还提供了另外一个用于连接MySQL服务器的函数:mysql_pconnect()。该函数用于建立一个与MySQL服务器的持久连接。
2.选择数据库
连接到服务器后,可以选择需要使用的数据库,使用mysql_select_db()函数,语法格式如下:
bool mysql_select_db(string $database_name [, resource $ link_identifier ])
说明:$database_name参数为要选择的数据库名,可选参数$lin_identifier 为一个连接标志符,如果没有指定,则使用上一个打开的连接。如果之前没有已经打开的连接,则本函数尝试调用一个无参数的 mysql_connect()函数来打开一个连接并使用。本函数运行成功返回TRUE,否则返回FALSE。
3.关闭连接
当一个已经打开的连接不再需要时,可以使用mysql_close()函数将其关闭,语法格式如下:
bool mysql_close([ resource $link_identifier ])
可选参数$link_identifier为指定的连接标志符,如果省略,则关闭上一个打开的连接。
【真题227】 以下代码的运行结果为( )。
<?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。
问题:如何进行MySQL优化?
SQL优化
执行缓慢的SQL语句能消耗数据库的70%~90%的CPU资源,而SQL语句独立于程序设计逻辑,相对于对程序源代码的优化,对SQL语句的优化在时间成本和风险上的代价都很低。SQL语句可以有不同的写法,下面分别介绍。
(1)在MySQL 5.5及其以下版本中避免使用子查询
例如,在MySQL 5.5版本里,若执行下面的SQL语句,则内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查内表T2。所以,当外表的数据很大时,查询速度就会非常慢。
SELECT * FROM T1 WHERE ID IN (SELECT ID FROM T2 WHERE NAME='xiaomaimiao');
在MySQL 5.6版本里,采用JOIN关联方式对其进行了优化,这条SQL会自动转换为
SELECT T1.* FROM T1 JOIN T2 ON T1.ID = T2.ID;
需要注意的是,该优化只针对SELECT有效,对UPDATE或DELETE子查询无效,故生产环境应避免使用子查询。
(2)避免函数索引
例如,下面的SQL语句会走全表扫描:
SELECT * FROM T WHERE YEAR(D) >= 2016;
由于MySQL不像Oracle那样支持函数索引,即使D字段有索引,也会直接全表扫描。应改为如下的SQL语句:
SELECT * FROM T WHERE D >= '2016-01-01';
(3)用IN来替换OR
低效查询:
SELECT * FROM T WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30;
高效查询:
SELECT * FROM T WHERE LOC_IN IN (10,20,30);
(4)在LIKE中双百分号无法使用到索引
SELECT * FROM t WHERE name LIKE '%de%';
SELECT * FROM t WHERE name LIKE 'de%';
在以上SQL语句中,第一句SQL无法使用索引,而第二句可以使用索引。目前只有MySQL 5.7及以上版本支持全文索引。
(5)读取适当的记录LIMIT M,N
SELECT * FROM t WHERE 1;
SELECT * FROM t WHERE 1 LIMIT 10;
(6)避免数据类型不一致
SELECT * FROM T WHERE ID = '19';
由于以上SQL中ID为数值型,所以应该去掉过滤条件中数值19的双引号:
SELECT * FROM T WHERE ID = 19;
(7)分组统计可以禁止排序
SELECT GOODS_ID,COUNT(*) FROM T GROUP BY GOODS_ID;
默认情况下,MySQL会对所有GROUP BY col1,col2...的字段进行排序。如果查询包括GROUP BY,那么想要避免排序结果的消耗,则可以指定ORDER BY NULL禁止排序,如下:
SELECT GOODS_ID,COUNT(*) FROM T GROUP BY GOODS_ID ORDER BY NULL;
(8)避免随机取记录
SELECT * FROM T1 WHERE 1=1 ORDER BY RAND() LIMIT 4;
由于MySQL不支持函数索引,所以以上SQL会导致全表扫描,可以修改为如下的SQL语句:
SELECT * FROM T1 WHERE ID >= CEIL(RAND()*1000) LIMIT 4;
(9)禁止不必要的ORDER BY排序
SELECT COUNT(1) FROM T1 JOIN T2 ON T1.ID = T2.ID WHERE 1 = 1 ORDER BY T1.ID DESC;
由于计算的是总量,所以没有必要去排序,可以去掉排序语句,如下:
SELECT COUNT(1) FROM T1 JOIN T2 ON T1.ID = T2.ID;
(10)尽量使用批量INSERT插入
下面的SQL语句可以使用批量插入:
INSERT INTO t (id, name) VALUES(1,'xiaolu');
INSERT INTO t (id, name) VALUES(2,'xiaobai');
INSERT INTO t (id, name) VALUES(3,'xiaomaimiao');
修改后的SQL语句:
INSERT INTO t (id, name) VALUES(1,'xiaolu'), (2,'xiaobai'),(3,'xiaomaimiao');
购买链接:京东购买
题目来自《PHP程序员面试笔试宝典》,里面涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书。
更多PHP面试笔试真题可以浏览:www.shuaiqi100.com
更多有趣有料的PHP面试笔试资料可以关注:“琉忆编程库”
或者浏览:www.shuaiqi100.com 获取。
PHP程序员面试笔试宝典下载:https://pan.baidu.com/s/1-ES2ZI3z5Lhv-zTKFmJDSQ