需求描述
某些页面需要配置广告或活动宣传图,广告或活动需满足随时上下线、过期自动下线及到时自动上线。
如:现在时间2019-2-22 16:16:13,要在支付完成页面配置领奖活动,活动要在2019-3-10 00:00:00准时上线,在2019-3-30 23:59:59结束活动。
因此,期望实现的效果是在活动上线前的任何时间配置完活动后,页面会在指定时间自动上线该活动。也可能会是其他的多个活动或广告,每个页面广告的个数可变,不同上下线时间可不同,其他页面也需要实现这样的功能,页面与页面之间的活动不一定一样。
需求分析
需求简单的几句话,那么我们来具体的分析一下。
提取关键词
广告或活动宣传图
随时上下线、过期自动下线及到时自动上线
每个页面广告的个数可变
不同广告上下线时间可不同
页面与页面之间的活动不一定一样
数据库分析
1、【广告或活动宣传图】
要为不同页面设置不同的广告,有的页面广告可能一样,也就是广告会复用,所有要有广告表。
2、【每个页面广告的个数可变】【不同广告上下线时间可不同】【页面与页面之间的活动不一定一样】
页面可配置多个广告,所有要有页面配置表,以及广告和页面的关系表,即页面广告表。
页面配置表主要配置页面的广告个数,实现【每个页面广告的个数可变】,页面广告表主要配置页面的每个广告上下线时间,实现【不同广告上下线时间可不同】
根据简单的分析,我得出以下表格构造:广告表(adv),页面配置表(page_config)和页面广告表(page_adv)

思考
这些页面配置的广告在一段时间内是不会变的,如果页面请求次数较多,广告查询次数就会很频繁,对数据库造成不必要的压力。所以可以引入缓存,降低数据库请求次数,缓解数据库压力。这里使用的Redis。
何时入缓存?
可以选择在服务启动时异步把已在上下线时间区间内的广告先加载至缓存,或选择在请求时取缓存,缓存内没有时再查库然后放缓存。缓存时间视情况而定。
这里选择的是,项目启动时异步把符合条件的页面广告配置信息存入Redis,那些还没到指定时间的先不放Redis,等到访问页面加载广告时,先查Redis,若无则按条件(>=nowtime)查库,查到后存Redis。
在接口中拿到广告配置信息后,判断当前时间是否在配置的时间区间内,由于一个页面配置多个广告,不同广告时间也不同,所以要迭代,把符合的返回,有过期的就做标记,然后把整个页面的配置信息在Redis里删除。(或者不选择在启动时加载,就在用户请求时加入缓存,但是下面的第1步的方法在刷新加载时会用到,故不能删)
具体实现
第1步、项目启动时先把页面广告配置信息存入Redis
a、查询所有pageId
SELECT pageId FROM page_config page_adv WHERE nowtime<=endtime AND GROUP BY pageId
两个表内连接,得List b、查询pegeId对应的广告图片及跳转链接 然后把查到的配置信息List 按标准的控制层,业务层,数据访问层写,第一步中的逻辑就是在业务层完成的。 控制层: 控制层接参pageId,调用业务层查询对应页面配置的广告信息,判空,直接返回状态码0,即无广告前端不展示。 不为空就根据业务逻辑处理数据(如img的URL加域名),然后返回状态码1,前端展示广告。这里控制层还可以加逻辑,迭代广告list,把当前时间在广告起始时间内的返回,不在的不返回,并且只要有一个广告过期,就把这个页面的广告list缓存清掉。这个逻辑是把过期的清掉。 业务层: 先取缓存,没有再查库判断不为空(本页面配置的有广告),放入缓存(pageId为KEY),然后返回。 数据访问层: SQL: 三表联查,根据pageId查询当前页面配置的广告活动信息(已在广告活动时间内) 为什么使用刷新加载? 因为有这样的场景:给页面A配置了一个广告(当前时间在广告的起始时间内),那么这个页面的广告已经在缓存里了,假如此时A页面要新加一个广告,在后台配置后如果不做其他操作,这个广告不会显示(假设缓存时间较长,为一天),因为库更新了,缓存没有同步更新。 解决方案 使用Redis的发布订阅机制实现缓存的刷新加载,使新配置的广告及时能够显示。刷新加载的回调方法即第1步中的方法。 想一想,目前的实现存在什么问题? 存在的问题 假如有页面需要配置广告,但是还没有配(前端已经开发完上线,每次都会调接口查广告信息),那么数据库肯定查不到,缓存也没有。如果这个页面访问量很大,那么缓存没命中就查库,这样对库的压力就会很大,这就是缓存穿透,请求上来了很容易击垮数据库。那怎么办呢? 解决方案 当页面没有配置广告时,在缓存存标志,查询时先看标志,在决定是否往下走。 具体方案 这时,上面的第1步就要改了。 1、首先改第1步的步骤a的SQL,把所有的pageId都查询出来。 使用左连接 或者干脆查page_config 目的是把已在page_config表中配置,但关系表中page_adv未配置广告的pageId也查出来,这样才能给未配置广告的pageId在缓存里放标志 2、第1步的步骤b的SQL改为 然后把查到的配置信息放入缓存之前判断【为空时的不做操作】改为【为空时存入一个标志】假如这个标志KEY为pageId+"_EMPTY_FLAG",value为"DB_IS_NULL" 为什么只判断小于结束时间 因为如果该页面配置的广告开始时间大于当前时间,那么这个是查不到的,会被处理为DATABASE_IS_NULL,如果在这个标志还没失效之前就到了配置的开始时间了,那么这个广告不会被展示。所有要让未到开始时间的也放入缓存,然后让控制层去判断在不在时间区间。 3、所以要在第2步也修改一下 在业务层里取缓存中的广告列表之前,先从缓存取pageId+"EMPTY_FLAG"的value判断为"DB_IS_NULL"直接返回空,这样就能避免缓存穿透的问题了。 继续修改第2步的业务层,查库的SQL同样要改: 然后判断为空的话,同上面的黄字那样处理。 4、最后,第3步的刷新加载调的是第1步的方法,不用改。 1、控制层拦截:根据pageId查询page_adv表,查不到说明没配置,直接返回。 2、page_config 表增加字段,表示当前页面已经配置的广告个数,默认0,每配置一个该字段加1,把大于0的pageId缓存起来,调接口时前判断在不在缓存里。 以上是redis怎么实现页面实时更新自动上线的详细内容。更多信息请关注PHP中文网其他相关文章!SELECT 字段名 FROM page_adv adv WHERE begintime<=nowtime<=endtime AND pageId={#pageId}
第2步、给前端写接口查询页面广告
SELECT 字段名 FROM page_config adv page_adv WHERE begintime<=nowtime<=endtime AND pageId=#{pageId}
第3步、刷新加载
进一步优化
SELECT pageId FROM page_config LEFT JOIN page_adv ON ... GROUP BY pageId
SELECT pageId FROM page_config
SELECT 字段名 FROM page_adv adv WHERE nowtime<=endtime AND pageId={#pageId}
SELECT 字段名 FROM page_config adv page_adv WHERE nowtime<=endtime AND pageId=#{pageId}
当然这个缓存穿透的优化方案只是其中一种。还可以这样:

REDISACTSASBOTHADATASTOREANDASERVICE.1)ASADATASTORE,ITUSESIN-MEMORYSTOOGATOFORFOFFASTESITION,支持VariousDatharptructuresLikeKey-valuepairsandsortedsetsetsetsetsetsetsets.2)asaservice,ItprovidespunctionslikeItionitionslikepunikeLikePublikePublikePlikePlikePlikeAndluikeAndluAascriptingiationsmpleplepleclexplectiations

