select?*?from?(
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供獻(xiàn)縣網(wǎng)站建設(shè)、獻(xiàn)縣做網(wǎng)站、獻(xiàn)縣網(wǎng)站設(shè)計(jì)、獻(xiàn)縣網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、獻(xiàn)縣企業(yè)網(wǎng)站模板建站服務(wù),10年獻(xiàn)縣做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
select?id,num,rank?from?(
select?heyf_tmp.id,heyf_tmp.num,@rownum:=@rownum+1?,
if(@pdept=heyf_tmp.id,@rank:=@rank+1,@rank:=1)?as?rank,
@pdept:=heyf_tmp.id
from?(
select?id,num?from?(SELECT
t.OPERATE_LOG_USER_ID?AS?id,
t.OPERATE_SEARCH_WORD?AS?word,
COUNT(*)AS?num
FROM
skp_operate_log?AS?t
WHERE
t.OPERATE_LOG_TIME
GROUP?BY
id,
word
ORDER?BY
num?DESC)tt?order?by?id?asc?,num?desc
)?heyf_tmp?,(select?@rownum?:=0?,?@pdept?:=?null?,@rank:=0)?a?)?result
)ttt
where?rank?in(1,2)
首先搭建一個(gè)PHP環(huán)境,我用的wamp
然后比如你的數(shù)據(jù)庫(kù)位置是本地localhost
數(shù)據(jù)庫(kù)用戶名是root
數(shù)據(jù)庫(kù)密碼是123456
數(shù)據(jù)庫(kù)名是mydb
數(shù)據(jù)庫(kù)里有個(gè)表mytab
有3個(gè)字段
id(主鍵) name sno
1 張三 123
2 李四 456
然后在項(xiàng)目根目錄,新建一個(gè)文件:index.php
?php
//連接數(shù)據(jù)庫(kù)
$con=mysqli_connect("localhost","root","123456","mydb");
//SQL語(yǔ)句
$sql="select * from mytab;";
//執(zhí)行SQL語(yǔ)句,結(jié)果保存到$arr
$obj=mysqli_query($con,$sql);
$arr=mysqli_num_rows($result);
?
html
head
meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
title實(shí)現(xiàn)最簡(jiǎn)單的php網(wǎng)頁(yè)+mysql查詢功能/title
/head
body
?php
echo "pre";
print_r($obj);
?
/body
/html
之后就能夠看到結(jié)果了
表結(jié)構(gòu)如下
id
uname
upwd
isdelete
注意:需要對(duì)密碼進(jìn)行加密。
如果使用md5加密,則密碼包含32個(gè)字符。
如果使用sha1加密,則密碼包含40個(gè)字符,這里使用這種方式。
md5加密方式:
sha1加密方式:
創(chuàng)建表
1)創(chuàng)建testLogin.py文件,引入hashlib模塊、MysqlHelper模塊。
2)接收輸入。
3)根據(jù)用戶名查詢,如果未查到則提示用戶名不存在。
4)如果查到則匹配密碼是否相等,如果相等則提示登錄成功,如果不相等則提示密碼錯(cuò)誤。
一個(gè)事務(wù)要更新一行,如果剛好有另外一個(gè)事務(wù)擁有這一行的行鎖,會(huì)被鎖住,進(jìn)入等待狀態(tài)。既然進(jìn)入了等待狀態(tài),那么等到這個(gè)事務(wù)自己獲取到行鎖要更新數(shù)據(jù)的時(shí)候,它讀到的值又是什么呢?
可重復(fù)讀隔離級(jí)別下,事務(wù)在啟動(dòng)的時(shí)候就“拍了個(gè)整個(gè)庫(kù)的快照”。如果一個(gè)庫(kù)有100G,那么我啟動(dòng)一個(gè)事務(wù),MySQL就要拷?100G的數(shù)據(jù)出來(lái),這個(gè)過(guò)程得多慢啊。但是平時(shí)事務(wù)執(zhí)行起來(lái)卻是非??斓摹2皇侨靠截惓鰜?lái)那是怎么實(shí)現(xiàn)的呢?
InnoDB里面每個(gè)事務(wù)有一個(gè)唯一的事務(wù)ID,叫作transaction id。它是在事務(wù)開(kāi)始的時(shí)候向InnoDB的事務(wù)系統(tǒng)申請(qǐng)的,是按申請(qǐng)順序嚴(yán)格遞增的。
而每行數(shù)據(jù)也都是有多個(gè)版本的。每次事務(wù)更新數(shù)據(jù)的時(shí)候,都會(huì)生成一個(gè)新的數(shù)據(jù)版本,并且把transaction id賦值給這個(gè)數(shù) 據(jù)版本的事務(wù)ID,記為row trx_id。同時(shí),舊的數(shù)據(jù)版本要保留,并且在新的數(shù)據(jù)版本中,能夠有信息可以直接拿到它。
數(shù)據(jù)表中的一行記錄,其實(shí)可能有多個(gè)版本(row),每個(gè)版本有自己的row trx_id。
圖中虛線框里是同一行數(shù)據(jù)的4個(gè)版本,當(dāng)前最新版本是V4,k的值是22,它是被transaction id 為25的事務(wù)更新的,因此它的row trx_id也是25。語(yǔ)句更新會(huì)生成undo log(回滾日志),圖中的三個(gè)虛線箭頭,就是undo log。
按照可重復(fù)讀的定義,一個(gè)事務(wù)啟動(dòng)的時(shí)候,能夠看到所有已經(jīng)提交的事務(wù)結(jié)果。但是之后,這個(gè)事務(wù)執(zhí)行期間,其他事務(wù)的更新對(duì)它不可?。
一個(gè)事務(wù)只需要在啟動(dòng)的時(shí)候聲明說(shuō),“以我啟動(dòng)的時(shí)刻為準(zhǔn),如果一個(gè)數(shù)據(jù)版本是在我啟動(dòng)之前生成的,就認(rèn);如果是我啟動(dòng)以后才生成的,我就不認(rèn),我必須要找到它的上一個(gè)版本”。
如果“上一個(gè)版本”也不可?,那就得繼續(xù)往前找。如果是這個(gè)事務(wù)自己更新的數(shù)據(jù),它自己還是要認(rèn)的。
在實(shí)現(xiàn)上, InnoDB為每個(gè)事務(wù)構(gòu)造了一個(gè)數(shù)組,用來(lái)保存這個(gè)事務(wù)啟動(dòng)瞬間,當(dāng)前正在“活躍”的所有事務(wù)ID?!盎钴S”指的就 是,啟動(dòng)了但還沒(méi)提交。數(shù)組里面事務(wù)ID的最小值記為低水位,當(dāng)前系統(tǒng)里面已經(jīng)創(chuàng)建過(guò)的事務(wù)ID的最大值加1記為高水位。 這個(gè)視圖數(shù)組和高水位,就組成了當(dāng)前事務(wù)的一致性視圖(read-view)。而數(shù)據(jù)版本的可?性規(guī)則,就是基于數(shù)據(jù)的row trx_id和這個(gè)一致性視圖的對(duì)比結(jié)果得到的。
InnoDB利用了“所有數(shù)據(jù)都有多個(gè)版本”的這個(gè)特性,實(shí)現(xiàn)了“秒級(jí)創(chuàng)建快照”的能力。
回到我們最開(kāi)始的表格,看看最后執(zhí)行的結(jié)果是多少。做如下假設(shè):
事務(wù)A的視圖數(shù)組就是[99,100], 事務(wù)B的視圖數(shù)組是[99,100,101], 事務(wù)C的視圖數(shù)組是[99,100,101,102]。為了簡(jiǎn)化分析,我先把其他干擾語(yǔ)句去掉,只畫(huà)出跟事務(wù)A查詢邏輯有關(guān)的操作:
第一個(gè)有效更新是事務(wù)C,把數(shù)據(jù)從(1,1)改成了(1,2)。這時(shí)候,這個(gè)數(shù)據(jù)的最新版本的row trx_id是102,而90這個(gè)版本已經(jīng)成為了歷史版本。 第二個(gè)有效更新是事務(wù)B,把數(shù)據(jù)從(1,2)改成了(1,3)。這時(shí)候,這個(gè)數(shù)據(jù)的最新版本(即row trx_id)是101,而102又成為了歷史版本。
事務(wù)B的update語(yǔ)句,如果按照一致性讀,好像結(jié)果不對(duì)哦?
事務(wù)B的視圖數(shù)組是先生成的,之后事務(wù)C才提交,不是應(yīng)該看不?(1,2)嗎,怎么能算出(1,3)來(lái)?
事務(wù)B在更新之前查詢一次數(shù)據(jù),這個(gè)查詢返回的k的值確實(shí)是1。 但是,當(dāng)它要去更新數(shù)據(jù)的時(shí)候,就不能再在歷史版本上更新了,否則事務(wù)C的更新就丟失了。因此,事務(wù)B此時(shí)的set k=k+1是在(1,2)的基礎(chǔ)上進(jìn)行的操作。 所以,這里就用到了這樣一條規(guī)則:更新數(shù)據(jù)都是先讀后寫(xiě)的,而這個(gè)讀,只能讀當(dāng)前的值,稱為 “當(dāng)前讀” ( current read )。
在更新的時(shí)候,當(dāng)前讀拿到的數(shù)據(jù)是(1,2),更新后生成了新版本的數(shù)據(jù)(1,3),這個(gè)新版本的row trx_id是101。
所以,在執(zhí)行事務(wù)B查詢語(yǔ)句的時(shí)候,一看自己的版本號(hào)是101,最新數(shù)據(jù)的版本號(hào)也是101,是自己的更新,可以直接使用, 所以查詢得到的k的值是3。
select語(yǔ)句如果加鎖,也是當(dāng)前讀。
如果把事務(wù)A的查詢語(yǔ)句select * from t where id=1修改一下,加上lock in share mode 或 for update,也都可以讀到版本號(hào)是101的數(shù)據(jù),返回的k的值是3。下面這兩個(gè)select語(yǔ)句,就是分別加了讀鎖(S鎖,共享鎖)和寫(xiě)鎖(X鎖,排他鎖)。
事務(wù)C’的不同是,更新后并沒(méi)有?上提交,在它提交前,事務(wù)B的更新語(yǔ)句先發(fā)起了。前面說(shuō)過(guò)了,雖然事務(wù)C’還沒(méi)提交,但是(1,2)這個(gè)版本也已經(jīng)生成了,并且是當(dāng)前的最新版本。那么,事務(wù)B的更新語(yǔ)句會(huì)怎么處理呢?
兩階段鎖協(xié)議,事務(wù)C’沒(méi)提交,也就是說(shuō)(1,2)這個(gè)版本上的寫(xiě)鎖還沒(méi)釋放。 而事務(wù)B是當(dāng)前讀,必須要讀最新版本,而且必須加鎖,因此就被鎖住了,必須等到事務(wù)C’釋放這個(gè)鎖,才能繼續(xù)它的當(dāng)前讀。
回到最初的問(wèn)題,事務(wù)的可重復(fù)讀的能力是怎么實(shí)現(xiàn)的?
MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),由瑞典MySQL AB 公司開(kāi)發(fā),目前屬于 Oracle 旗下產(chǎn)品。MySQL 是最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)之一,在 WEB 應(yīng)用方面,MySQL是最好的 RDBMS (Relational Database Management System,關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)) 應(yīng)用軟件。
MySQL是一種關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng),關(guān)系數(shù)據(jù)庫(kù)將數(shù)據(jù)保存在不同的表中,而不是將所有數(shù)據(jù)放在一個(gè)大倉(cāng)庫(kù)內(nèi),這樣就增加了速度并提高了靈活性。
MySQL所使用的 SQL 語(yǔ)言是用于訪問(wèn)數(shù)據(jù)庫(kù)的最常用標(biāo)準(zhǔn)化語(yǔ)言。MySQL 軟件采用了雙授權(quán)政策,分為社區(qū)版和商業(yè)版,由于其體積小、速度快、總體擁有成本低,尤其是開(kāi)放源碼這一特點(diǎn),一般中小型網(wǎng)站的開(kāi)發(fā)都選擇 MySQL 作為網(wǎng)站數(shù)據(jù)庫(kù)。
由于其社區(qū)版的性能卓越,搭配 PHP 和 Apache 可組成良好的開(kāi)發(fā)環(huán)境。
由于MySQL是開(kāi)放源碼軟件,對(duì)于一般的個(gè)人使用者和中小型企業(yè)來(lái)說(shuō),MySQL提供的功能綽綽有余,可以大大降低開(kāi)發(fā)成本。
Linux作為操作系統(tǒng),Apache 或Nginx作為 Web 服務(wù)器,MySQL 作為數(shù)據(jù)庫(kù),PHP/Perl/Python作為服務(wù)器端腳本解釋器。由于這四個(gè)軟件都是免費(fèi)或開(kāi)放源碼軟件(FLOSS),因此使用這種方式不用花一分錢(除開(kāi)人工成本)就可以建立起一個(gè)穩(wěn)定、免費(fèi)的網(wǎng)站系統(tǒng),被業(yè)界稱為“LAMP“或“LNMP”組合。