基于memcache接口的统一存储工具类设计

刚开始处理的时候,临时想做一个统一接口的key-value数据的存储方式。然后我模拟memcached接口,写了个简单的k-v数据存储的工具类。

临时想到,暂且记下。

1.接口类/**

*存储工具抽象接口类

*

*/

abstractclassStoreTool

{

abstractpublicfunctionset($key,$val);

abstractpublicfunctionget($key);

abstractpublicfunctionreplace($key,$val);

abstractpublicfunctiondelete($key);

abstractpublicfunctionflush();

abstractpublicfunctionincrement($key,$val=1);

abstractpublicfunctionadd($key,$val);

}

复制代码

2.memcached和mysql处理(mysql用的heapengine)/**

*mysqlheapengin存储工具类

*

*/

classDbStoreToolextendsStoreTool

{

staticprivate$_instance;

private$_dbh;

private$_tablename='mmouc_memory_kv';

staticpublicfunctiongetInstance($config){

if(self::$_instance==null){

self::$_instance=newself($config);

}

returnself::$_instance;

}

privatefunction__construct($config){

$conn=$config['persistency']?mysql_pconnect($config['host'].':'.$config['port'],$config['user'],$config['password'])

:mysql_connect($config['host'].':'.$config['port'],$config['user'],$config['password']);

if($conn){

if($config['charset'])mysql_query("SETNAMES'".$config['charset']."'",$conn);

if(!empty($config['database'])){

$dbselect=mysql_select_db($config['database'],$conn);

if(!$dbselect){

mysql_close($conn);

$conn=$dbselect;

}

}

$this->_dbh=$conn;

$this->_tablename=$config['tablename'];

}

}

/**

*Storedataattheserver

*storesanitemvarwithkeyonthememcachedserver

*

*@paramunknown_type$key

*@paramunknown_type$val

*@returnunknown

*/

publicfunctionset($key,$val){

$res=$this->update($key,$val);

if(0===$res){

return$this->add($key,$val);

}

returntrue;

}

/**

*Replacevalueoftheexistingitem

*shouldbeusedtoreplacevalueofexistingitemwithkey.

*Incaseifitemwithsuchkeydoesn'texists,ThisfunctionreturnsFALSE

*

*@paramunknown_type$key

*@paramunknown_type$val

*@returnunknown

*/

publicfunctionreplace($key,$val){

$res=$this->update($key,$val);

if(0===$res){

returnfalse;

}

returntrue;

}

publicfunctionget($key){

if(is_array($key)){

$in_keys="'".implode("','",$key)."'";

$sql="

SELECT`k`,`v`FROM`".$this->_tablename."`

WHERE`k`IN({$in_keys})

";

$res=mysql_query($sql,$this->_dbh);

if(empty($res)){

returnMMO_STORE_OP_ERROR;

}

$_arr_res=array();

while($row=mysql_fetch_assoc($res)){

$row['v']=unserialize($row['v']);

$_arr_res[$row['k']]=$row;

}

$out=array();

foreach($keyas$_k){

$out[]=$_arr_res[$_k]['v'];

}

return$out;

}elseif(is_string($key)){

$sql="

SELECT`v`FROM`".$this->_tablename."`

WHERE`k`='{$key}'

";

$res=mysql_query($sql,$this->_dbh);

if(empty($res)){

return-1;

}

$row=mysql_fetch_assoc($res);

if(empty($row)){

returnMMO_STORE_ITEM_NOT_EXIST;

}

returnunserialize($row['v']);

}else{

returnfalse;

}

}

publicfunctiondelete($key){

$sql="

DELETEFROM`".$this->_tablename."`

WHERE`k`='$key'

";

$res=mysql_query($sql,$this->_dbh);

if(!$res){

returnMMO_STORE_OP_ERROR;

}

returnmysql_affected_rows($this->_dbh);

}

publicfunctionflush(){

$sql="TRUNCATETABLE`".$this->_tablename."`";

$res=mysql_query($sql,$this->_dbh);

return$res?true:false;

}

/**

*

*TODO:

*修改这里的并发访问问题

*

*@paramunknown_type$key

*@paramunknown_type$val

*@returnunknown

*/

publicfunctionincrement($key,$val=1){

$_db_val=$this->get($key);

if(MMO_STORE_ITEM_NOT_EXIST==$_db_val){

//不存在

returnfalse;

}

$val=intval($_db_val)+intval($val);

$this->update($key,$val);

return$val;

}

/**

*Addanitemtotheserver

*

*storesvariablevarwithkeyonlyifsuchkeydoesn'texistattheserveryet

*

*@paramunknown_type$key

*@paramunknown_type$val

*@returnunknown

*/

publicfunctionadd($key,$val){

if(!$this->_isExist($key)){

$val=serialize($val);

$time=time();

$sql="

INSERTINTO`".$this->_tablename."`

SET`k`='{$key}',

`v`='{$val}',

`t`='{$time}'

";

$res=mysql_query($sql,$this->_dbh);

return$res?true:MMO_STORE_OP_ERROR;

}else{

returnfalse;

}

}

privatefunction_isExist($key,$val=''){

$sql="

SELECTCOUNT(`k`)as'num'

FROM`".$this->_tablename."`

WHERE`k`='{$key}'

";

!empty($val)&&$sql.=",`v`='".serialize($val)."'";

$res=mysql_query($sql,$this->_dbh);

if(empty($res)){

return-1;

}

$row=mysql_fetch_assoc($res);

return$row['num']?true:false;

}

privatefunctionupdate($key,$val){

$val=serialize($val);

$time=time();

$sql="

UPDATE`".$this->_tablename."`

SET`v`='{$val}',

`t`='{$time}'

WHERE`k`='$key'

";

$res=mysql_query($sql,$this->_dbh);

if(!$res){

returnMMO_STORE_OP_ERROR;

}

returnmysql_affected_rows($this->_dbh);

}

}

