Yii CDBHttpSession数据库存储session性能优化实战

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, 尤其在分布式集群环境。
YOLOv11【第二十章:模型迭代与生态闭环篇·第1节】在线增量学习——部署后新数据自动回流重训! 🏆 本文收录于专栏 《YOLOv11实战:从入门到深度优化》。本专栏围绕 YOLOv11 的改进、训练、部署与工程优化 展开,系统梳理并复现当前主流的 YOLOv11 实战案例与优化方案,内容目前已覆盖 分类、检测、分割、追踪、关键点、OBB 检测 等多个方向。 阅读详情

相关推荐

AI医疗影像诊断工具2025 完整教程

本教程所述工具均为辅助诊断设备,不可替代执业医师判断。部署使用需遵守当地医疗器械管理法规。推荐开源框架组合:代码太多打包上传网盘了 自行下载。2025年的AI医疗影像诊断工具将以。

m0_60084632的博客 2029

Yii1.1 CHttpSession 的session属性配置项

本文记录下main.php中session的配置选项,仅做记录,因为Yii本身的session,已经封装的很强悍,但是过于强悍,也不免丢失了很多细节。 详细文档请参考:http://www.yiiframework.com/doc/api/1.1/CDbHttpSession // protected/config/main.php // application component

ruxing.li 的专栏 4598

uniapp监听扫码枪键盘事件|无输入框式监听

一般的扫码枪通过USB或蓝牙连接手机或电脑,充当的是一个外接设备。当扫码后,扫码枪会自动识别内容,然后向连接的电脑或手机发送键盘事件keydown或keyup。

tcy9099的专栏 9751

yii 中CHttpSession的使用

开启一个session代码如下: $session=new CHttpSession; $session->open(); $value=$session['name']; // 获取 session 变量 $session['name] 中的值 在yii中CHttpSession有两个子类,分别是:CcacheHttpSession和CdbHttpSession,可以实现使用

How many roads must a man walk down 718

手把手教你用Trae配置Python开发环境(含Claude 3.5代码生成实战)

本文详细介绍了如何使用字节跳动推出的Trae智能开发环境配置Python开发环境,并实战演示了Claude 3.5代码生成功能。从环境准备到项目初始化,再到AI辅助编码和调试优化,全面展示了Trae在提升开发效率方面的强大能力,特别适合Python开发者快速搭建项目和解决复杂问题。

weixin_28309571的博客 977

DS250DF410寄存器配置实战:从原理到调试的高速SerDes信号优化指南

在高速串行通信领域,SerDes(串行器/解串器)技术是实现芯片间高速数据传输的核心。其工作原理是通过时钟数据恢复(CDR)从串行数据流中提取时钟,并利用均衡技术补偿信道损耗。这项技术的核心价值在于突破PCB走线或电缆的带宽限制,确保在25Gbps及以上速率下数据的可靠传输。其应用场景广泛覆盖数据中心、高性能计算和通信设备中的高速背板、光模块及芯片互连。本文以TI的DS250DF410多通道重定时器为例,深入剖析其寄存器配置,特别是如何通过精细调控其自适应均衡器和眼图监测模块,实现对高速链路的信号整形与质量

aodiyi6351的博客 386

httpsession mysql,session 的持久化存储

sessio遇新是直朋能到分览支体调n 的定义:ses用,事少来最差端在事路原们这制码效移,动sion 是一个概念,是一个数据对象,用来存储访问者的朋支不器几事为的时后级功发发来久都这样含制层是请些间例业多在上屏屏信息。sessi在很理应于是会商器则,,是各近或多,用维on 的存储方式由开发者自己定义,可存于内存,redis,mysql,甚至是 cookie 中在重说道。础过学开概码数项遍间里哦行...

weixin_29115107的博客 425

域控制器开发避坑实录:从硬件设计到软件集成的5个关键挑战

本文深入剖析了域控制器开发中的5大关键挑战,从硬件选型到软件集成,涵盖智能驾驶芯片选择、实时性优化、AUTOSAR架构适配等核心问题。通过实战案例和数据对比,为工程师提供避坑指南,助力提升开发效率和系统可靠性。

weixin_29258297的博客 395

分布式架构学习之如何将session信息存储到数据库中

最近实践了一把SpringCloud集成注册中心、网关、配置中心、微服务,恰好电脑上的redis出现了各种问题,索性不用redis,自己写了个中间件,将存储到了MySQL中。下面是期间遇到的各种问题总结。 手先介绍基实现的本原理。我请教了下师傅,总结出了将Session持久化的几条要点。 Http是无状态的协议; 所谓http是无状态协议,言外之意是说http协议没法保存客户...

Purse的博客 2591

论文复现5:UMI Universal Manipulation Interface

UMI 采用手持式夹具,加上精心的界面设计,可实现便携式、低成本和信息丰富的数据收集,以进行具有挑战性的双手和动态操作演示。配备这些功能后,UMI 框架解锁了新的机器人操作功能,只需更改每个任务的训练数据,即可实现零样本可推广的动态、双手、精确和长视野行为。我们通过全面的现实世界实验展示了 UMI 的多功能性和有效性,其中通过 UMI Zeroshot 学习的策略在对不同的人类演示进行训练时可以推广到新的环境和对象。项目主页:https://umi-gripper.github.io/

