类似QQ空间的社交网站的用户动态的数据库应该怎么设计

类似QQ空间的社交网站的用户动态的数据库应该怎么设计,第1张

动态的结构: { user_id:13, action: 行为, object_id: 对象ID, object_type: 对象类型, object_user_id: 对象用户ID, parent_object_id: 对象父级ID, parent_object_type: 对象父级类型, parent_object_user_id: 对象父级用户ID, reply_id: 回复ID, // action为回复时有用 parent_reply_id: 回复的父级回复ID, // action为回复时有用,回复了别人对评论的回复 text: '转发或者分享时附加文字', view_count: 0, created_at: 创建时间, deleted_at: 删除时间, } 说明: 1.object_*只存储主要模块内容信息,不含评论; 2.parent_object_*存储有嵌套关系的对象,比如当object_*为答案时,parent_object_*为问题; 3.reply_id用于直接回复评论时用到; 4.parent_reply_id父回复ID5. 两个回复ID,使用情况是:当回复了别人的回复时,根据comment_id拉取评论与全部回复,在模板显示时只显示对话的两个回复。 场景列表: 一级结构: 安正超发布了文章 'action' =>NEW, 'user_id' =>安正超ID, 'object_id' =>文章ID, 'object_user_id' =>安正超ID, 'object_type' =>ARTICLE, 安正超上传 了 N张 图片 'action' =>NEW, 'user_id' =>安正超ID, 'object_id' =>图片ID(数组,以逗号隔开), 'object_user_id' =>安正超ID, 'object_type' =>PICTURE, 安正超提了问题xxxx 'action' =>NEW, 'user_id' =>安正超ID, 'object_id' =>问题ID, 'object_user_id' =>安正超ID, 'object_type' =>QUESTION 二级结构: 安正超评论了文章xxxx(回答了通用) 展示: 文章: xxxxx 评论:xxxxx (李林评论的) 'action' =>COMMENT, 'user_id' =>安正超ID, 'object_id' =>评论ID, 'object_type' =>COMMENT, 'object_user_id' =>安正超ID 'parent_object_id' =>文章ID, 'parent_object_user_id' =>作者ID 'parent_object_type' =>ARTICLE, 三级结构: 安正超在文章中回复了李林的评论 展示: 文章: xxxxx 评论:xxxxx (李林评论的) 回复:xxxx (安正超) 'action' =>REPLY, 'user_id' =>安正超ID, 'object_id' =>评论ID, 'object_type' =>COMMENT, 'object_user_id' =>李林ID 'parent_object_id' =>文章ID, 'parent_object_user_id' =>作者ID 'parent_object_type' =>ARTICLE, 'reply_id' =>安正超的回复ID 四级结构: 安正超回复了李文凯在问题 “xxxx” 中 李林的答案下的评论 说明:问题信息从答案接口取回 展示: 问题: xxxxx 答案1... 答案2... 答案3...(李林回答的) 评论:xxxxx (李文凯评论的) 回复:xxxx (安正超) 'action' =>RESPOND, 'user_id' =>安正超ID, 'object_id' =>评论ID, 'object_type' =>COMMENT, 'object_user_id' =>李文凯的ID 'parent_object_id' =>答案ID, 'parent_object_type' =>ANSWER, 'parent_object_user_id' =>李林ID 'reply_id' =>安正超的回复ID

可以采用四种技术:

动态增加数据库表字段

预留足够的空白字段,运行时作动态影射

用xml格式保存在单字段里

改列为行,用另外一个表存放定制字段

【一】

现在我们来分析一下四种技术的优劣,不过首先可以排除的是第一点动态增加字段的方法,因为在实际 *** 作时候几乎是不可能的(sqlserver太慢,oracle索性不支持),基本可以不讨论就排除。剩下后三点。

【二】

先来讨论预留空白字段的方法,基本原理就是在数据库表设计的时候加入一些多余的字段,看下面的代码:

CREATE TABLE Sample(

name varchar(12),

field0 varchar(1),

field1 varchar(1),

fieldN varchar(1)

}

然后看实际运行时候的需要,动态分配字段给系统使用,也许需要一个这样的结构来描述分配情况:

public class Available

{

public int CurrentUnusedFieldNumber

public Hashtable FieldToRealName

}

也许某一时刻的数据状况是这样的: CurrentUnusedFieldNumber=3,

哈西表FieldToRealName包含内容是("field0"="SomeId", "field1"="AnyName",

"field2=IsOk")

现在的问题是如果要配合Hibernate,如何来处理?以上段的数据使用状况为例子,如果我们的类定义是这样:

public class Entity01

{

public string Name

public string SomeId

public string AnyName

public bool IsOk

}

也许只需要修改一下xxx.hbm.xml,把 SomeId 和 field0

做成对应就ok了。但是在运行时我们怎么知道会有这样的类定义?除非我们做动态代码生成,自动编译也许可以,但是问题也许就到其他方面去了;如果我们不用动态定义,那么类就只能是这样:

public class Entity01

{

public string Name

public Hashtable ExtraFieldAndValues

}

使用的时候,用 entity01.ExtraFieldAndValues.setValue("AnyName", "boss")

的方式来引用,也许这样是修改最少的了,但是问题是Hibernate不支持这样的方法。

【三】

再来讨论单字段存储的方法,我们使用这样的数据库表定义

CREATE TABLE Sample

(

Name varchar(12),

Xml CLOB(102400) // 仅作说明而已

)

然后对应这样的类定义

public class Entity01

{

public string Name

public string Xml

public Hashtable ExtraNameAndValueFromXml

}

我们的代码就可以这样使用:string id =

entity01.ExtraNameAndValueFromXml.getValue("SomeId")

了。这样解决看起来很不错,不仅不需要Available表,而且看起来Hibernate对它的支持也很完美,但是致命的问题在于:如果保持高效的查询?除非数据库系统本身对此有支持,否则就只能用低效的substring或者like做查询,这在大批量数据中根本就不可行。

是不是折衷一下,把两种方法的优点和起来?问题有来了:怎么保持两者之间数据的同步?难道要我们用存储过程去解析xml内容?

所以,一个两难的问题,需要我们认真去解决。我们通过认真的需求分析,也许可以减少可变字段的数量,但是只要有一个可变字段或者可变的可能性存在,我们始终要去解决这个两难的问题。

期待继续讨论。

【四】

还有一种方法就是改列为行,用另外一个表存放扩展字段,定义可以如下:

CREATE

TABLE SampleFields

(

idSample Integer,

fieldName varchar(30),

fieldValue varchar(100)

)

其中idSample关联到Sample表的id字段(我没有写出来)。这样的话,Hibernate很容易支持,也可以支持Sql的查询,而且可以支持把内容放到Hashtable中去,看起来是目前最好的方式了。但是在大容量数据的时候,SampleFields表的数据会是主表数据量的N倍(看定制的字段数目多少而定),同样存在有很严重的性能问题。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6644905.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-26
下一篇 2023-03-26

发表评论

登录后才能评论

评论列表(0条)

保存