最代码网站中关于动态表event的设计思路
原文:最代码网站中关于动态表event的设计思路 为了能将最代码整站用户的操作都展现出来,需要设计一种动态类型,既可以根据业务无限扩展,也可以指定某些用户行为是可以产生多少牛币交换的,这样就在原先javaniu的零散的表设计基础上抽象出event表 表结构如
原文:最代码网站中关于动态表event的设计思路
为了能将最代码整站用户的操作都展现出来,需要设计一种动态类型,既可以根据业务无限扩展,也可以指定某些用户行为是可以产生多少牛币交换的,这样就在原先javaniu的零散的表设计基础上抽象出event表
表结构如下:
CREATE TABLE `javaniu_event` ( `id` bigint(20) unsigned NOT NULL auto_increment, `create_time` datetime NOT NULL, `update_time` datetime default NULL, `event_rule_id` bigint(20) NOT NULL default '0' COMMENT '用户注册\r\n下载代码\r\n浏览分享\r\n浏览寻求\r\n收藏分享\r\n收藏寻求\r\n浏览活动\r\n追加悬赏\r\n加入活动\r\n拜师\r\n关注用户\r\n发表心情\r\n发表寻求\r\n评论寻求\r\n评论代码\r\n上传代码\r\n下载代码\r\n分享代码\r\n关注用户\r\n浏览分享\r\n浏览寻求\r\n管理员删除代码\r\n收藏分享\r\n收藏寻求\r\n获取勋章\r\n拜师傅\r\n发起活动\r\n浏览活动\r\n加入活动\r\n追加悬赏\r\n连续一周发表心情\r\n用户周贡献排行\r\n用户月贡献排行\r\n用户年贡献排行\r\n代码下载周排行\r\n代码下载月排行\r\n代码下载年排行', `user_id` bigint(20) NOT NULL default '0', `source_user_id` bigint(20) NOT NULL default '0', `source_id` bigint(20) NOT NULL default '0', `target_id` bigint(20) NOT NULL default '0', `status` int(2) NOT NULL default '0' COMMENT '-1删除0待审核2正常', `type` int(2) NOT NULL default '0', PRIMARY KEY (`id`), KEY `create_time` (`create_time`), KEY `userid_status` (`user_id`,`status`), KEY `event_rule_id_source_id` (`event_rule_id`,`source_id`), KEY `event_rule_id_status` (`event_rule_id`,`status`), KEY `type_source_id` (`type`,`source_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
关联表event_rule可以指定牛币规则及其动态显示信息,结构如下:
CREATE TABLE `javaniu_event_rule` ( `id` bigint(20) unsigned NOT NULL auto_increment, `create_time` datetime NOT NULL, `update_time` datetime default NULL, `type` int(1) NOT NULL COMMENT '注册+1\r\n发表心情+1\r\n连续一周发表心情+5\r\n分享代码+1\r\n分享代码被下载+n(n为分享者者自定义牛币)\r\n寻求代码-2\r\n上传代码+1\r\n上传代码被下载+1\r\n代码被设为最佳+n(n为寻求者者自定义牛币)\r\n删除代码-1\r\n无效寻求-2\r\n无效代码-2\r\n管理员奖赏+n\r\n管理员惩罚-n\r\n周top10+5\r\n月top10+10\r\n年top10+100\r\n信息完善+1\r\n包月vip+100\r\n师傅赠送+n牛币\r\n授予徽章+5牛币\r\n', `name` varchar(100) NOT NULL, `niubi` int(11) NOT NULL, `extend_json` varchar(1000) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
event的用户行为数据模型抽象如下:
模型一:用户a通过事件x产生动态0=user_id_a 0 0 0
a=>x=>0
模型二:用户a通过事件x产生产生用户a的数据1=user_id_a 0 0 1
a=>x=>1
模型三:用户a通过事件x对用户b的数据1产生用户a的数据2=user_id_a b 1 2
a=>x+b+1=>2
模型四:用户a通过事件x对用户b的数据1产生动态0=user_id_a b 1 0
a=>x+b+1=>0
模型五:用户a通过事件x对用户b产生动态0=user_id_a b 0 0
a=>x+b=>0
排列组合:
user_id source_user_id source_id target_id
user_id
user_id source_user_id
user_id source_user_id source_id
user_id source_user_id source_id target_id
这样就囊括了所有会出现的用户event,只要在java层做业务转换即可:
最核心的event数据转换java类源码:
package com.zuidaima.core.service.impl; private void setSourceAndTarget(Event event, EventRule _eventRule) { try { EventRule eventRule = new EventRule(); eventRule.setCreateTime(_eventRule.getCreateTime()); eventRule.setExtendJson(_eventRule.getExtendJson()); eventRule.setId(_eventRule.getId()); eventRule.setName(_eventRule.getName()); eventRule.setNiubi(_eventRule.getNiubi()); eventRule.setType(_eventRule.getType()); eventRule.setUpdateTime(_eventRule.getUpdateTime()); BaseEntity source = null; BaseEntity target = null; long sourceId = event.getSourceId(); long targetId = event.getTargetId(); JSONObject extend = eventRule.getExtend(); extend = eventRule.getExtend(); String description = (String) extend.get("description"); String _description = null; Answer answer = null; Project project = null; switch (eventRule.getType()) { case ModuleConstants.EVENT_TYPE_RULE_PROJECT_CREATE: case ModuleConstants.EVENT_TYPE_RULE_PROJECT_DELETE_BY_USER: case ModuleConstants.EVENT_TYPE_RULE_PROJECT_DELETE_BY_ADMIN: case ModuleConstants.EVENT_TYPE_RULE_PROJECT_VIEW: case ModuleConstants.EVENT_TYPE_RULE_PROJECT_COLLECT: case ModuleConstants.EVENT_TYPE_RULE_PROJECT_REWARD: if (sourceId > 0) { source = projectService.findOneById(sourceId); } if (targetId > 0) { target = projectService.findOneById(targetId); } project = (Project) target; if (source != null) { project = (Project) source; } if (project == null) { return; } _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( project.getType()).getDesc()); break; case ModuleConstants.EVENT_TYPE_RULE_POST_CREATE: case ModuleConstants.EVENT_TYPE_RULE_POST_DELETE_BY_USER: case ModuleConstants.EVENT_TYPE_RULE_POST_DELETE_BY_ADMIN: if (sourceId > 0) { source = postService.findOneById(sourceId); } if (targetId > 0) { target = postService.findOneById(targetId); } Post post = (Post) target; if (source != null) { post = (Post) source; } _description = String.format(description, ModuleConstants.POST_TYPE_DESC_MAP.get(post.getType())); break; // case ModuleConstants.EVENT_TYPE_RULE_GROUP_CREATE://暂时没有这种动态 case ModuleConstants.EVENT_TYPE_RULE_GROUP_JOIN_IN: case ModuleConstants.EVENT_TYPE_RULE_GROUP_DELETE_BY_USER: // case // ModuleConstants.EVENT_TYPE_RULE_GROUP_DELETE_BY_ADMIN://暂时没有这种动态 if (sourceId > 0) { source = groupService.findOneById(sourceId); } if (targetId > 0) { target = groupService.findOneById(targetId); } Group group = (Group) source; _description = String .format(description, ModuleConstants.GROUP_TYPE_DESC_MAP.get(group .getType())); break; case ModuleConstants.EVENT_TYPE_RULE_COMMENT_CREATE: case ModuleConstants.EVENT_TYPE_RULE_COMMENT_DELETE_BY_USER: case ModuleConstants.EVENT_TYPE_RULE_COMMENT_DELETE_BY_ADMIN: target = commentService.findOneById(targetId); Comment comment = (Comment) target; int commentType = comment.getType(); if (commentType == ModuleConstants.COMMENT_TYPE_ANSWER) { source = answerService.findOneById(sourceId); answer = (Answer) source; project = (Project) answer.getTarget(); _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( project.getType()).getDesc()); } else if (commentType == ModuleConstants.COMMENT_TYPE_PROJECT) { source = projectService.findOneById(sourceId); project = (Project) source; _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( project.getType()).getDesc()); } else if (commentType == ModuleConstants.COMMENT_TYPE_POST) { source = postService.findOneById(sourceId); post = (Post) source; _description = String.format(description, ModuleConstants.POST_TYPE_DESC_MAP.get(post .getType())); } else { } break; case ModuleConstants.EVENT_TYPE_RULE_ANSWER_CREATE: case ModuleConstants.EVENT_TYPE_RULE_ANSWER_BEEN_SET_PERFECT: source = projectService.findOneById(sourceId); target = answerService.findOneById(targetId); project = (Project) source; _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( project.getType()).getDesc()); break; case ModuleConstants.EVENT_TYPE_RULE_ANSWER_GET: case ModuleConstants.EVENT_TYPE_RULE_ANSWER_DELETE_BY_USER: case ModuleConstants.EVENT_TYPE_RULE_ANSWER_DELETE_BY_ADMIN: source = answerService.findOneById(sourceId); answer = (Answer) source; Project _project = (Project) answer.getTarget(); _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( _project.getType()).getDesc()); break; case ModuleConstants.EVENT_TYPE_RULE_REPUTATION_CREATE: if (sourceId > 0) { source = reputationService.findOneById(sourceId); } if (targetId > 0) { target = reputationService.findOneById(targetId); } break; case ModuleConstants.EVENT_TYPE_RULE_USER_FOLLOW: source = userService.findOneById(sourceId); User _user = (User) source; _description = String .format(description, "<a href='/user/n/" + _user.getName() + ".htm'>" + _user.getName() + "</a>"); break; case ModuleConstants.EVENT_TYPE_RULE_MENTION_COMMENT: target = commentService.findOneById(targetId); comment = (Comment) target; commentType = comment.getType(); if (commentType == ModuleConstants.COMMENT_TYPE_ANSWER) { source = answerService.findOneById(sourceId); answer = (Answer) source; project = (Project) answer.getTarget(); _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( project.getType()).getDesc()); } else if (commentType == ModuleConstants.COMMENT_TYPE_PROJECT) { source = projectService.findOneById(sourceId); project = (Project) source; _description = String.format( description, ModuleConstants.PROJECT_TYPE_DESC_MAP.get( project.getType()).getDesc()); } else if (commentType == ModuleConstants.COMMENT_TYPE_POST) { source = postService.findOneById(sourceId); post = (Post) source; _description = String.format(description, ModuleConstants.POST_TYPE_DESC_MAP.get(post .getType())); } else { } break; case ModuleConstants.EVENT_TYPE_RULE_MENTION_POST: source = postService.findOneById(sourceId); break; default: _description = description; } extend.put("description", _description); eventRule.setExtend(extend); eventRule.setExtendJson(extend.toString()); event.setEventRule(eventRule); event.setSource(source); event.setTarget(target); } catch (Exception e) { logger.error("Fail to setSourceAndTarget event:" + event); } }
freemarker显示层转换核心代码:
<#switch event.eventRule.type> <#case event_type_rule_post_create> <@event_post_macro event.target/> <#break> <#case event_type_rule_project_create> <@event_project_macro event event.target/> <#break> <#case event_type_rule_project_view> <#case event_type_rule_project_collect> <#case event_type_rule_project_reward> <@event_project_macro event event.source/> <#break> <#case event_type_rule_comment_create> <@event_comment_macro event event.target/> <#break> <#case event_type_rule_answer_create> <@event_answer_macro event event.target/> <#break> <#case event_type_rule_answer_get> <#case event_type_rule_answer_been_set_perfect> <@event_answer_macro event event.source/> <#break> <#case event_type_rule_mention_comment> <@event_comment_macro event event.target/> <#break> <#case event_type_rule_mention_post> <@event_post_macro event.source/> <#break> </#switch>
比如其中一种event type的freemarker macro代码如下:
<!--event post--> <#macro event_post_macro post> <div class="content margin_top5"> ${post.contentExt} <span class="comments_count"> <a target="_blank" href="/mood/${post.id}/comment.htm" rel="nofollow"><img src="/static/imghw/default1.png" data-src="/resource/img/comment.gif" class="lazy" alt="${post.thirdSort}个评论"> ${post.thirdSort}</a> </span> </div> </#macro>
这样的设计符合高内聚低耦合的设计思路,未来可以根据业务实现无限扩张,当然代价就是event表越来越大,但可以通过分库分表来分担压力,大家可以参考下,有好的意见可以留言。

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

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

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

在创建虚拟机时,系统会要求您选择磁盘类型,您可以选择固定磁盘或动态磁盘。如果您选择了固定磁盘,后来意识到需要动态磁盘,或者相反,该怎么办?好!你可以把一种转换成另一种。在这篇文章中,我们将看到如何将VirtualBox固定磁盘转换为动态磁盘,反之亦然。动态磁盘是一种虚拟硬盘,它最初具有较小的大小,随着您在虚拟机中存储数据,其大小会相应增长。动态磁盘在节省存储空间方面非常高效,因为它们只占用所需的主机存储空间。然而,随着磁盘容量的扩展,可能会稍微影响计算机的性能。固定磁盘和动态磁盘是虚拟机中常用的

4月17日消息,HMD携手知名啤酒品牌喜力以及创意公司Bodega,联袂推出了一款别具一格的翻盖手机——无聊手机(TheBoringPhone)。这款手机不仅在设计上充满新意,更在功能上返璞归真,旨在引领人们回归真实的人际交往,享受与朋友畅饮的纯粹时光。无聊手机采用了独特的透明翻盖设计,展现出一种简约而不失优雅的美感。其内部配备了2.8英寸QVGA显示屏,外部则是一块1.77英寸的显示屏,为用户提供了基本的视觉交互体验。在摄影方面,虽然仅搭载了30万像素的摄像头,但足以应对日常的简

4月26日消息,中兴5G随身Wi-FiU50S目前已经正式开售,首发899元。外观设计上,中兴U50S随身Wi-Fi简约时尚,易于手持和包装。其尺寸为159/73/18mm,携带方便,让您随时随地畅享5G高速网络,实现畅行无阻的移动办公与娱乐体验。中兴5G随身Wi-FiU50S该设备支持先进的Wi-Fi6协议,峰值速率高达1800Mbps,依托骁龙X55高性能5G平台,为用户提供极速的网络体验。不仅支持5G双模SA+NSA网络环境和Sub-6GHz频段,实测网速更可达惊人的500Mbps,轻松满

4月3日消息,台电即将推出的M50Mini平板电脑是一款功能丰富、性能强大的设备。这款8英寸小平板新品搭载了8.7英寸的IPS屏幕,为用户提供了出色的视觉体验。其金属机身设计不仅美观,还增强了设备的耐用性。在性能方面,M50Mini搭载了紫光展锐T606八核处理器,拥有两个A75核心和六个A55核心,确保了流畅且高效的运行体验。同时,该平板还配备了6GB+128GB的存储方案,并支持8GB内存扩展,满足了用户对于存储和多任务处理的需求。在续航上,M50Mini配备了5000mAh的电池,支持Ty

7月12日消息,荣耀MagicV3系列今日正式发布,搭载全新荣耀视力舒缓绿洲护眼屏,在屏幕本身具备高规格和高素质的同时,还开创性的引入AI主动式护眼技术。据悉,传统的缓解近视的方式是“近视镜”,近视眼镜度数均匀分布,保证了视线中心区域成像在视网膜之上,但周边区域成像在视网膜后,视网膜感应到成像在后,促进眼轴向后生长,从而使度数加深。目前主要的缓解近视发展的方式之一是“离焦镜”,其中心区域度数正常,周边区域通过光学设计分区调整,从而使周边区域成像落在视网膜前,

在工作中,ppt是职场人士常常使用的办公软件。一个完整的ppt必须有一个好的结束页。不同的职业要求赋予不同的ppt制作特点。关于结束页的制作,如何才能设计的比较吸引人呢?下边我们一起看一看,如何设计ppt结束页吧!ppt结束页的设计可以在文字和动画方面进行一些调整,根据需要选择简洁或炫目的风格。接下来,我们将重点关注如何通过创新的表达方式来打造出符合要求的ppt结束页。那我们开始今天的教程吧。1、对于结束页的制作上,使用图片中的任何文字都可以,结束页重要的是表示我的演示结束了。2、除了这些文字,

7月29日消息,荣耀X60i手机今日正式开售,首发1399元。设计上,荣耀X60i手机采用居中挖孔直屏设计,四边近乎无界的超窄边框,极大地拓宽了视野边界。荣耀X60i参数显示屏:6.7英寸高清显示屏电池:5000mAh大容量电池处理器:天玑6080处理器(台积电6nm,2x2.4G的A76+6×2G的A55)系统:MagicOS8.0系统其他功能:5G信号增强灵动胶囊屏下指纹双MIC降噪知识问答摄影能力:后置双摄系统:5000万像素主摄200万像素辅助镜头前置自拍镜头:800万像素价格:8GB

在Linux操作系统中处理文件需要使用各种命令和技术,使开发人员能够高效地创建和执行文件、代码、程序、脚本和其他东西。在Linux环境中,扩展名为”.a”的文件作为静态库具有重要的重要性。这些库在软件开发中发挥着重要作用,允许开发人员有效地管理和共享多个程序的公共功能。对于Linux环境中的有效软件开发,了解如何创建和运行“.a”文件至关重要。本文将介绍如何全面安装和配置Linux“.a”文件,让我们一起探索Linux“.a”文件的定义、用途、结构,以及创建和执行它的方法。什么是L
