PHP和MySQL愛考的10道題php
來自《PHP程序員面試筆試寶典》,涵蓋了近三年了各大型企業常考的PHP面試題,針對面試題提取出來各類面試知識也涵蓋在了本書。html
數據庫優化的過程可使用如下的方法進行:mysql
1)選取最適用的字段屬性,儘量減小定義字段長度,儘可能把字段設置NOT NULL,例如'省份、性別',最好設置爲ENUM。程序員
2)使用鏈接(JOIN)來代替子查詢。web
① 刪除沒有任何訂單客戶:DELETE FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)。面試
② 提取全部沒有訂單客戶:SELECT FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)。sql
③ 提升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。
2、選擇正確的存儲引擎?
在MySQL中有兩個存儲引擎:MyISAM和InnoDB,每一個引擎都有利有弊。
MyISAM適合於一些須要大量查詢的應用,但其對於有大量寫操做的支持並非很好。甚至只是須要update一個字段,整個表都會被鎖起來,而其餘進程,就算是讀進程都沒法操做直到讀操做完成。另外,MyISAM 對於 SELECT COUNT(*) 這類的計算是超快無比的。
InnoDB 的趨勢會是一個很是複雜的存儲引擎,對於一些小的應用,它會比 MyISAM 還慢。可是它支持「行鎖」,因而在寫操做比較多的時候,會更優秀。而且,它還支持更多的高級應用,例如事務。
3、【真題231】 用什麼方法檢查PHP腳本的執行效率(一般是腳本執行時間)和數據庫SQL的效率(一般是數據庫query時間),並定位和分析腳本執行和數據庫查詢的瓶頸所在?
參考答案:檢查PHP腳本的執行效率的方法以下:能夠在檢查的代碼開頭記錄一個時間,而後在代碼的結尾也記錄一個時間,結尾時間減去開頭時間取這個時間的差值,從而檢查PHP的腳本執行效率,記錄時間可使用microtime()函數。
檢查數據庫SQL的效率的方法以下:能夠經過explain顯示MySQL如何使用索引來處理select語句及鏈接表,幫助選擇更好的索引和寫出更優化的查詢語句。而後啓用slow query log記錄慢查詢,經過查看SQL的執行時間和效率來定位分析腳本執行的問題和瓶頸所在。
4、 如下代碼的運行結果爲( )。
<?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。
5、考慮以下數據表和查詢,如何添加索引能提升查詢速度?( )
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設索引則能使排序更快。
6、 如何高效操做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)記得備份。數據庫必須進行備份,常見的有主從、主主數據庫等系統架構形式。
7、【真題222】 如下說法正確的是( )。
A.使用索引能加快插入數據的速度
B.良好的索引策略有助於防止跨站攻擊
C.應當根據數據庫的實際應用合理設計索引
D.刪除一條記錄將致使整個表的索引被破壞
參考答案:C。
分析:索引的做用主要是幫助數據庫快速查找到對應的數據,並不能加快插入數據的速度,因此,選項A錯誤。
索引不可以幫助防止跨站攻擊,因此,選項B錯誤。
建立合理的索引須要分析數據庫的實際用途並找出它的弱點。優化腳本中的冗餘查詢一樣也能提升數據庫效率。索引是佔用物理空間的,因此在實際的應用中是要合理設計使用索引的。因此,選項C正確。
索引是一種表結構,刪除一條數據也不會影響到整個表的索引,而且索引不必定是數字,也能夠是字符串。因此,選項D錯誤。
8、如何對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 #馬上生效
9、什麼是數據庫權限?
關於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.%';
10、【真題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