我前幾天有一個(gè)面試,面試題就是有這樣一道題。先把自己的思路說(shuō)一下,因?yàn)樾畔⒘糠浅5拇螅晕也捎昧朔直恚殖?4張表,每個(gè)小時(shí)一張,雖然凌晨時(shí)刻的表可能很少數(shù)據(jù),但這樣sum字段的問(wèn)題就容易解決了,我理解的sum字段是一個(gè)小時(shí)同一個(gè)用戶在相同的環(huán)境的登陸次數(shù)。這樣理解不知對(duì)否,請(qǐng)網(wǎng)友自行甄辨。然后我通過(guò)PHP中的fgets函數(shù)一行一行的數(shù)據(jù)取出,入表。實(shí)驗(yàn)了幾萬(wàn)條數(shù)據(jù)是沒(méi)有問(wèn)題的,但是上億條數(shù)據(jù)可能夠嗆。這一點(diǎn)也請(qǐng)網(wǎng)友注意,我也是新手。只是看到這里沒(méi)有答案,給大家一個(gè)參考。廢話不多,看流程:
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、重慶小程序開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了鐘樓免費(fèi)建站歡迎大家使用!
日志文件(access.log)格式:
200?/alipeng.gif?zoneid=2bannerid=44clentid=6materialid=64redirect=http%3a%2f%2f;time=1384444800.832ip=127.0.0.1user_agent=Mozilla/5.0?(X11;?Linux?x86_64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/31.0.1650.48?Safari/537.36utrace=a6dbdd2f6a37b946165b7ae98dcd4f79
502?/alipeng.gif?zoneid=2bannerid=44clentid=6materialid=64redirect=http%3a%2f%2f;time=1384444800.904ip=127.0.0.1user_agent=Mozilla/5.0?(X11;?Linux?x86_64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/31.0.1650.48?Safari/537.36utrace=a6dbdd2f6a37b946165b7ae98dcd4f79
配置文件cfg.php:
define(HOST,'localhost');//主機(jī)名
define(USER,'root');//數(shù)據(jù)庫(kù)賬號(hào)
define(PASS,'111111');//數(shù)據(jù)庫(kù)密碼
define(DBNAME,'test');//所用的數(shù)據(jù)庫(kù)
define(CHARSET,'utf8');//使用的字符集
具體代碼test.php:
?php
header("content-type:text/html;charset=utf-8");
require?'./cfg.php';
$link?=?mysql_connect(HOST,USER,PASS)?or?die('連接數(shù)據(jù)庫(kù)失敗');
//程序中自動(dòng)建庫(kù)和建表,這樣一定程度上拖慢了程序的速度
//創(chuàng)建數(shù)據(jù)庫(kù)
$crdb="create?database?if?not?exists?".DBNAME;
if(!mysql_query($crdb)){
die('創(chuàng)建數(shù)據(jù)庫(kù)失敗');
}
//鏈接數(shù)據(jù)庫(kù)
mysql_select_db(DBNAME)?or?die('選擇數(shù)據(jù)庫(kù)失敗');
mysql_set_charset(CHARSET);
//因?yàn)閿?shù)據(jù)量很大我將數(shù)據(jù)按小時(shí)分表,分成24個(gè)表,每小時(shí)一個(gè)表,這樣num字段的值也好做統(tǒng)計(jì)
//數(shù)據(jù)循環(huán)建表
for($i=0;$i24;$i++){
if($i10){
$tbhz='0'.$i;//如果前10張表,表后綴應(yīng)該是00-09
}else{
$tbhz=$i;
}
$ctbsql="create?table?if?not?exists?logininfo_{$tbhz}(
id?int?not?null?auto_increment?primary?key,
zoneid?int?not?null?default?0,
bannerid?int?not?null?default?0,
clentid?int?not?null?default?0,
materialid?int?not?null?default?0,
redirect?char(200)?not?null?default?'',
time?char(16)?not?null?default?'',
user_agent?char(200)?not?null?default?'',
utrace?char(32)?not?null?default?'',
sum?int?not?null?default?0
)TYPE=MyISAM?DEFAULT?CHARACTER?SET?utf8?COLLATE?utf8_general_ci";
mysql_query($ctbsql);
}
//打開(kāi)文件
$file=fopen("./access.log",'r')?or?die("打開(kāi)文件失敗");
//對(duì)文件內(nèi)容進(jìn)行循環(huán),直到文件末尾才停止
while?(!feof($file)){
//每次讀取一行
$line?=?fgets($file,1024);
//狀態(tài)是200的進(jìn)行寫(xiě)入數(shù)據(jù)庫(kù)操作
if(preg_match('/^200/',$line)){
$pinfo=parse_url($line);//url信息
$ext=$pinfo['query'];//取得傳遞的各個(gè)參數(shù)
$parray=explode('',$ext);//根據(jù)分解為數(shù)組
//因?yàn)榉纸鉃閿?shù)組后并不是要的值,所以要對(duì)值進(jìn)行一次截取,將等號(hào)及等號(hào)左邊的都去掉
foreach($parray?as?$val){
$narray[]=ltrim(strstr($val,'='),'=');
}
$narray[8]=rtrim($narray[8],'_');
//截取時(shí)間的秒數(shù)
$getmun=substr($parray[5],5,10);
$time=date('Y-m-d?H',$getmun);//將秒數(shù)轉(zhuǎn)化為時(shí)間類(lèi)型。
//得到表后綴
$tbhz=date('H',$getmun);
$sql="insert?into?logininfo_{$tbhz}?values(null,'{$narray[0]}','{$narray[1]}','{$narray[2]}','{$narray[3]}','{$narray[4]}','{$time}','{$narray[7]}','{$narray[8]}',0)";
//echo?$sql;
$res=mysql_query($sql);//執(zhí)行插入
if(!$res?||?!mysql_affected_rows()0){
die('寫(xiě)入數(shù)據(jù)庫(kù)失敗');
}
unset($narray);//循環(huán)一次將narray銷(xiāo)毀,為下一次循環(huán)做準(zhǔn)備
//var_dump(parse_url($line)['query']);
}
}
fclose($file);//關(guān)閉
//因?yàn)閟um字段還是0,下面代碼段需要處理sum字段的值
//24張表循環(huán)處理
for($i=0;$i24;$i++){
if($i10){
$tbhz='0'.$i;//如果前10張表,表后綴應(yīng)該是00-09
}else{
$tbhz=$i;
}
//該sql語(yǔ)句是把同一個(gè)小時(shí)內(nèi),并且符合條件相等的登陸的總次數(shù)和需要的登陸信息查出,為下面修改sum做準(zhǔn)備
$sql="SELECT?COUNT('zoneid')?AS?sum,zoneid,bannerid,clentid,materialid,redirect,user_agent,utrace?FROM?logininfo_{$tbhz}?GROUP?BY?zoneid,bannerid,clentid,materialid,redirect,user_agent,utrace";
//發(fā)送查詢sql
$res=mysql_query($sql);
if($res??mysql_num_rows($res)0){
while($row=mysql_fetch_assoc($res)){
//修改sum字段,即同一小時(shí)內(nèi)的登陸次數(shù)
$upsql="update?logininfo_{$tbhz}?set?sum='{$row['sum']}'?where?zoneid='{$row['zoneid']}'?and?bannerid='{$row['bannerid']}'?and?clentid='{$row['clentid']}'?and?materialid='{$row['materialid']}'?and?redirect='{$row['redirect']}'?and?user_agent='{$row['user_agent']}'?and?utrace='{$row['utrace']}'";
//發(fā)送修改sql,執(zhí)行修改sum
$upres=mysql_query($upsql);
if(!$upres){
die('修改登陸sum失敗');
}
}
}
}
echo?'數(shù)據(jù)成功入表';
使用說(shuō)明:
將配置文件cfg.php中的連接數(shù)據(jù)庫(kù)賬號(hào)、密碼修改為自己本機(jī)的(默認(rèn)新增的庫(kù)名是test)
直接運(yùn)行test1.php
理論上是可以的,但效率上就有問(wèn)題了,這么大量的數(shù)據(jù)一般不會(huì)放一張表里面,都會(huì)考慮分表,然后考慮索引、數(shù)據(jù)庫(kù)主從、服務(wù)器配置等,提高查詢效率php+mysql可以處理億級(jí)的數(shù)據(jù)嗎
下面通過(guò)創(chuàng)建100張表來(lái)演示下1億條數(shù)據(jù)的分表過(guò)程,具體請(qǐng)看下文代碼。
當(dāng)數(shù)據(jù)量猛增的時(shí)候,大家都會(huì)選擇庫(kù)表散列等等方式去優(yōu)化數(shù)據(jù)讀寫(xiě)速度。筆者做了一個(gè)簡(jiǎn)單的嘗試,1億條數(shù)據(jù),分100張表。具體實(shí)現(xiàn)過(guò)程如下:
首先創(chuàng)建100張表:
$i=0;
while($i=99){
echo
"$newNumber
\r\n";
$sql="CREATE
TABLE
`code_".$i."`
(
`full_code`
char(10)
NOT
NULL,
`create_time`
int(10)
unsigned
NOT
NULL,
PRIMARY
KEY
(`full_code`),
)
ENGINE=MyISAM
DEFAULT
CHARSET=utf8";
mysql_query($sql);
$i++;
下面說(shuō)一下我的分表規(guī)則,full_code作為主鍵,我們對(duì)full_code做hash
函數(shù)如下:
$table_name=get_hash_table('code',$full_code);
function
get_hash_table($table,$code,$s=100){
$hash
=
sprintf("%u",
crc32($code));
echo
$hash;
$hash1
=
intval(fmod($hash,
$s));
return
$table."_".$hash1;
}
這樣插入數(shù)據(jù)前通過(guò)get_hash_table獲取數(shù)據(jù)存放的表名。
最后我們使用merge存儲(chǔ)引擎來(lái)實(shí)現(xiàn)一張完整的code表
CREATE
TABLE
IF
NOT
EXISTS
`code`
(
`full_code`
char(10)
NOT
NULL,
`create_time`
int(10)
unsigned
NOT
NULL,
INDEX(full_code)
)
TYPE=MERGE
UNION=(code_0,code_1,code_2.......)
INSERT_METHOD=LAST
;
這樣我們通過(guò)select
*
from
code就可以得到所有的full_code數(shù)據(jù)了。
以上介紹就是本文的全部?jī)?nèi)容,希望對(duì)大家有所幫助。
名稱欄目:PHP上億數(shù)據(jù) php大量數(shù)據(jù)處理
本文URL:http://www.chinadenli.net/article32/hpjdsc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、響應(yīng)式網(wǎng)站、網(wǎng)站制作、網(wǎng)站策劃、靜態(tài)網(wǎng)站、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)