- 浏览: 106059 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
沉醉音乐的咖啡:
引用
Yii框架中ActiveRecord使用Relations -
stevecj:
呵呵,这个以后再交流。
盛大开始行动了,值得尊敬 -
庄表伟:
谢谢鼓励!我们会更加努力的。能聊聊你想做的另一个新产品是什么吗 ...
盛大开始行动了,值得尊敬
Yii CDBHttpSession数据库存储session性能优化实战
report it01
1 follower
上一篇 关于 Yii CHttpSession性能优化篇之源码流程分析 有详细分析CHttpSession执行流程,在了解CHttpSession的详细执行流程之后,我们就可以非常轻松的扩展Yii Session,来优化和符合自己的业务流程。
首先我们来看CDBHttpSession的数据库表结构, 可以看到,Yii是基于大众化的考虑,Yii_Session表实际没有作详细的性能优化,这是非常合理的。
CREATE TABLE $tableName
(
id CHAR(32) PRIMARY KEY,
expire INTEGER,
data TEXT
)";
当每次打开一个session时,都会调用readSession和writeSession方法,也就是说来一个用户相当于需要执行一次数据库的读和写操作,我们看表结构为 id CHAR(32),data 这字段为TEXT,存储引擎为MyISAM,当你在线访问量并发高时,使用CDBHttpSession一个很大的性能瓶颈,但是我们可以进一步优化.
首先从表结构入手, 当每来一次请求都需要读写session, 超时后将自动清除,所以将MySQL表类型设为TYPE=HEAP(内存表), session 为六个字符, data将保存session中的数据,这里我将设为255个字符,因为我本身session里面放的数据很少,如果你放的数据很多,更改data字符大小, ip地址实际都是为数字组成,我们将切分为四个tinyint字段。
CREATE TABLE $tableName (
sid char(6) NOT NULL DEFAULT '', //session id
ip1 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip2 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip3 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip4 tinyint(3) unsigned NOT NULL DEFAULT '0',
lastactivity int(10) unsigned NOT NULL DEFAULT '0', //最后缓存时间作为过期时间清理条件
data varchar(255) NOT NULL DEFAULT '', //保存session数据
UNIQUE KEY sid (sid),
KEY uid (uid)
) TYPE=HEAP;";
完成表设计之后就只需要重写openSession,readSession,writeSession,destroySession,gcSession 即可, 我们将使用6位session id 和 ip 作为当前请求用户的唯一ID.
下面看完整代码. 我们继承自CHttpSession,扩展一个类叫HttpSession.
首先我们重写createSessionTable方法:
/**
* Creates the session DB table.
* @param CDbConnection $db the database connection
* @param string $tableName the name of the table to be created
*/
protected function createSessionTable($db,$tableName) {
$sql=" CREATE TABLE $tableName (
sid char(6) NOT NULL DEFAULT '',
ip1 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip2 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip3 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip4 tinyint(3) unsigned NOT NULL DEFAULT '0',
lastactivity int(10) unsigned NOT NULL DEFAULT '0', //最后缓存时间作为过期时间清理条件
data varchar(255) NOT NULL DEFAULT '', //保存session数据
UNIQUE KEY sid (sid),
KEY uid (uid)
) TYPE=HEAP;";
$db->createCommand($sql)->execute();
}
init方法:
/**
* Initializes the application component.
* This method is required by IApplicationComponent and is invoked by application.
*/
public function init() {
$sid = $this->getCookie('sid'); //从cookie中取得session id
if (!isset($sid)) {
$sid = $this->random(6); //如果不存在,重新生成一个新的session id
$this->dsetcookie('sid',$sid); //将session id存入cookie, 24小时过期
}
$this->sessionID = $sid;
parent::init();
}
readSession 方法, 以6位sid和当前用户ip地址为条件作为唯的session id
/**
* Do not call this method directly.
* @param string $id session ID
* @return string the session data, 特别注意,必须返回$_SESSION可以识别的字符串
*/
public function readSession($id) {
$ip = $this->getIp();
$sql="SELECT data FROM {$this->sessionTableName} WHERE sid='$id' AND CONCAT_WS('.', ip1,ip2,ip3,ip4)='$ip'";
$data=$this->getDbConnection()->createCommand($sql)->queryScalar();
if($data !== false) {
return $data; //注意,此处必须返回$_SESSION特定格式的字符串.
} else {
return '';
}
}
writeSession 方法:
$cookieSid = $this->getCookie('sid');
if($id != $cookieSid) {
$newSid = $id;
}
$sid = isset($newSid) ? $newSid : $id;
try {
$db=$this->getDbConnection();
$ip = $this->getIp();
$ips = explode('.', $ip);
//如果已经登陆,设置超时时间,如果是游客,设为60秒.
$onlinehold = $data['id'] ? time() + $this->timeout : time() + 60 ;
$sql="SELECT * FROM {$this->sessionTableName} WHERE sid=:sid AND CONCAT_WS('.', ip1,ip2,ip3,ip4)=:ip";
//.......
if($row!==false) { //如果已经存在,更新session id以及session数据
} else { //插入新的记录
}
} catch(Exception $e) {
if(YII_DEBUG)
echo $e->getMessage();
// it is too late to log an error message here
return false;
}
return true;
destroySession
public function destroySession($id) {
$sql="DELETE FROM {$this->sessionTableName} WHERE sid=:sid AND CONCAT_WS('.', ip1,ip2,ip3,ip4)=:ip";
$this->getDbConnection()->createCommand($sql)
->bindParam(':sid',$id,PDO:"%5C%22static/image/smiley/default/tongue.gif%5C%22" smilieid="\"7\"" alt="\"\"" border="\"0\"">ARAM_STR)
->bindParam(':ip',$this->getIp(),PDO:"%5C%22static/image/smiley/default/tongue.gif%5C%22" smilieid="\"7\"" alt="\"\"" border="\"0\"">ARAM_STR)
->execute();
return true;
}
gcSession方法
public function gcSession($maxLifetime) {
$now = time();
$sql="DELETE FROM {$this->sessionTableName} WHERE lastactivity < $now";
$this->getDbConnection()->createCommand($sql)->execute();
return true;
}
注:本文只作CDBHttpSession探讨,Yii 本身已经提供了 CCacheHttpSession 类,如果你的服务器支持Memcached,可以优先考虑使用Cache管理Session, 尤其在分布式集群环境。
report it01
1 follower
上一篇 关于 Yii CHttpSession性能优化篇之源码流程分析 有详细分析CHttpSession执行流程,在了解CHttpSession的详细执行流程之后,我们就可以非常轻松的扩展Yii Session,来优化和符合自己的业务流程。
首先我们来看CDBHttpSession的数据库表结构, 可以看到,Yii是基于大众化的考虑,Yii_Session表实际没有作详细的性能优化,这是非常合理的。
CREATE TABLE $tableName
(
id CHAR(32) PRIMARY KEY,
expire INTEGER,
data TEXT
)";
当每次打开一个session时,都会调用readSession和writeSession方法,也就是说来一个用户相当于需要执行一次数据库的读和写操作,我们看表结构为 id CHAR(32),data 这字段为TEXT,存储引擎为MyISAM,当你在线访问量并发高时,使用CDBHttpSession一个很大的性能瓶颈,但是我们可以进一步优化.
首先从表结构入手, 当每来一次请求都需要读写session, 超时后将自动清除,所以将MySQL表类型设为TYPE=HEAP(内存表), session 为六个字符, data将保存session中的数据,这里我将设为255个字符,因为我本身session里面放的数据很少,如果你放的数据很多,更改data字符大小, ip地址实际都是为数字组成,我们将切分为四个tinyint字段。
CREATE TABLE $tableName (
sid char(6) NOT NULL DEFAULT '', //session id
ip1 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip2 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip3 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip4 tinyint(3) unsigned NOT NULL DEFAULT '0',
lastactivity int(10) unsigned NOT NULL DEFAULT '0', //最后缓存时间作为过期时间清理条件
data varchar(255) NOT NULL DEFAULT '', //保存session数据
UNIQUE KEY sid (sid),
KEY uid (uid)
) TYPE=HEAP;";
完成表设计之后就只需要重写openSession,readSession,writeSession,destroySession,gcSession 即可, 我们将使用6位session id 和 ip 作为当前请求用户的唯一ID.
下面看完整代码. 我们继承自CHttpSession,扩展一个类叫HttpSession.
首先我们重写createSessionTable方法:
/**
* Creates the session DB table.
* @param CDbConnection $db the database connection
* @param string $tableName the name of the table to be created
*/
protected function createSessionTable($db,$tableName) {
$sql=" CREATE TABLE $tableName (
sid char(6) NOT NULL DEFAULT '',
ip1 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip2 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip3 tinyint(3) unsigned NOT NULL DEFAULT '0',
ip4 tinyint(3) unsigned NOT NULL DEFAULT '0',
lastactivity int(10) unsigned NOT NULL DEFAULT '0', //最后缓存时间作为过期时间清理条件
data varchar(255) NOT NULL DEFAULT '', //保存session数据
UNIQUE KEY sid (sid),
KEY uid (uid)
) TYPE=HEAP;";
$db->createCommand($sql)->execute();
}
init方法:
/**
* Initializes the application component.
* This method is required by IApplicationComponent and is invoked by application.
*/
public function init() {
$sid = $this->getCookie('sid'); //从cookie中取得session id
if (!isset($sid)) {
$sid = $this->random(6); //如果不存在,重新生成一个新的session id
$this->dsetcookie('sid',$sid); //将session id存入cookie, 24小时过期
}
$this->sessionID = $sid;
parent::init();
}
readSession 方法, 以6位sid和当前用户ip地址为条件作为唯的session id
/**
* Do not call this method directly.
* @param string $id session ID
* @return string the session data, 特别注意,必须返回$_SESSION可以识别的字符串
*/
public function readSession($id) {
$ip = $this->getIp();
$sql="SELECT data FROM {$this->sessionTableName} WHERE sid='$id' AND CONCAT_WS('.', ip1,ip2,ip3,ip4)='$ip'";
$data=$this->getDbConnection()->createCommand($sql)->queryScalar();
if($data !== false) {
return $data; //注意,此处必须返回$_SESSION特定格式的字符串.
} else {
return '';
}
}
writeSession 方法:
$cookieSid = $this->getCookie('sid');
if($id != $cookieSid) {
$newSid = $id;
}
$sid = isset($newSid) ? $newSid : $id;
try {
$db=$this->getDbConnection();
$ip = $this->getIp();
$ips = explode('.', $ip);
//如果已经登陆,设置超时时间,如果是游客,设为60秒.
$onlinehold = $data['id'] ? time() + $this->timeout : time() + 60 ;
$sql="SELECT * FROM {$this->sessionTableName} WHERE sid=:sid AND CONCAT_WS('.', ip1,ip2,ip3,ip4)=:ip";
//.......
if($row!==false) { //如果已经存在,更新session id以及session数据
} else { //插入新的记录
}
} catch(Exception $e) {
if(YII_DEBUG)
echo $e->getMessage();
// it is too late to log an error message here
return false;
}
return true;
destroySession
public function destroySession($id) {
$sql="DELETE FROM {$this->sessionTableName} WHERE sid=:sid AND CONCAT_WS('.', ip1,ip2,ip3,ip4)=:ip";
$this->getDbConnection()->createCommand($sql)
->bindParam(':sid',$id,PDO:"%5C%22static/image/smiley/default/tongue.gif%5C%22" smilieid="\"7\"" alt="\"\"" border="\"0\"">ARAM_STR)
->bindParam(':ip',$this->getIp(),PDO:"%5C%22static/image/smiley/default/tongue.gif%5C%22" smilieid="\"7\"" alt="\"\"" border="\"0\"">ARAM_STR)
->execute();
return true;
}
gcSession方法
public function gcSession($maxLifetime) {
$now = time();
$sql="DELETE FROM {$this->sessionTableName} WHERE lastactivity < $now";
$this->getDbConnection()->createCommand($sql)->execute();
return true;
}
注:本文只作CDBHttpSession探讨,Yii 本身已经提供了 CCacheHttpSession 类,如果你的服务器支持Memcached,可以优先考虑使用Cache管理Session, 尤其在分布式集群环境。
发表评论
-
YII CACHE使用示例
2011-08-29 21:58 3966从Boylee那抄过来的.链接中有boylee的博客地址. 我 ... -
Yii CDBHttpSession数据库存储session性能优化实战
2011-08-29 21:36 4241Yii CDBHttpSession数据库存储session性 ... -
通过扩展CWebUser添加信息到Yii:app()->user
2011-08-29 21:21 3548通过扩展CWebUser添加信息到Yii:app()-> ... -
通过扩展 CWebUser 增加信息到 Yii::app()->user
2011-05-25 11:16 7577通过扩展 CWebUser 增加信息到 Yii::app()- ... -
Gridview日期过滤列(filter date column for gridview in Yii framework)
2011-05-23 11:02 5097Gridview日期过滤列(filter da ... -
利用yii framework dropdown 创建级联菜单
2011-05-23 10:57 2407利用yii framework dropdown 创建级联菜单 ... -
如何开发Yii的中文网站
2011-05-23 10:50 5103如何开发Yii的中文网站 首先在配置文件main.php 中 ... -
Yii CGridView 详解(关键看关联表字段排序部分)
2011-05-23 10:47 6964Yii CGridView 详解(关键看关联表字段排序部分) ... -
总结一下隐藏index.php文件的步骤
2011-05-23 10:07 1570总结一下隐藏index.php文件的步骤 1.开启apache ... -
Yii Framework的CPagination用法详解
2011-05-22 17:52 3268Yii Framework的CPagination用法详解 c ... -
YII TIPS
2011-05-22 17:12 1448db组件 'schemaCachingDuration'=&g ... -
yii ajax分页
2011-05-22 16:24 1868我们有时候需要ajax读取数据,并进行分页。首先我们遇到的是如 ... -
yii中widget分页的用法
2011-05-22 16:15 4150yii中widget分页的用法 1首先contr ... -
YII全局函数使用
2011-05-21 08:57 4617由于YII致力于完美的整合第三方库,它并没有定义任何全局函数。 ... -
Yii框架中ActiveRecord使用Relations
2011-05-21 06:55 2023Yii框架中ActiveRecord使用Relations ... -
转:关于yii的relations
2011-05-20 16:53 2596关于yii的relations . ... -
使用GD库生成验证码
2011-05-14 21:19 1179GD库在php 中的另一个重要的应用,是使用GD库生 ... -
smarty插件:在多少分钟前,多少小时前,多少天前。
2011-05-14 21:11 1281smarty插件:在多少分钟前,多少小时前,多少天前。 ... -
yii快速入门与参考
2011-05-04 09:17 5515yii快速入门与参考 ...
相关推荐
### YII 2数据库迁移(Migrations) 使用教程 #### 一、数据库迁移概念与作用 在软件开发过程中,随着项目的推进和技术需求的变化,数据库结构往往也需要进行调整或更新。为了更好地管理和跟踪这些变更,YII 2框架...
Yii框架数据库操作分享ppt (Mac版,windows需转换格式)
6. **性能优化**:Yii框架支持缓存(如Memcached或Redis)、查询构建器优化、预加载关联等,以提高数据库操作的效率。 综上所述,Yii框架的数据库备份模块涉及到数据库连接、备份与恢复策略、代码生成、事务处理等...
4. **性能优化**:学习数据库查询优化技巧、减少 HTTP 请求、使用缓存(如 Yii 的 Cache 组件)等方法提升系统性能。 5. **安全实践**:理解 Yii 的安全特性,如 CSRF 防护、输入验证、用户认证和授权。 6. **API ...
首先,要实现session的数据库存储,开发者需要在Yii应用配置文件中设置session组件,指定使用的数据库连接和session表。具体配置方式如下: ```php 'components' => [ 'db' => [ 'class' => 'yii\db\Connection',...
其次,Yii也支持直接的SQL查询,这在处理复杂查询或者优化性能时非常有用。`yii\db\Query`类提供了构建SQL查询的能力,而`yii\db\Command`类则负责执行这些查询。例如,获取`User`表中所有邮箱以`@example.com`结尾...
总结来说,MySQL复制和读写分离能够大幅提高数据库性能和可靠性,尤其在YII2框架中,通过合理配置和编程,可以有效实现这一目标。重要的是要理解MySQL复制机制的细节,以及YII2框架提供的数据库访问方式,确保读写...
在本文中,我们将深入探讨如何在Yii2框架中进行数据库备份,以及如何处理与NULL字符相关的常见问题。Yii2是一个高性能、组件化的PHP框架,它为开发者提供了丰富的工具和功能来构建复杂的Web应用程序。数据库备份是...
Yii 操作数据库的 3 种方法 在 Yii 框架中,操作数据库是不可或缺的一部分。Yii 提供了多种方式来操作数据库,本文将介绍 Yii 操作数据库的 3 种方法,分别是原生 SQL 的 PDO 方式、Active Record 方式和 Query ...
1. session存储配置不当:默认情况下,Yii使用文件系统来存储session数据。如果服务器的文件系统权限设置不当,或者多个实例(如多个Web服务器)访问同一个session存储目录时,可能会导致session文件冲突或破坏,...
数据库存储虽然方便,但在高并发环境下可能会导致性能下降。因此,一种常见的做法是使用内存存储,如Redis或Memcached。在Yii2中,可以通过配置`session`组件来实现: ```php 'session' => [ 'class' => 'yii\...
Yii框架是PHP开发中的一个流行选择,其强大的数据库操作功能使得开发者可以轻松地进行数据库的增删查改操作。在Yii中,数据库访问是通过...在实际项目中,还应考虑性能优化、数据库设计以及数据安全等方面的问题。
Yii框架是一个高性能的现代PHP框架,特别适用于开发Web 2.0应用程序。在数据库操作方面,Yii框架提供了Active Record和Query Builder两种主要方式来进行数据的查询、增加和删除操作。 首先,我们来介绍数据库查询...
### Yii 框架中的数据库 DAO #### 一、简介 在PHP开发中,Yii作为一个高效且功能丰富的框架,提供了强大的数据库支持。其中,数据访问对象(DAO)是其核心特性之一,它基于PHP的数据对象(PDO)扩展,提供了一个...
其中,数据库关联查询是Web开发中经常需要操作的功能,Yii框架通过其Active Record组件提供了便捷的方式来实现数据库的关联查询。 在Yii框架中,关联查询通常涉及到两个或多个数据表之间的关系。关联关系大致分为两...
Yii框架是PHP中一个流行的高性能MVC(模型-视图-控制器)Web开发框架。它提供了一整套数据访问和查询方法,使得与数据库交互变得简单高效。在Yii框架中,查询数据库的方法主要可以分为直接查询和使用Criteria对象...