一个关于数据表设计的问题

0 views
Skip to first unread message

Samuel

unread,
Jan 20, 2010, 10:18:50 AM1/20/10
to pyth...@googlegroups.com
个人认为这是一个非常naive的问题,但无奈,说服不了partner, 特此请教一下各位,给点意见。

我想记录用户成功做完某个操作的时间,理论上每天一条只有一条记录, 然后有一个任务就是每天需要统计一下每个用户当月,当年的登录情况(当月登录多少天,当年登录多少天,总共登录多少天等)
---------------------
我想的设计是建立一个日志表 log(user,date), 用户每成功一次,插入一条记录(用户每天只有一次成功机会,如果有两次就是系统错误,要report出来的)。 做统计的时候,无非就是根据user来做一个select 查询。

---------------------
partner的设计是,在user_profile这样一个表里,增加一个text 字段,如log_info. 这个log_info 是date拼接起来的,如date1,date2,date3. 做法是没天先根据user,读取出log_info, log_info =log_info & date.

理论上来说,每天一条记录,log_info的长度是有限的,不会无限制膨胀。
他这么做的理由有二:
1. 这样记录数会比我的少很多,比如我可能需要10000条记录,而他的设计中只有100条记录。 根据查询的速度取决于记录数,理论上他的查询速度会高于我的, 特别是记录数大的情况下;
2. 从极限的角度来看,我的表可能会崩掉,因为记录数太多



--------------------------

我坚持我的理由:

1. 可扩展性要好,如果我想加点啥,我可以加点;
2. 我写入的速度会远远快于它;当数据库繁忙的时候,我觉得这会成为一个瓶颈。
3, 我做统计的速度会方便很多
4, 我觉得有个text类型文本在数据库里,非常碍眼。 我总是不放心这类型的东西。


最后,请求高手的方案,并希望给出一点点原因。


--
吴焱红( Samuel )


@@

unread,
Jan 20, 2010, 10:21:09 AM1/20/10
to pyth...@googlegroups.com
你可以2个同时采用。。



2010/1/20 Samuel <samuel...@gmail.com>
--
来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
详情: https://groups.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp


诚子

unread,
Jan 20, 2010, 10:29:54 AM1/20/10
to pyth...@googlegroups.com
虽不是数据库高手,但我喜欢LZ的方案,
感觉第二个方案不是很安全。

2010/1/20 @@ <ask...@gmail.com>



--
my.unix-center.net/~WeiZhicheng

Samuel

unread,
Jan 20, 2010, 10:32:18 AM1/20/10
to pyth...@googlegroups.com


2010/1/20 @@ <ask...@gmail.com>
你可以2个同时采用。。
同时采用是什么意思啊。


--
吴焱红( Samuel )


刘鑫

unread,
Jan 20, 2010, 10:52:34 AM1/20/10
to python-cn


2010/1/20 Samuel <samuel...@gmail.com>

个人认为这是一个非常naive的问题,但无奈,说服不了partner, 特此请教一下各位,给点意见。

我想记录用户成功做完某个操作的时间,理论上每天一条只有一条记录, 然后有一个任务就是每天需要统计一下每个用户当月,当年的登录情况(当月登录多少天,当年登录多少天,总共登录多少天等)
---------------------
我想的设计是建立一个日志表 log(user,date), 用户每成功一次,插入一条记录(用户每天只有一次成功机会,如果有两次就是系统错误,要report出来的)。 做统计的时候,无非就是根据user来做一个select 查询。

---------------------
partner的设计是,在user_profile这样一个表里,增加一个text 字段,如log_info. 这个log_info 是date拼接起来的,如date1,date2,date3. 做法是没天先根据user,读取出log_info, log_info =log_info & date.

理论上来说,每天一条记录,log_info的长度是有限的,不会无限制膨胀。
他这么做的理由有二:
1. 这样记录数会比我的少很多,比如我可能需要10000条记录,而他的设计中只有100条记录。 根据查询的速度取决于记录数,理论上他的查询速度会高于我的, 特别是记录数大的情况下;
2. 从极限的角度来看,我的表可能会崩掉,因为记录数太多

两个都反对,日志直接写到文件里吧。
如果一定要挑一个,肯定是你的方法,开玩笑,他那个搞法,不用多了,来个每天几百万访问,就杯具了。


--------------------------

我坚持我的理由:

1. 可扩展性要好,如果我想加点啥,我可以加点;
2. 我写入的速度会远远快于它;当数据库繁忙的时候,我觉得这会成为一个瓶颈。
3, 我做统计的速度会方便很多
4, 我觉得有个text类型文本在数据库里,非常碍眼。 我总是不放心这类型的东西。