classFileStoreTool

{

}

classMemcacheStoreToolextendsStoreTool

{

staticprivate$_instance;

private$_memcacheHandler;

staticpublicfunctiongetInstance($config){

if(self::$_instance==null){

self::$_instance=newself($config);

}

returnself::$_instance;

}

privatefunction__construct($config){

$this->_memServers=$config;

$this->_initMemcacheObj();

}

publicfunctionset($key,$val){

return$this->_memcacheHandler->set($key,$val);

}

publicfunctionget($key){

return$this->_memcacheHandler->get($key);

}

publicfunctionreplace($key,$val){

return$this->_memcacheHandler->replace($key,$val);

}

publicfunctiondelete($key){

return$this->_memcacheHandler->delete($key);

}

publicfunctionflush(){

return$this->_memcacheHandler->flush();

}

publicfunctionincrement($key,$val=1){

return$this->_memcacheHandler->increment($key,$val);

}

publicfunctionadd($key,$val){

return$this->_memcacheHandler->add($key,$val);

}

/**

*检查保存Session数据的路径是否存在

*

*@returnbool成功返回true

*/

privatefunction_initMemcacheObj(){

if(!class_exists('Memcache')||!function_exists('memcache_connect')){

die('Failed:Memcacheextensionnotinstall,pleasefromhttp://pecl.php.netdownloadandinstall');

}

if($this->_memcacheHandler&&is_object($this->_memcacheHandler)){

returntrue;

}

$this->_memcacheHandler=newMemcache;

if(!empty($this->_memServers)){

foreach($this->_memServersas$_host=>$_port){

$this->_memcacheHandler->addServer($_host,$_port);

}

}

returntrue;

}

}

复制代码

3.mysql和file相关

mysql记录方式,对应表建表语句如下:

CREATETABLEIFNOTEXISTS`mmouc_memory_kv`(

`k`varchar(40)NOTNULLCOMMENT'键名',

`v`varchar(2048)NOTNULLCOMMENT'键值的serialize值',

`t`int(10)NOTNULLDEFAULT'0'COMMENT'更新时间',

PRIMARYKEY(`k`)

)ENGINE=MEMORYDEFAULTCHARSET=utf8COMMENT='代替memcache数据记录表';

对于file,暂未处理,以后补上。

4.todo:

a.对于memcached数据的遍历方式策略,需要做一个完备而统一接口的策略算法处理类,可以在多种分级存储模式,和存储策略间任意切换;

b. file存储工具类补上

相关推荐