一種是innodb,一種是myisam,二者的主要區別是
①myisam不支持事務處理,而innoDB支持事務處理php
②myisam 不支持外鍵,innoDB支持外鍵html
③myisam支持全文檢索,而innoDB在MySQL5.6版本以後才支持全文檢索前端
④數據的存儲形式不同,mysiam表存放在三個文件:結構、索引、數據,innoDB存儲把結構存儲爲一個文件,索引和數據存儲爲一個文件mysql
⑤myisam在查詢和增長數據性能更優於innoDB,innoDB在批量刪除方面性能較高。git
⑥myisam支持表鎖,而innoDB支持行鎖github
mysql優化怎麼作的?redis
??
①設計角度:存儲引擎的選擇,字段類型選擇,範式算法
??
②功能角度:能夠利用mysql自身的特性,如索引,查詢緩存,碎片整理,分區、分表等sql
??
③sql語句的優化方面:儘可能簡化查詢語句,能查詢字段少就儘可能少查詢字段,優化分頁語句、分組語句等。數據庫
??
④部署大負載架構體系:數據庫服務器單獨出來,負載大時能夠採用主從複製,讀寫分離機制進行設計
??
⑤從硬件上升級數據庫服務器
單例模式
private static $_instance;
private function __construct(){}
private function __clone(){}
public static function get_instance(){}
接口安全方面是怎麼處理的
咱們當時是這麼作的,使用HTTP的POST方式,對固定參數+附加參數進行數字簽名,使用的是md5加密,好比:我想經過標題獲取一個信息,在客戶端使用 信息標題+日期+雙方約定好的一個key經過md5加密生成一個簽名(sign),而後做爲參數傳遞到服務器端,服務器端使用一樣的方法進行校驗,如何接受過來的sign和咱們經過算法算的值相同,證實是一個正常的接口請求,咱們纔會返回相應的接口數據。
用戶不登陸,怎麼直接加入購物車的
用戶在不登陸的狀況下,能夠把要購買商品的信息(如商品的ID,商品的價格、商品的sku_id,購買數量等關鍵數據)存到COOKIE裏面,當登錄的狀況下。把COOKIE裏面的內容存到數據庫,並清除cookie中的數據。
如何處理負載、高併發
一、HTML靜態化
其實你們都知道,效率最高、消耗最小的就是純靜態化的html頁面,因此咱們儘量使咱們的 網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。
二、圖片服務器分離
把圖片單獨存儲,儘可能減小圖片等大流量的開銷,能夠放在一些相關的平臺上,如騎牛等
三、數據庫集羣和庫表散列及緩存數據庫的併發鏈接爲100,一臺數據庫遠遠不夠,能夠從讀寫分離、主從複製,數據庫集羣方面來着手。另外儘可能減小數據庫的訪問,可使用緩存數據庫如memcache、redis。
四、鏡像:儘可能減小下載,能夠把不一樣的請求分發到多個鏡像端。
五、負載均衡:
Apache的最大併發鏈接爲1500,只能增長服務器,能夠從硬件上着手,如F5服務器。固然硬件的成本比較高,咱們每每從軟件方面着手。
echo(),print(),print_r()的區別
echo能夠一次輸出多個值,多個值之間用逗號分隔。echo是語言結構(language construct),而並非真正的函數,所以不能做爲表達式的一部分使用。
echo是php的內部指令,不是函數,無返回值。
print():函數print()打印一個值(它的參數),若是字符串成功顯示則返回true,不然返回false。只能打印出簡單類型變量的值(如int,string),有返回值
printf():源於C語言中的printf()。該函數輸出格式化的字符串。
print_r()和var_dump()
print_r()能夠把字符串和數字簡單地打印出來,而數組則以括起來的鍵和值得列表形式顯示,並以Array開頭。但print_r()輸出布爾值和NULL的結果沒有意義,由於都是打印"\n"。所以用var_dump()函數更適合調試。print_r是函數,能夠打印出比較複雜的變量(如數組,對象),有返回值
var_dump()判斷一個變量的類型與長度,並輸出變量的數值,若是變量有值輸的是變量的值並回返數據類型。此函數顯示關於一個或多個表達式的結構信息,包括表達式的類型與值。數組將遞歸展開值,經過縮進顯示其結構。
Linux基本命令,目錄結構
文件搜索?
find / -name file1?從?'/'開始進入根文件系統搜索文件和目錄?
locate \*.ps?尋找以?'.ps'結尾的文件?-先運行'updatedb'命令?
whereis halt?顯示一個二進制文件、源碼或man的位置?
which halt?顯示一個二進制文件或可執行文件的完整路徑?
磁盤空間?
df -h?顯示已經掛載的分區列表?
ls -lSr |more?以尺寸大小排列文件和目錄?
du -sh dir1?估算目錄?'dir1'已經使用的磁盤空間'?
下載、解壓
1)對於.tar結尾的文件?
tar -xf all.tar?
2)對於.gz結尾的文件?
gzip -d all.gz?
gunzip all.gz?
# zip all.zip *.jpg?
這條命令是將全部.jpg的文件壓縮成一個zip包?
# unzip all.zip?
這條命令是將all.zip中的全部文件解壓出來
下載命令
wget +?空格?+要下載文件的url路徑
魔術方法、魔術常量
1。__construct()
實例化對象時被調用,當__construct和以類名爲函數名的函數同時存在時,__construct將被調用,另外一個不被調用。
2。__destruct()
當刪除一個對象或對象操做終止時被調用。
3。__call()
對象調用某個方法,若方法存在,則直接調用;若不存在,則會去調用__call函數。
4。__get()
讀取一個對象的屬性時,若屬性存在,則直接返回屬性值;若不存在,則會調用__get函數。
5。__set()
設置一個對象的屬性時,若屬性存在,則直接賦值;若不存在,則會調用__set函數。
6。__toString()
打印一個對象的時被調用。如echo $obj;或print $obj;
7。__clone()
克隆對象時被調用。如:$t=new Test();$t1=clone $t;
8。__sleep()
serialize以前被調用。若對象比較大,想刪減一點東東再序列化,可考慮一下此函數。
9。__wakeup()
unserialize時被調用,作些對象的初始化工做。
10。__isset()
檢測一個對象的屬性是否存在時被調用。如:isset($c->name)。
11。__unset()
unset一個對象的屬性時被調用。如:unset($c->name)。
12。__set_state()
調用var_export時,被調用。用__set_state的返回值作爲var_export的返回值。
13。__autoload()
實例化一個對象時,若是對應的類不存在,則該方法被調用。
魔術常量:
1。__LINE__
返回文件中的當前行號。
2。__FILE__
返回文件的完整路徑和文件名。若是用在包含文件中,則返回包含文件名。自?PHP 4.0.2?起,__FILE__?老是包含一個絕對路徑,而在此以前的版本有時會包含一個相對路徑。
3。__FUNCTION__
返回函數名稱(PHP 4.3.0?新加)。自?PHP 5?起本常量返回該函數被定義時的名字(區分大小寫)。在PHP 4?中該值老是小寫字母的。
4。__CLasS__
返回類的名稱(PHP 4.3.0?新加)。自?PHP 5?起本常量返回該類被定義時的名字(區分大小寫)。在PHP 4?中該值老是小寫字母的。
5。__METHOD__
返回類的方法名(PHP 5.0.0?新加)。返回該方法被定義時的名字(區分大小寫)。
__set()當程序試圖寫入一個不存在或者不可見的成員變量時,__set()方法包含兩個參數,分別表示變量名稱和變量值,兩個參數都不可省略
__get()當程序試圖調用一個未定義或不可見的成員變量時,__get()方法有一個參數,表示要調用的變量名
__sleep()?經常使用於提交未提交的數據,或相似的清理操做若是有一些很大的對象,但不須要所有保存,這個功能就很好用。
__construct() ?在類實例化對象的同時執行該函數
__distruct()?在類實例化的對象銷燬時執行
__call()對象調用某個方法,若方法存在,則直接調用;若不存在,則會去調用__call函數。
__clone()克隆對象時被調用。如:$t=new Test();$t1=clone $t;
__toString()打印一個對象的時被調用。如echo $obj;或print $obj;
__isset()檢測一個對象的屬性是否存在時被調用。如:isset($c->name)。
__unset()unset一個對象的屬性時被調用。如:unset($c->name)。
__autoload()實例化一個對象時,若是對應的類不存在,則該方法被調用。
字符串反轉
給定字符串abcdef,寫出反轉函數,將字符串反轉爲fedcba.?
function?myStrReve($str){??
????
$len?=?strlen($str);??
????
$result?=?'';???
????
for($i?=?$len?-?1;?$i?>=0?;?$i--?){??
???????
?$result?.=?$str[$i];??
????
}?????
????
return?$result;??
}??
mysql共享鎖與排他鎖
mysql鎖機制分爲表級鎖和行級鎖,本文就和你們分享一下我對mysql中行級鎖中的共享鎖與排他鎖進行分享交流。
共享鎖又稱爲讀鎖,簡稱S鎖,顧名思義,共享鎖就是多個事務對於同一數據能夠共享一把鎖,都能訪問到數據,可是隻能讀不能修改。
排他鎖又稱爲寫鎖,簡稱X鎖,顧名思義,排他鎖就是不能與其餘所並存,如一個事務獲取了一個數據行的排他鎖,其餘事務就不能再獲取該行的其餘鎖,包括共享鎖和排他鎖,可是獲取排他鎖的事務是能夠對數據就行讀取和修改。
對於共享鎖你們可能很好理解,就是多個事務只能讀數據不能改數據,對於排他鎖你們的理解可能就有些差異,我當初就犯了一個錯誤,覺得排他鎖鎖住一行數據後,其餘事務就不能讀取和修改該行數據,其實不是這樣的。排他鎖指的是一個事務在一行數據加上排他鎖後,其餘事務不能再在其上加其餘的鎖。mysql InnoDB引擎默認的修改數據語句,update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,若是加排他鎖可使用select ...for update語句,加共享鎖可使用select ... lock in share mode語句。因此加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,但能夠直接經過select ...from...查詢數據,由於普通查詢沒有任何鎖機制
MySQL的四種事務隔離級別
https://www.cnblogs.com/huanongying/p/7021555.html
1、事務的基本要素(ACID)
一、原子性(Atomicity):事務開始後全部操做,要麼所有作完,要麼所有不作,不可能停滯在中間環節。事務執行過程當中出錯,會回滾到事務開始前的狀態,全部的操做就像沒有發生同樣。也就是說事務是一個不可分割的總體,就像化學中學過的原子,是物質構成的基本單位。
二、一致性(Consistency):事務開始前和結束後,數據庫的完整性約束沒有被破壞 。好比A向B轉帳,不可能A扣了錢,B卻沒收到。
三、隔離性(Isolation):同一時間,只容許一個事務請求同一數據,不一樣的事務之間彼此沒有任何干擾。好比A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉帳。
四、持久性(Durability):事務完成後,事務對數據庫的全部更新將被保存到數據庫,不能回滾。
2、事務的併發問題
一、髒讀:事務A讀取了事務B更新的數據,而後B回滾操做,那麼A讀取到的數據是髒數據
二、不可重複讀:事務 A 屢次讀取同一數據,事務 B 在事務A屢次讀取的過程當中,對數據做了更新並提交,致使事務A屢次讀取同一數據時,結果 不一致。
三、幻讀:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住知足條件的行,解決幻讀須要鎖表
3、MySQL事務隔離級別
事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交(read-uncommitted) 是 是 是
不可重複讀(read-committed) 否 是 是
可重複讀(repeatable-read) 否 否 是
串行化(serializable) 否 否 否
mysql默認的事務隔離級別爲repeatable-read
Mysql事務與redis事務的區別
默認狀態
MySQL:
MySQL會默認開啓一個事務,且缺省設置是自動提交,即,每成功執行一個SQL,一個事務就會立刻 COMMIT。因此不能Rollback。
Redis:
Redis默認不會開啓事務,即command會當即執行,而不會排隊。並不支持Rollback(詳情可見:Redis之坑:理解Redis事務 )
事務命令
mysql:
begin #顯式地開啓一個事務
commit #提交事務,對數據庫進行的全部寫操做變爲永久性的
rollback #結束用戶的事務,並撤銷正在進行的全部未提交的寫操做
redis支持簡單的事務:
multi #標記事務的開始
exec #執行事務的
commands隊列
discard #結束事務,並清除commands隊列
https://blog.csdn.net/github_26672553/article/details/82892233
主鍵索引和惟一索引的區別
主鍵建立後必定包含一個惟一性索引,惟一性索引並不必定就是主鍵。
惟一性索引列容許空值,而主鍵列不容許爲空值。
主鍵列在建立時,已經默認爲空值 + 惟一索引了。
主鍵能夠被其餘表引用爲外鍵,而惟一索引不能。
一個表最多隻能建立一個主鍵,但能夠建立多個惟一索引。
主鍵更適合那些不容易更改的惟一標識,如自動遞增列、身份證號等。
在 RBO 模式下,主鍵的執行計劃優先級要高於惟一索引。 二者能夠提升查詢的速度。
Mysql各類索引區別:
普通索引:最基本的索引,沒有任何限制
惟一索引:與"普通索引"相似,不一樣的就是:索引列的值必須惟一,但容許有空值。
主鍵索引:它 是一種特殊的惟一索引,不容許有空值。
全文索引:僅可用於 MyISAM 表,針對較大的數據,生成全文索引很耗時好空間。
組合索引:爲了更多的提升mysql效率可創建組合索引,遵循」最左前綴「原則。
mysql建立索引的原則
1.選擇惟一性索引
惟一性索引的值是惟一的,能夠更快速的經過該索引來肯定某條記錄。例如,學生表中學號是具備惟一性的字段。爲該字段創建惟一性索引能夠很快的肯定某個學生的信息。若是使用姓名的話,可能存在同名現象,從而下降查詢速度。
2.爲常常須要排序、分組和聯合操做的字段創建索引
常常須要ORDER BY、GROUP BY、DISTINCT和UNION等操做的字段,排序操做會浪費不少時間。若是爲其創建索引,能夠有效地避免排序操做。
3.爲常做爲查詢條件的字段創建索引
若是某個字段常常用來作查詢條件,那麼該字段的查詢速度會影響整個表的查詢速度。所以,爲這樣的字段創建索引,能夠提升整個表的查詢速度。
4.限制索引的數目
索引的數目不是越多越好。每一個索引都須要佔用磁盤空間,索引越多,須要的磁盤空間就越大。修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
5.儘可能使用數據量少的索引
若是索引的值很長,那麼查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文檢索須要的時間確定要比對CHAR(10)類型的字段須要的時間要多。
6.儘可能使用前綴來索引
若是索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。若是隻檢索字段的前面的若干個字符,這樣能夠提升檢索速度。
7.刪除再也不使用或者不多使用的索引
表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能再也不須要。數據庫管理員應當按期找出這些索引,將它們刪除,從而減小索引對更新操做的影響。
8 . 最左前綴匹配原則,很是重要的原則。
mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配,好比a 1=」」 and=」」 b=」2」 c=」「> 3 and d = 4 若是創建(a,b,c,d)順序的索引,d是用不到索引的,若是創建(a,b,d,c)的索引則均可以用到,a,b,d的順序能夠任意調整。
9 .=和in能夠亂序。
好比a = 1 and b = 2 and c = 3 創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式
10 . 儘可能選擇區分度高的列做爲索引。
區分度的公式是count(distinct col)/count(*),表示字段不重複的比例,比例越大咱們掃描的記錄數越少,惟一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就 是0,那可能有人會問,這個比例有什麼經驗值嗎?使用場景不一樣,這個值也很難肯定,通常須要join的字段咱們都要求是0.1以上,即平均1條掃描10條 記錄
11 .索引列不能參與計算,保持列「乾淨」。
好比from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,緣由很簡單,b+樹中存的都是數據表中的字段值,但進行檢索時,須要把全部元素都應用函數才能比較,顯然成本 太大。因此語句應該寫成create_time = unix_timestamp(’2014-05-29’);
12 .儘可能的擴展索引,不要新建索引。
好比表中已經有a的索引,如今要加(a,b)的索引,那麼只須要修改原來的索引便可
注意:選擇索引的最終目的是爲了使查詢的速度變快。上面給出的原則是最基本的準則,但不能拘泥於上面的準則。讀者要在之後的學習和工做中進行不斷的實踐。根據應用的實際狀況進行分析和判斷,選擇最合適的索引方式。
Mysql explain的每項說明
一、id
每一個被獨立執行的操做的標識,表示對象被操做的順序;id值大,先被執行;若是相同,執行順序從上到下。
若沒有子查詢和聯合查詢,id則都是1。Mysql會按照id從大到小的順序執行query,在id相同的狀況下,則從上到下執行。
二、select_type
查詢中每一個select子句的類型
(1)SIMPLE
(2)PRIMARY/UNION
(3)DEPENDENT UNION/UNIOIN RESULT
(4)SUBQUERY/DEPENDENT SUBQUERY
(5)DERIVED/MATERIALIZED
(6)UNCACHEABLE SUBQUERY/UNCACHEABLE UNION
三、table
名字,被操做的對象名稱,一般是表名,或者表的別名,或者一個爲查詢產生臨時表的標示符(如派生表、子查詢、集合)。
四、type
表明查詢執行計劃中表使用的鏈接方式。
鏈接操做類型及級別:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
通常來講,得保證查詢至少達到range級別,最好能達到ref。
五、partitions
匹配的分區信息(對於非分區表值爲NULL)。
六、possible_keys
備選的索引(列出可能被使用到的索引)
七、key
經優化器選定的索引;經常使用ANALYZE TABLE命令,可使優化器正確地選擇索引。若是沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
八、key_len
被優化器選定的索引鍵的長度,單位是字節。
九、ref
表示本行被操做的對象的參照對象(被參照的對象多是一個常量用const表示,也多是其餘表的key指向的對象)。
十、rows
查詢執行所掃描的元組個數(對於InnoDB,此值是估計值)。
十一、filtered
按照條件表上數據被過濾的元組個數的百分比,rows×filtered/100能夠求出過濾後的元組數即實際的元組數。
十二、Extra
(1)using where
(2)using temporary
(3)using filesort
(4)using index
(5)using join buffer
(6)impossible where
(7)select tables optimized away
(8)distinct
mysql索引的原理
一 索引原理
索引的目的在於提升查詢效率,與咱們查閱圖書所用的目錄是一個道理:先定位到章,而後定位到該章下的一個小節,而後找到頁數。類似的例子還有:查字典,查火車車次,飛機航班等
本質都是:經過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,咱們能夠老是用同一種查找方式來鎖定數據。
數據庫也是同樣,但顯然要複雜的多,由於不只面臨着等值查詢,還有範圍查詢(>、<、between、in)、模糊查詢(like)、並集查詢(or)等等。數據庫應該選擇怎麼樣的方式來應對全部的問題呢?咱們回想字典的例子,能不能把數據分紅段,而後分段查詢呢?最簡單的若是1000條數據,1到100分紅第一段,101到200分紅第二段,201到300分紅第三段......這樣查第250條數據,只要找第三段就能夠了,一會兒去除了90%的無效數據。但若是是1千萬的記錄呢,分紅幾段比較好?稍有算法基礎的同窗會想到搜索樹,其平均複雜度是lgN,具備不錯的查詢性能。但這裏咱們忽略了一個關鍵的問題,複雜度模型是基於每次相同的操做成原本考慮的。而數據庫實現比較複雜,一方面數據是保存在磁盤上的,另一方面爲了提升性能,每次又能夠把部分數據讀入內存來計算,由於咱們知道訪問磁盤的成本大概是訪問內存的十萬倍左右,因此簡單的搜索樹難以知足複雜的應用場景。
Mysql優化的思路?
Mysql的優化,大致能夠分爲三部分:索引的優化,sql語句的優化,表的優化
1.索引的優化
只要列中含有NULL值,就最好不要在此例設置索引,複合索引若是有NULL值,此列在使用時也不會使用索引
儘可能使用短索引,若是能夠,應該制定一個前綴長度
對於常常在where子句使用的列,最好設置索引,這樣會加快查找速度
對於有多個列where或者order by子句的,應該創建複合索引
對於like語句,以%或者‘-’開頭的不會使用索引,以%結尾會使用索引
儘可能不要在列上進行運算(函數操做和表達式操做)
儘可能不要使用not in和<>操做
2.sql語句的優化
查詢時,能不要*就不用*,儘可能寫全字段名
大部分狀況鏈接效率遠大於子查詢
多使用explain和profile分析查詢語句
查看慢查詢日誌,找出執行時間長的sql語句優化
多表鏈接時,儘可能小表驅動大表,即小表 join 大表
在千萬級分頁時使用limit
對於常用的查詢,能夠開啓緩存
3.表的優化
表的字段儘量用NOT NULL
字段長度固定的表查詢會更快
把數據庫的大表按時間或一些標誌分紅小表
將表分區
操做系統優化
sysbench 工具
1.測試CPU性能
2.測試IO讀寫性能
3.測試事務性能
數據庫系統參數優化
1.使用 show processlist命令長時間查看服務器負載狀況
2.開啓服務器慢查詢開關
3.減小臨時表使用,能夠EXPLAIN 語法查看 extra 是否爲 using temporary
@若是group by 的列沒有索引,會產生內部臨時表
@若是order by 與 group by爲不一樣列時,或多表聯查時 order by,group by 包含的列不是第一張表的列,會產生外部臨時表
@若是distinct 與 order by 一塊兒使用可能會產生臨時表
@若是用union合併查詢會用到臨時表
@若是表中數據過大,可能會把臨時錶轉存在磁盤上處理
數據表設計
1.表結構拆分,核心字段與非核心字段或長文本字段最好拆出單一張表
2.字段選取規則:整形->data,time->enum,char->varchar->text->blob
3.字段長度設定,夠用就行杜絕浪費
4.儘可能避免用NULL(),不利於索引查詢,要用特殊的字節來標註,佔有磁盤空間較大。
索引設計,myisam與innodb默認使用B-tree索引
1.建議創建單個索引,避免創建組合索引
2.索引值,或主鍵值應儘可能是連續增加的整型值,不是隨機值
3.要創建適當的索引對象,過多的索引會影響插入和更新速度,同時佔用內存
4.對於左前綴不易區分的列,要分析數據內容找出最容易區別的部分放在前面,(好比,要url倒過來存儲,後綴都不同)
5.索引碎片維護,長期的數據更改過程當中, 索引文件和數據文件,都將產生空洞,造成碎片
4.注意索引的左前綴原則,範圍截斷原則(or 條件,只要其中一個沒有都不會用索引)
創建組合索引index(a,b,c) 爲例:
語句
索引是否發揮做用
Where a=3
是,只使用了a列
Where a=3 and b=5
是,使用了a,b列
Where a=3 and b=5 and c=4
是,使用了abc
Where b=3 ?or ?where c=4
否
Where a=3 and c=4
a列能發揮索引,c不能
Where a=3 and b>10 and c=7
a能利用,b能利用, c不能利用 ? ? ? ? ? ? ? ? ? ? ??
同上,where a=3 and b like ‘xxxx%’ and c=7 ? ?
a能用,b能用,c不能用
創建多個單列索引index(a),index(b),index(c)
Where a=3
是,只使用了a列
Where a=3 and b=5
是,使用了a,b列
Where a=3 and b=5 and c=4
是,使用了abc
Where b=3 ?or ?where c=4
bc使用
Where a=3 and c=4
ac都使用
Where a=3 and b>10 and c=7
a能利用,b能利用, c不能利用 ? ? ? ? ? ? ? ? ? ? ? ?
同上,where a=3 and b like ‘xxxx%’ and c=7 ? ?
a能用,b用,c不能用
Mysql索引不生效場景總結
1. 跳過列,where a = 1 and c = 3,最多用到索引列a;where b = 2 and c = 3,一個也用不到,必須從最左列開始
2. 前面是範圍查詢,where a = 1 and b > 2 and c = 3,最多用到 a, b兩個索引列;
3. 順序顛倒,where c = 3 and b = 2 and a = 1,一個也用不到;
4. 索引列上使用了表達式,如where substr(a, 1, 3) = 'hhh',where a = a + 1,表達式是一大忌諱,再簡單mysql也不認。有時數據量不是大到嚴重影響速度時,通常能夠先查出來,好比先查全部有訂單記錄的數據,再在程序中去篩選以'cp1001'開頭的訂單,而不是寫sql過濾它;
5. 模糊匹配時,like '%a'
6. 若是 MySQL 估計使用索引比全表掃描更慢,則不使用索引。例如若是列key_part1 均勻分佈在 1 和 100 之間,下列查詢中使用索引就不是很好:SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90;
7. 用 or 分割開的條件,若是 or 前的條件中的列有索引,然後面的列中沒有索引,那麼涉及到的索引都不會被用到,必須兩個字段都得是索引才能使用到索引
8. 若是列類型是字符串,那麼必定記得在 where 條件中把字符常量值用引號引發來,不然的話即使這個列上有索引,MySQL 也不會用到的,由於,MySQL 默認把輸入的常量值進行轉換之後才進行檢索。以下面的例子中 company2 表中的 name字段是字符型的,可是 SQL 語句中的條件值 294 是一個數值型值,所以即使在 name 上有索引,MySQL 也不能正確地用上索引,而是繼續進行全表掃描;explain select * from company2 where name = 294\G; explain select * from company2 where name = '294'
9. 查看索引使用狀況 show status like 'Handler_read%';
10. show status like 'Com_%'; Com_select:執行 select 操做的次數,一次查詢只累加 1。Com_insert:執行 INSERT 操做的次數,對於批量插入的 INSERT 操做,只累加一次。Com_update:執行 UPDATE 操做的次數。Com_delete:執行 DELETE 操做的次數。
11. Innodb_rows_read:select 查詢返回的行數。Innodb_rows_inserted:執行 INSERT 操做插入的行數。Innodb_rows_updated:執行 UPDATE 操做更新的行數。Innodb_rows_deleted:執行 DELETE 操做刪除的行數。
12. Connections:試圖鏈接 MySQL 服務器的次數。Uptime:服務器工做時間。Slow_queries:慢查詢的次數
13. show processlist 命令查看當前 MySQL 在進行的線程,包括線程的狀態、是否鎖表等,能夠實時地查看 SQL 的執行狀況,同時對一些鎖表操做進行優化。
14. 查看索引使用狀況:show status like 'Handler_read%';
15. 按期分析和檢查表,若是感受分析表:本語句用於分析和存儲表的關鍵字分佈,分析的結果將可使得系統獲得準確的統計信息,使得 SQL 可以生成正確的執行計劃。若是用戶感受實際執行計劃並非預期的執行計劃,執行一次分析表可能會解決問題。 檢查表:能夠檢查表或視圖是否由錯誤(表刪除以後,視圖可能仍然存在);優化表:若是已經刪除了表的一大部分,或者若是已經對含有可變長度行的表(含有 VARCHAR、BLOB 或 TEXT 列的表)進行了不少更改,則應使用 OPTIMIZE TABLE 命令來進行表優化。 ANALYZE、CHECK、OPTIMIZE 執行期間將對錶進行鎖定,所以必定注意要在數據庫不繁忙的時候執行相關的操做。
16. show status like 'Handler_read%'; 查看'Handler_read_key ' 和 'Handler_read_rnd_next' 兩個值的大小來評判索引效果是否明顯;
sql語句優化
1.儘可能使用索引覆蓋,加快查詢速度(查詢只須要在索引文件上進行,不須要回行到磁盤再找數據)
2.在大數據範圍查找時,儘可能在索引覆蓋上面查找到須要的索引id,而後在經過id去查到對應的數據
3.儘可能減小查詢次數,能用業務邏輯處理的功能,都用算法處理。
4.利用explain來利用分析
hash索引爲何不能做爲數據存儲緣由:
1.hash函數計算後的結果,是隨機的,若是是在磁盤上放置數據,比主鍵爲id爲例, 那麼隨着id的增加, id對應的行,在磁盤上隨機放置
2.沒法對範圍查詢進行優化
3.沒法利用前綴索引
4.排序沒法優化
5.必須回行.就是說 經過索引拿到數據位置,必須回到表中取數據
工廠模式
工廠模式,工廠方法或者類生成對象,而不是在代碼中直接new。
使用工廠模式,能夠避免當改變某個類的名字或者方法以後,在調用這個類的全部的代碼中都修改它的名字或者參數。
1 Test1.php
2 <?php
3 class Test1{
4 static function test(){
5 echo __FILE__;
6 }
7 }
8
9 Factory.php
10 <?php
11 class Factory{
12 /*
13 * 若是某個類在不少的文件中都new ClassName(),那麼萬一這個類的名字
14 * 發生變動或者參數發生變化,若是不使用工廠模式,就須要修改每個PHP
15 * 代碼,使用了工廠模式以後,只須要修改工廠類或者方法就能夠了。
16 */
17 static function createDatabase(){
18 $test = new Test1();
19 return $test;
20 }
21 }
22
23 Test.php
24 <?php
25 spl_autoload_register('autoload1');
26
27 $test = Factory::createDatabase();
28 $test->test();
29 function autoload1($class){
30 $dir = __DIR__;
31 $requireFile = $dir."\\".$class.".php";
32 require $requireFile;
33 }
HTTP與HTTPS有什麼差別
一、HTTPS是加密傳輸協議,HTTP是名文傳輸協議;
二、HTTPS需求用到SSL證書,而HTTP不用;
三、HTTPS比HTTP更加安全,對查找引擎更友好,利於SEO
四、HTTPS規範端口443,HTTP規範端口80;
五、HTTPS基於傳輸層,HTTP基於使用層;
六、HTTPS在瀏覽器顯現綠色安全鎖,HTTP沒有顯現;
因爲HTTP協議傳輸的數據都是未加密的,頗有可能被人盜取或篡改,於是使用HTTP協議傳輸隱私信息十分不安全。
短信防刷
圖片驗證
單IP請求次數限制
手機號限制
一、時間限制:60秒後才能再次發送
從發送驗證碼開始,前端(客戶端)會進行一個60秒的倒數,在這一分鐘以內,用戶是沒法提交屢次發送信息的請求的。這種方法雖然使用得比較廣泛,可是卻不是很是有用,技術稍微好點的人徹底能夠繞過這個限制,直接發送短信驗證碼。
二、手機號限制:同一個手機號,24小時以內不可以超過5條
對使用同一個手機號碼進行註冊或者其餘發送短信驗證碼的操做的時候,系統能夠對這個手機號碼進行限制,例如,24小時只能發送5條短信驗證碼,超出限制則進行報錯(如:系統繁忙,請稍後再試)。然而,這也只可以避免人工手動刷短信而已,對於批量使用不一樣手機號碼來刷短信的機器,這種方法也是迫不得已的。
三、短信驗證碼限制:30分鐘以內發送同一個驗證碼
網上還有一種方法說:30分鐘以內,全部的請求,所發送的短信驗證碼都是同一個驗證碼。第一次請求短信接口,而後緩存短信驗證碼結果,30分鐘以內再次請求,則直接返回緩存的內容。對於這種方式,不是很清楚短信接口商會不會對發送緩存信息收取費用,若是有興趣能夠了解了解。
四、先後端校驗:提交Token參數校驗
這種方式比較少人說到,我的以爲能夠這種方法值得一試。前端(客戶端)在請求發送短信的時候,同時向服務端提交一個Token參數,服務端對這個Token參數進行校驗,校驗經過以後,再向請求發送短信的接口向用戶手機發送短信。
五、惟一性限制:微信產品,限制同一個微信ID用戶的請求數量
若是是微信的產品的話,能夠經過微信ID來進行識別,而後對同一個微信ID的用戶限制,24小時以內最多隻可以發送必定量的短信。
六、產品流程限制:分步驟進行
例如註冊的短信驗證碼使用場景,咱們將註冊的步驟分紅2步,用戶在輸入手機號碼並設置了密碼以後,下一步才進入驗證碼的驗證步驟。
七、圖形驗證碼限制:圖形驗證經過後再請求接口
用戶輸入圖形驗證碼並經過以後,再請求短信接口獲取驗證碼。爲了有更好的用戶體驗,也能夠設計成:一開始不須要輸入圖形驗證碼,在操做達到必定量以後,才須要輸入圖形驗證碼。具體狀況請根據具體場景來進行設計。
八、IP及Cookie限制:限制相同的IP/Cookie信息最大數量
使用Cookie或者IP,可以簡單識別同一個用戶,而後對相同的用戶進行限制(如:24小時內最多隻可以發送20條短信)。然而,Cookie可以清理、IP可以模擬,並且IP還會出現局域網相同IP的狀況,所以,在使用此方法的時候,應該根據具體狀況來思考。
九、短信預警機制,作好出問題以後的防禦
以上的方法並不必定可以徹底杜絕短信被刷,所以,咱們也應該作好短信的預警機制,即當短信的使用量達到必定量以後,向管理員發送預警信息,管理員能夠馬上對短信的接口狀況進行監控和防禦。
以上所說到的方式,或許不是很完美,可是能夠經過多個方式結合着來做使用,經過多個規則來下降短信被刷的風險。
(問羣裏的人)
php作APP接口時,如何保證接口的安全性?
一、當用戶登陸APP時,使用https協議調用後臺相關接口,服務器端根據用戶名和密碼時生成一個access_key,並將access_key保存在session中,將生成的access_key和session_id返回給APP端。
二、APP端將接收到的access_key和session_id保存起來
三、當APP端調用接口傳輸數據時,將所傳數據和access_key使用加密算法生成簽名signature,並將signature和session_id一塊兒發送給服務器端。
四、服務器端接收到數據時,使用session_id從session中獲取對應的access_key,將access_key和接收到的數據使用同一加密算法生成對應signature,若是生成的簽名和接收到的signature相同時,則代表數據合法
oauth2.0
https://www.cnblogs.com/flashsun/p/7424071.html
mysql獲取版本號
select versio();
mysql獲取用戶名和主機名組合函數
select user(),current_user(), system_user();
查詢mysq數據庫性能參數
show status like ‘value’;
其中value是參數值經常使用以下:
connections :鏈接mysql服務器次數;
uptime: mysql 服務器上線時間;
slow queries: 慢查詢次數
com_select: 查詢操做的次數
com_insert: 查詢插入的次數
com_delete:updata....
舉例子:show status like 'slow_queries';
//字符串「open_door」 轉換成 「OpenDoor」、」make_by_id」 轉換成 」MakeById」。
function str_change($str) {
$strr = str_replace('_','',$str);
$strr = ucwords($strr);//將單詞首字母變大寫
$strr = str_replace(' ','',$strr);
return $strr;
}
$aa = str_change('open_door');
var_dump($aa);
php數組函數
array
array_combine
array_merge
array_chunk
array_filp
array_keys
array_push 插入末尾
array_pop 刪除最後一個
array_shift 刪除第一個
array_unshift 開頭插入
array_column 返回輸入數組中某個單一列的值。
array_key_exists 判斷某個數組中是否存在指定的key
array_unique 去重
常見的HTTP相應狀態碼
返回的狀態
1xx:指示信息--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操做
4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現
5xx:服務器端錯誤--服務器未能實現合法的請求
200:請求被正常處理
204:請求被受理但沒有資源能夠返回
206:客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法,相應報文中經過Content-Range指定範圍的資源。
301:永久性重定向
302:臨時重定向
303:與302狀態碼有類似功能,只是它但願客戶端在請求一個URI的時候,能經過GET方法重定向到另外一個URI上
304:發送附帶條件的請求時,條件不知足時返回,與重定向無關
307:臨時重定向,與302相似,只是強制要求使用POST方法
400:請求報文語法有誤,服務器沒法識別
401:請求須要認證
403:請求的對應資源禁止被訪問
404:服務器沒法找到對應資源
500:服務器內部錯誤
503:服務器正忙
echo "今天:".date("Y-m-d")."<br>"; echo "昨天:".date("Y-m-d",strtotime("-1 day")), "<br>"; echo "明天:".date("Y-m-d",strtotime("+1 day")). "<br>"; echo "一週後:".date("Y-m-d",strtotime("+1 week")). "<br>"; echo "一週零兩天四小時兩秒後:".date("Y-m-d G:H:s",strtotime("+1 week 2 days 4 hours 2 seconds")). "<br>"; echo "下個星期四:".date("Y-m-d",strtotime("next Thursday")). "<br>"; echo "上個週一:".date("Y-m-d",strtotime("last Monday"))."<br>"; echo "一個月前:".date("Y-m-d",strtotime("last month"))."<br>"; echo "一個月後:".date("Y-m-d",strtotime("+1 month"))."<br>"; echo "十年後:".date("Y-m-d",strtotime("+10 year"))."<br>";