最后,请求高手的方案,并希望给出一点点原因。


--
吴焱红( Samuel )



--
来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
详情: https://groups.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp




--
每一行代码都应该出自我手,工具可以帮我写,但不能替我写,更不能替我思考。
……

劉鑫
March.Liu

狗尾草

unread,
Jan 20, 2010, 10:53:24 AM1/20/10
to pyth...@googlegroups.com
楼主的方案相对合理。
拼接字符保存的话,日后处理会很麻烦。比如统计等。

还得从需求入手,分析两种方案的优缺点。
-------------------------------------------------------
Hunk
http://twitter.com/hunkguo



2010/1/20 Samuel <samuel...@gmail.com>

way wrong

unread,
Jan 20, 2010, 11:05:51 AM1/20/10
to pyth...@googlegroups.com
个人感觉你parter的这种作法是用来将关系数据库中的join relation斩断,转变为K/V存储时的常用方法之一,但是我感觉兄台这个项目的记录日志好象关联性不是很强,都可以不用关系数据库来存储日记可以考虑以文件形式保存),就更谈不上用自造的like K/V字段来保存原有关联的必要了,所以你partner的这种方案并不是很实用,保存时还好说,统计的时候可能就比较麻烦了。

有种为了克制困难而制造困难的感觉........


2010/1/20 Samuel <samuel...@gmail.com>

Pan Menghan

unread,
Jan 20, 2010, 11:06:33 AM1/20/10
to python-cn`CPyUG`华蟒用户组(中文Py用户组)
我们公司正使用的一个软件(这个软件不是我写的), 他的数据库是这样设计的:
有三个database: XXX, XXX.log, XXX.right
XXX里面只有业务逻辑相关的表
XXX.log里面只有一个表Log(log_id,log_date,log_operator,log_descript)
XXX.right里面的表是用户和权限相关的, 分别是Groups, RightModuleGroup,
RightModules,UserGroup, Users

tsangpo

unread,
Jan 20, 2010, 11:11:37 AM1/20/10
to pyth...@googlegroups.com
即然要统计,那就按你的方法好。否则如刘老师说的,写log文件。
你的partner那样设计好像连第一范式都通不过哦。

于 2010年01月20日 23:52, 刘鑫 写道:


2010/1/20 Samuel <samuel...@gmail.com>
个 人认为这是一个非常naive的问题,但无奈,说服不了partner, 特此请教一下各位,给点意见。

limodou

unread,
Jan 20, 2010, 11:16:57 AM1/20/10
to pyth...@googlegroups.com
2010/1/20 Samuel <samuel...@gmail.com>:

同意你的方案。

他的理由:

记录少很多我看未必,而且并不是主要问题,还有数据空间的问题。这个要具体分析

同一个表的话,如果放在一个字段中,那么你要考虑最大的存储空间,比如log_info&date1&date2,允许几次date这是可以商量的,如果更多次登录如何处理,存不下了怎么办,而使用一条条的记录方式无此问题。再从你的说明,应该一天就一次,基本上是与用户的数量相关的,和他的数量差不多。从存储上,使用记录有可能要节省,这个要看log_info是什么字段类型,是不是可变长度。如果是定长,那有可能有浪费。处理上基本上登录就要修改,如果是第二天,那么昨天的数据怎么处理?覆盖还是添加?所以处理复杂性上增加。而使用记录时,如果不想处理昨天处理,可以做一个历史数据的加工工作,通过定时方式来执行,不影响正常的业务处理。

一个date字段再加一个用户id占不了多少空间。

--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://uliwebproject.appspot.com
My Blog: http://hi.baidu.com/limodou

limodou

unread,
Jan 20, 2010, 11:17:49 AM1/20/10
to pyth...@googlegroups.com
2010/1/21 tsangpo <tsangpo....@gmail.com>:

> 即然要统计,那就按你的方法好。否则如刘老师说的,写log文件。
> 你的partner那样设计好像连第一范式都通不过哦。
>

log文件的话要考虑是否存在集群的情况,如果存在,还是建议使用数据库。并且后续加工方便,不会慢多少。

way wrong

unread,
Jan 20, 2010, 11:21:11 AM1/20/10
to pyth...@googlegroups.com
“他这么做的理由有二:
1. 这样记录数会比我的少很多,比如我可能需要10000条记录,
而他的设计中只有100条记录。 根据查询的速度取决于记录数,理论上他的查询速度会高于我的, 特别是记录数大的情况下;
2. 从极限的角度来看,我的表可能会崩掉,因为记录数太多