Redis与其他数据库相比,具有以下独特优势:1)速度极快,读写操作通常在微秒级别;2)支持丰富的数据结构和操作;3)灵活的使用场景,如缓存、计数器和发布订阅。选择Redis还是其他数据库需根据具体需求和场景,Redis在高性能、低延迟应用中表现出色。

Redis在数据存储和管理中扮演着关键角色,通过其多种数据结构和持久化机制成为现代应用的核心。1)Redis支持字符串、列表、集合、有序集合和哈希表等数据结构,适用于缓存和复杂业务逻辑。2)通过RDB和AOF两种持久化方式,Redis确保数据的可靠存储和快速恢复。

Redis是一种NoSQL数据库,适用于大规模数据的高效存储和访问。1.Redis是开源的内存数据结构存储系统,支持多种数据结构。2.它提供极快的读写速度,适合缓存、会话管理等。3.Redis支持持久化,通过RDB和AOF方式确保数据安全。4.使用示例包括基本的键值对操作和高级的集合去重功能。5.常见错误包括连接问题、数据类型不匹配和内存溢出,需注意调试。6.性能优化建议包括选择合适的数据结构和设置内存淘汰策略。

Redis在现实世界中的应用包括:1.作为缓存系统加速数据库查询,2.存储Web应用的会话数据,3.实现实时排行榜,4.作为消息队列简化消息传递。Redis的多功能性和高性能使其在这些场景中大放异彩。

Redis脱颖而出是因为其高速、多功能性和丰富的数据结构。1)Redis支持字符串、列表、集合、散列和有序集合等数据结构。2)它通过内存存储数据,支持RDB和AOF持久化。3)从Redis6.0开始引入多线程处理I/O操作,提升了高并发场景下的性能。

RedisisclassifiedasaNoSQLdatabasebecauseitusesakey-valuedatamodelinsteadofthetraditionalrelationaldatabasemodel.Itoffersspeedandflexibility,makingitidealforreal-timeapplicationsandcaching,butitmaynotbesuitableforscenariosrequiringstrictdataintegrityo

Redis通过缓存数据、实现分布式锁和数据持久化来提升应用性能和可扩展性。1)缓存数据:使用Redis缓存频繁访问的数据,提高数据访问速度。2)分布式锁:利用Redis实现分布式锁,确保在分布式环境中操作的安全性。3)数据持久化:通过RDB和AOF机制保证数据安全性,防止数据丢失。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

记事本++7.3.1
好用且免费的代码编辑器

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),