首頁 資料庫 mysql教程 最代码网站中关于动态表event的设计思路

最代码网站中关于动态表event的设计思路

Jun 07, 2016 pm 03:57 PM
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/" &#43; _user.getName()
										&#43; ".htm'>" &#43; _user.getName() &#43; "</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:" &#43; 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表越来越大,但可以通过分库分表来分担压力,大家可以参考下,有好的意见可以留言。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

將VirtualBox固定磁碟轉換為動態磁碟,反之亦然 將VirtualBox固定磁碟轉換為動態磁碟,反之亦然 Mar 25, 2024 am 09:36 AM

在建立虛擬機器時,系統會要求您選擇磁碟類型,您可以選擇固定磁碟或動態磁碟。如果您選擇了固定磁碟,後來意識到需要動態磁碟,或者相反,該怎麼辦?好!你可以把一種轉換成另一種。在這篇文章中,我們將看到如何將VirtualBox固定磁碟轉換為動態磁碟,反之亦然。動態磁碟是一種虛擬硬碟,它最初具有較小的大小,隨著您在虛擬機器中儲存數據,其大小會相應增長。動態磁碟在節省儲存空間方面非常高效,因為它們只佔用所需的主機儲存空間。然而,隨著磁碟容量的擴展,可能會稍微影響電腦的效能。固定磁碟和動態磁碟是虛擬機器中常用的

首發899元 中興5G隨身Wi-Fi U50S開賣:最高網速500Mbps 首發899元 中興5G隨身Wi-Fi U50S開賣:最高網速500Mbps Apr 26, 2024 pm 03:46 PM

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,輕鬆滿

復古潮流! HMD與喜力聯合推出翻蓋手機:透明外殼設計 復古潮流! HMD與喜力聯合推出翻蓋手機:透明外殼設計 Apr 17, 2024 pm 06:50 PM

4月17日消息,HMD攜手知名啤酒品牌喜力以及創意公司Bodega,聯袂推出了一款獨特的翻蓋手機-無聊手機(TheBoringPhone)。這款手機不僅在設計上充滿新意,更在功能上返璞歸真,旨在引領人們回歸真實的人際交往,享受與朋友暢飲的純粹時光。無聊手機採用了獨特的透明翻蓋設計,展現出簡約而不失優雅的美感。其內部配備了2.8英寸QVGA顯示屏,外部則是一塊1.77英寸的顯示屏,為用戶提供了基本的視覺交互體驗。在攝影方面,雖然僅搭載了30萬畫素的鏡頭,但足以應付日常的簡

榮耀Magic V3首發AI離焦護眼技術:有效緩和近視發展 榮耀Magic V3首發AI離焦護眼技術:有效緩和近視發展 Jul 18, 2024 am 09:27 AM

7月12日消息,榮耀MagicV3系列今日正式發布,搭載全新榮耀視力舒緩綠洲護眼屏,在屏幕本身俱備高規格和高素質的同時,還開創性的引入AI主動式護眼技術。據悉,傳統的緩解近視的方式是“近視鏡”,近視眼鏡度數均勻分佈,保證了視線中心區域成像在視網膜之上,但周邊區域成像在視網膜後,視網膜感應到成像在後,促進眼軸向後生長,從而使度數加深。目前主要的緩解近視發展的方式之一是“離焦鏡”,其中心區域度數正常,週邊區域透過光學設計分區調整,從而使周邊區域成像落在視網膜前,

台電M50 Mini小平板來了:8.7吋IPS螢幕、5000mAh電池 台電M50 Mini小平板來了:8.7吋IPS螢幕、5000mAh電池 Apr 04, 2024 am 08:31 AM

4月3日消息,台電即將推出的M50Mini平板電腦是一款功能豐富、效能強大的裝置。這款8吋小平板新品搭載了8.7吋的IPS螢幕,為用戶提供了出色的視覺體驗。其金屬機身設計不僅美觀,也增強了設備的耐用性。在性能方面,M50Mini搭載了紫光展銳T606八核心處理器,擁有兩個A75核心和六個A55核心,確保了流暢且高效的運作體驗。同時,該平板還配備了6GB+128GB的儲存方案,並支援8GB記憶體擴展,滿足了用戶對於儲存和多任務處理的需求。在續航上,M50Mini配備了5000mAh的電池,支援Ty

如何使用Copilot產生程式碼 如何使用Copilot產生程式碼 Mar 23, 2024 am 10:41 AM

身為一名程式設計師,對於能夠簡化程式設計體驗的工具,我感到非常興奮。借助人工智慧工具的幫助,我們可以產生演示程式碼,並根據需求進行必要的修改。在VisualStudioCode中新引入的Copilot工具讓我們能夠創建具有自然語言聊天互動的AI生成程式碼。透過解釋功能,我們可以更好地理解現有程式碼的含義。如何使用Copilot產生程式碼?要開始,我們首先需要取得最新的PowerPlatformTools擴充。要實現這一點,你需要進入擴充頁面,搜尋“PowerPlatformTool”,然後點擊Install按鈕

ppt結束頁如何設計才夠吸引人 ppt結束頁如何設計才夠吸引人 Mar 20, 2024 pm 12:30 PM

在工作中,ppt是職場人士常使用的辦公室軟體。一個完整的ppt必須有一個好的結束頁。不同的職業要求賦予不同的ppt製作特色。關於結束頁的製作,如何才能設計的比較吸引人呢?下邊我們一起看一看,如何設計ppt結束頁吧! ppt結束頁的設計可以在文字和動畫方面進行一些調整,根據需要選擇簡潔或炫目的風格。接下來,我們將重點放在如何透過創新的表達方式來打造出符合要求的ppt結束頁。那我們就開始今天的教學吧。 1.對於結束頁的製作上,使用圖片中的任何文字都可以,結束頁重要的是表示我的簡報結束了。 2、除了這些文字,

vivo訊號最強手機! vivo X100s搭載寰宇訊號放大系統:21天線、360°環繞設計 vivo訊號最強手機! vivo X100s搭載寰宇訊號放大系統:21天線、360°環繞設計 Jun 03, 2024 pm 08:41 PM

5月13日消息,vivoX100s今晚正式發布,除了出色的影像,新機在訊號方面表現也十分強悍。根據vivo官方介紹,vivoX100s採用了創新的寰宇訊號放大系統,該系統配備了高達21根天線。這項設計基於直屏進行了重新優化,以平衡5G、4G、Wi-Fi、GPS以及NFC等眾多訊號需求。這使得vivoX100s成為了vivo有史以來訊號接收能力最強的手機。新款手機還採用了獨特的360°環繞設計,天線分佈在機身周圍。這項設計不僅增強了訊號的強度,還針對日常各種握持姿勢進行了優化,避免了因握持方式不當導

See all articles