github_38060285的博客 1979

基于STM32L4XX 、HAL库的ATD5984步进电机驱动器驱动程序应用设计

一、简介: ATD5984是一款内部集成了译码器的微特步进电机 驱动器,能使双极步进电机以全、半、1/4、/1/8、1/16 和1/32步进模式工作。步进模式由逻辑输入管脚MSx选 择。其输出驱动能力达到28V±1.6A。 译码器是ATD5984易于使用的关键,通过STEP管脚 输入一个脉冲就可以使电机完成一次步进,省去了相序 表,高频控制线及复杂的编程接口,使其更适于没有复 杂的微处理器或微处理器负担过重的场合。 在步进操作期间,ATD5984的内部电路可以自动

PP_Cottage的博客 408

Yii中Session和cookie的用法

一,在Yii中使用session 1,CHttpSession 与原生态php5的session使用差别是,php5使用session_start();$_session['key'] = $value; 在yii中,session已经被封装。 To start the session, call open(); To complete and send out session data, cal...

weixin_30848775的博客 92

【测开求职】面试题:数据结构 吐血整理

本篇文章是笔者为准备研究生复试以及校招而写,因此主要针对问答,注重理解,而不在于细节计算。涵盖考研范围内的所有知识内容,读者可以先查看上面的链接走一遍数据结构的整体框架结构。其中,重点难点以及易混淆的知识点,笔者用其他近30篇文章进行了详述,在知识点处贴好了链接,有需要的可以查阅。

vector的博客 7065

保存Session数据到数据库

开发工具与关键技术: VS,Session 作者:卢惠圳 撰写时间:2019年7月26日 当保存的数据里面有一些是Session的时候并且是跟据不是Session里的数据的ID来保存Session里的数据所以要先获取到页面的数据,并且最好用POST提交否则可能会有一些需要单独传过去的ID会传不过去,代码如下图: 然后就是控制器部分了,先将页面传过来的数据和单独传过来的ID获取到然后将Sessio...

weixin_44561044的博客 1099

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

yii2的请求(request)、响应与跳转(response)、缓存(session)常用操作

一、yii2 request操作 Yii::app−&gt;request−&gt;get();//等价于:app-&gt;request-&gt;get();//等价于:app−>request−>get();//等价于:_GET; Yii::app−&gt;request−&gt;post();//等价于:app-&gt;re...

freedom_fd的博客 747

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Yii - session 数据库存储

在组件中声明session 组件开启数据库库存储[ 'components' => [ 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii',

聆听岁月的博客 1002

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

yii2 session mysql_Yii框架 session 数据库存储操作方法示例

本文实例讲述了Yii框架 session 数据库存储操作方法。分享给大家供大家参考,具体如下:在组件中声明session 组件开启数据库库存储['components' => ['db' => ['class' => 'yii\db\Connection','dsn' => 'mysql:host=localhost;dbname=yii','user...

weixin_39835792的博客 273

Yii框架下使用memcached来存取数据时,key的生成方式

1 使用CCacheHttpSession时,memached中的真实值: session_id in memcached:  $key=md5("nameYii.CCacheHttpSession.REAL_ID") name: cmemcache.keyPrefix or  $key=md("APPIDYii.CCacheHttpSession.REAL_ID)

iSuperGoo 803

关于Session优化

优化Session:        网站访问量过多的时候,会存在大量的Session在内存中,这个时候可以让一定时间内不活跃的的Session序列化到硬盘上,当用户再次访问的时候,反序列化到内存中.从而达到优化Session的目的.        通过配置&lt;Context&gt;标签配置定时session序列化,Session优化的三种方式: * 在tomcat/conf/context.x...

玲儿叮当想 998

yii2 session存储代码解析

首先,在Yii框架中,你不需要像标准PHP代码那样使用session_start(), 在 Yii 框架中,autoStart 属性缺省被设置为true,所以, 虽然没有使用session_start(),你仍然可以使用 $_SESSION 全局变量,但最好使用 下面我们来看看源码: 首先yii2的public配置文件中: 可以找到CCacheHttpSession类,看到缓存有个前缀 Yii.CCacheHttpSession. 因为缓存配置的是redis,看到缓存类CRedisCa...

lchmyhua88的博客 406

Gridview日期过滤列(filter date column for gridview in Yii framework)

Gridview日期过滤列(filter date column for gridview in Yii framework) CActiveDataProvider, CArrayDataProvider, CSqlDataProvider做为gridview挂件的数据提供者的使用经验 使用yii进行命令行程序设计 近期评论 ...

stevecj的专栏 609

yii中widget分页的用法

yii中widget分页的用法 1首先controller的action     $count = Listdetail::model()-&gt;count("listId=:listId",array(':listId'=&gt;$listid)); $pages=new CPagination($count); $pages-&gt;pageSize=20; $cr...

stevecj的专栏 364

总结一下隐藏index.php文件的步骤

总结一下隐藏index.php文件的步骤 1.开启apache的mod_rewrite模块 去掉LoadModule rewrite_module modules/mod_rewrite.so前的“#”符号 确保中有“AllowOverride All” 2.在项目中的/protected/config/main.php中添加代码: 'componen...

stevecj的专栏 333
上一篇: YII CACHE使用示例
stevecj
博客等级 码龄25年 0粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值