博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php mysql记录用户行为_用户参与记录存储的演变_PHP教程
阅读量:6268 次
发布时间:2019-06-22

本文共 2355 字,大约阅读时间需要 7 分钟。

有这样一个应用场景:用户有两个连续的操作A和操作B,必须是操作A完成后才能执行操作B,如果操作A没有完成就触发了操作B,则显示用户需要先执行操作A,即在操作B执行需要查询操作A是否执行过。这里引申出来的问题是,记录用户参与记录,提供针对用户和操作的查询方法。当不同的数据量时,我们的存储方案会大不相同,随着数据的增长,方案不断演变。

1、数据量较小,用户操作行为固定:

存储:MySQL

方案:我们以UID为key,一行一个用户,每个用户包括的用户作为列存储,比如UID=100,固定存储为操作A和操作B,则表结构大致如下:

table_operation

uid operation_a operation_b

100 1 1

如果我们要查询用户是否参与A或B时,直接使用SQL: SELECT * FROM table_operation WHERE uid=100 AND action_a=1就可以达成目标。

问题:用户操作固定,扩展较难,如果需要增加用户操作行为,则需要增加字段或增加表存储,增加字段的方法在一定的数据量级以下(比如100万)是可行的,如果行为间无关,则增加表存储方案的表现会很不错。

2、数据量较小、用户操作行为不固定:

与场景1相比,当前场景除了uid这个变量,增加了用户操作变量,即我们需要关注用户和用户操作两个变量。

存储:MySQL

方案1:增加操作表,生成操作id,用户操作行为表存储uid和oid。当用户执行一个新的操作时就在操作行为表插入一条记录。其表结构大致如下:

table_operation_info

oid name

1 operation_a

2 operation_b

table_operation

uid oid

1 1

1 2

当需要查询用户1是否执行过操作A时,使用SQL:SELECT * FROM table_operation WHERE oid=1 AND oid=1。

问题:当用户的操作行为较多时,用户操作行为增长速度很快,数据量也为逐渐增大,可能MySQL单表无法负载。解决方案在后续场景中说明。

3、数据量较大,用户行为固定

存储:MySQL

方案:与场景1相比,当前场景不同在于数据量比场景1大,数据量大到MySQL单表负载不过来。此方案解决的就是这个问题,当单表太大时,性价比较高的方法一般是采用分表。我们当前场景的变量是uid,只要依据uid按水平分表即可。

4、数据量较大,用户行为不固定

存储: MySQL

方案1:此方案应用于用户的操作行为可以分类的情况,即在场景1的基础上增加两次分表操作,按操作行为类分表和按用户分表。当前方案中我们需要应对两个变量:操作行为和用户。两次分表分别对应这两个变量,按业务规则做操作行为的分表操作,按用户id水平切分减少数据量。

方案2:此方案是完全的水平分表操作,在场景2的方案基础上,按用户水平切分。

5、数据量超大

存储: MySQL

方案1:分库分表,此时一个库已经无法满足需求,规则依据前面的场景实现,根据实际的需求可以考虑把不同的库放不同的机器上。

方案2:在分库分表的基础上,按位存储,因为一个操作行为有没有执行过是一个是否的状态,即0,1状态,因此我们可以用一个位来存储,64位可以存储64个操作行为的标记。

其它存储

key-value数据库

我们的需求实际上并不需要太多的关系型数据库的功能,简单的 k-v数据库就可以实现我们的功能,并且在性能上也会有所提升,毕竟做得少,会快。

先不管是选择基于内存的,还是非内存的(可以根据实际需求来选择,也可以是热点数据在内存,沉默数据在非内存中),假设我们有足够的空间存储。

方案1:

以uid+oid为key,值可以存储状态,也可以只存储是否参与(0和1),但是会存在key太多的情况,特别是当数据量超大时,uid的个数*oid的个数,可能是你无法相像的量级。

方案2:

一般来说,用户操作行为的数据量完全小于用户的量级,并且用户操作行为的数据可控。如果要减少key的个数,我们可以使用oid+用户分区索引id作为key,这里所谓的用户分区索引是指将用户以某个数量分成一个区,所有的用户都记录在这个这个区间内,比如以10000为一个区间,则uid为1到9999的用户分到区间0,这里可以以1和0存储用户是否执行了此操作,一个key对应的value初始化存储10000个0。当uid=100的用户执行了某操作,则将第100个0置为1。

方案3:

在方案2的基础上,将10000个0转换为10000个01位,假设一个位存储50位,则总共只需要200个。

方案4:

当用户量超大时,大多数的用户对于某个操作可能都是没有参与的,则在方案3的基础上我们增加简单的稀疏矩阵压缩,给每个存储位添加索引,当存储值不为0时才会存储。

方案5:

我还没想到,期待你的分享

小结

•随着数据量的增大,总的思路是分冶,当一个表搞不定时分表,当一个库搞不定时分库,当一台机器搞不定时加机器。

•对于不同的存储介质选择需要考虑成本和需求,所有的选择都是平衡后的结果。

•节省空间,按位存储。

•不要过早优化。

http://www.bkjia.com/PHPjc/444587.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/444587.htmlTechArticle有这样一个应用场景:用户有两个连续的操作A和操作B,必须是操作A完成后才能执行操作B,如果操作A没有完成就触发了操作B,则显示用户...

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

转载地址:http://xxspa.baihongyu.com/

你可能感兴趣的文章
js-权威指南学习笔记13
查看>>
《超级时间整理术》晨读笔记
查看>>
Spring Boot 2.0(二):Spring Boot 2.0尝鲜-动态 Banner
查看>>
Delphi IdTCPClient IdTCPServer 点对点传送文件
查看>>
Delphi中使用ActiveX的一些心得
查看>>
QT5.8.0+MSVC2015安装以及环境配置(不需要安装VS2015)
查看>>
(原創) C/C++的function prototype和header file (C/C++) (C)
查看>>
深入理解JavaScript系列(29):设计模式之装饰者模式
查看>>
程序员的罪与罚
查看>>
SQL*LOADER错误总结
查看>>
SQL日志收缩
查看>>
【转】MySQL Query Cache 小结
查看>>
SVN分支和合并的简单例子
查看>>
PHP实现的封装验证码类
查看>>
Augular初探
查看>>
PHPStorm下XDebug配置
查看>>
【LeetCode】55. Jump Game
查看>>
Android应用盈利广告平台的嵌入方法详解
查看>>
Linux(CentOS6.5) 开放端口,配置防火墙
查看>>
Func与Action
查看>>