从1来看,在海量小字段数据下确实是有这个问题,但发生这种问题的场景可能会出现在人们的应中。你partner的说法适应用于这样一个应用场景:某特大型网上商城保存顾客的购物记录,如果用through表将顾客表的ID和产品的ID关联起来,并保存购物时间,当时折扣,接待客服等信息,如果购物记录狂增爆增猛增,那么通过through表查询某个顾客A的历史消费纪录时就会比较缓慢,A的信息就会象硬盘碎片一样遍布磁盘的各个角落,只见磁盘灯狂现,还没等到信息出。。。

但是你们的日志记录场景似乎并不强调对某名单个用户进行跟踪?而且数据量也没有大到非常非常可观的地步,

2.从极限的角度来看,你的表恰恰不会崩掉,而是你partner的表先崩。因为你只是简单的插入写,而partner却是读,改,写。

你parnter的这种表设计应该是强调快速得到某单独个体的相关历史数据,我个人感觉并不适用地这种简单的日记记录场景

2010/1/20 Samuel <samuel...@gmail.com>

Samuel

unread,
Jan 20, 2010, 11:21:43 AM1/20/10
to pyth...@googlegroups.com
log文件的话要考虑是否存在集群的情况,如果存在,还是建议使用数据库。并且后续加工方便,不会慢多少。
 
谢谢, log文件之前我也考虑过,就是担心锁的问题,用数据库简单直接,所以就考虑了日志表。

--
吴焱红( Samuel )


way wrong

unread,
Jan 20, 2010, 11:25:06 AM1/20/10
to pyth...@googlegroups.com
键盘坏了,几个键不好使,老打不出字,我更正一下

从1来看,在海量小字段数据下确实是有这个问题,但发生这种问题的场景不怎么可能会出现在你们的应用当中。你partner的做法适应用于这样一个应用场景:


2010/1/21 way wrong <wrong...@gmail.com>

Samuel

unread,
Jan 20, 2010, 11:31:32 AM1/20/10
to pyth...@googlegroups.com


2010/1/21 way wrong <wrong...@gmail.com>

键盘坏了,几个键不好使,老打不出字,我更正一下

从1来看,在海量小字段数据下确实是有这个问题,但发生这种问题的场景不怎么可能会出现在你们的应用当中。你partner的做法适应用于这样一个应用场景:

谢谢way, 我其实是看懂了的。 谢谢 :).  我想如果我们的数据膨胀很厉害,其实主要是用户数的增加会导致膨胀,而每天一条数据的累加并不会膨胀起来。 处理历史数据的方法只要把过去的数据archive起来就可以了,而新的数据放到一个新的表中就可以了。


商场的明细数据,电话清单之类的东西都是有时效性的,电信不给几个月前的电话清单,大概也是这个原因。 这些数据合理的archive起来,索要之前的数据是需要额外付费,大概也是这个理。



--
吴焱红( Samuel )


@@

unread,
Jan 20, 2010, 11:32:44 AM1/20/10
to pyth...@googlegroups.com


2010/1/20 Samuel <samuel...@gmail.com>



2010/1/20 @@ <ask...@gmail.com>
你可以2个同时采用。。
同时采用是什么意思啊。

比如说有一个表来记录每一次的记录
另外user表上还有一个大的字段来记录一年的登录数据(或者一个月?)看你的需求 

pength

unread,
Jan 20, 2010, 8:13:26 PM1/20/10
to python-cn`CPyUG`华蟒用户组(中文Py用户组)
你可以问parter“如果哪天boss要统计某一天有多少个用户登录过,该怎么办?”;)

Samuel

unread,
Jan 20, 2010, 8:51:44 PM1/20/10
to pyth...@googlegroups.com
有道理,我咋没有想到咩 ?



2010/1/21 pength <pen...@163.com>
--
来自: `python-cn`:CPyUG ~ 华蟒用户组 | 发言:pyth...@googlegroups.com
退订: http://tinyurl.com/45a9tb //针对163/qq邮箱:http://tinyurl.com/4dg6hc
详情: https://groups.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp




--
吴焱红( Samuel )


samhoo

unread,
Jan 20, 2010, 10:20:44 PM1/20/10
to pyth...@googlegroups.com
系统的用户场景决定了设计

1、如果每个用户的登录信息累计起来不多,就那么几十条,总数量也不大,哪种方案都无所谓
2、如果每个用户的登录信息累计起来很多,你partne的方案就杯具了,每次都要读出这么长的日志、拼接、更新...,而且很难满足复杂的查询。
3、如果日志是海量的(比如我们有将近1亿/日),楼主用数据库也杯具了。不用担心文件锁的问题,用syslog类的专用日志服务比较靠谱,我们就是这么干的,用awk类的shell工具统计非常高效。

2010/1/21 Samuel <samuel...@gmail.com>
Reply all
Reply to author
Forward
0 new messages