数据库设计中冗余字段的两个小应用【转】

peng_wu01 2013-08-30 04:59:30
1. 时间显示冗余字段。

在表中如果有时间字段,比如存储记录业务时间,我们一般会把时间化为数字进行存储,主要的目的是为了方便比较,但是问题就在于在显示的时候面临一个转换的问题,必须要转成有格式有文字的样式。

初始时我的做法就是写个工具类然后遇到此类的情况就不停的来回转,返回查询结果数据之前完整的遍历一遍List,现在想想有点不应该,浪费了服务端的好多资源,后来又变成了在页面显示时利用extjs的render方法去转换,这样又延缓了页面呈现时间。

现在想明白了,完全可以在数据库里多加一个字段,存储的就是用于显示格式的时间,仅仅用于显示,那么如果这样做带来的影响也不是很大,插入的时候多处理一个字段,把数字转换成显示格式存进去,但是查询和显示的时候就带来了极大的方便。效率上几乎没有损耗。这个问题太容易遇到,非常推荐大家采用。



2. 用于乱序排序的随机数字段

大部分的数据库业务记录都是有顺序存储的,一般是时间或者id,但是有时候我们需要拿出一个乱序的集合,比如我们要处理一个报名考试的拍考场问题。

以往的做法是把整个表都拿出来,然后放入一个List1,然后从List1随机的去除元素然后依次放入List2,再将List2返回,效率低自然是不必说了。

后来的解决方案变成在表中多加入一个随机数字段,插入数据的时候顺手把生成的随机数插入进去,查询的时候直接order by这随机数字段,出来的结果就已经是乱序的,而且又不影响其他业务的正常查询,效率高了不止一点两点。
...全文
280 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
舟之桥 2013-09-04
  • 打赏
  • 举报
回复
引用 24 楼 ldh911 的回复:
[quote=引用 23 楼 piaoboyijianke1 的回复:] 那楼主说的,第二种情况是适用你这种场景的喽
我觉得不一样,楼主的场景是排考场,那么直接把结果记录考试座位表即可;最终目的应该是出座位表,也就是哪个考生被抽进哪个考场的座位上;不需要记录原始随机顺序。 另一种适用场景是非重复伪随机,必须要求能高效的获取100万以内的非重复随机数;那么这种情况下可以预先准备一个记录了100W行的非重复随机数表;后续要得到随机数时只需要随机设置一个起始位,再加上一个随机素数当作增量,就可以连续获得100W个非重复的随机数;而且这个表还可以重复利用。[/quote] 嗯,学习了
MiceRice 2013-09-04
  • 打赏
  • 举报
回复
引用 23 楼 piaoboyijianke1 的回复:
那楼主说的,第二种情况是适用你这种场景的喽
我觉得不一样,楼主的场景是排考场,那么直接把结果记录考试座位表即可;最终目的应该是出座位表,也就是哪个考生被抽进哪个考场的座位上;不需要记录原始随机顺序。 另一种适用场景是非重复伪随机,必须要求能高效的获取100万以内的非重复随机数;那么这种情况下可以预先准备一个记录了100W行的非重复随机数表;后续要得到随机数时只需要随机设置一个起始位,再加上一个随机素数当作增量,就可以连续获得100W个非重复的随机数;而且这个表还可以重复利用。
舟之桥 2013-09-04
  • 打赏
  • 举报
回复
引用 22 楼 ldh911 的回复:
[quote=引用 21 楼 piaoboyijianke1 的回复:] 随机结果可再现 这个是什么一个场景
首次生成是必须是随机的,但以后则需要能够准确反查每个序号下的随机值。 类似于大家集体摇号,后面总是能查到此次摇号的结果。[/quote] 那楼主说的,第二种情况是适用你这种场景的喽
MiceRice 2013-09-04
  • 打赏
  • 举报
回复
引用 21 楼 piaoboyijianke1 的回复:
随机结果可再现 这个是什么一个场景
首次生成是必须是随机的,但以后则需要能够准确反查每个序号下的随机值。 类似于大家集体摇号,后面总是能查到此次摇号的结果。
舟之桥 2013-09-04
  • 打赏
  • 举报
回复
引用 20 楼 ldh911 的回复:
[quote=引用 19 楼 piaoboyijianke1 的回复:] 楼主说的方法,我觉得还是很有道理, 就拿CET-4来说,考生应该是随机获得一个准考证号,然后按准考证号进行排考场,从而达到随机排序的目的
楼主说的方法并不是没有价值,而是在他所介绍的场景中没有道理。 实际上用数据库做伪随机记录,生产系统不是没有用到的。我所设计的系统中就采用过这种方案,数据规模是千万级别。而俺说的这个场景恰好就是要求:“随机结果可再现”。[/quote] 随机结果可再现 这个是什么一个场景
MiceRice 2013-09-02
  • 打赏
  • 举报
回复
引用 19 楼 piaoboyijianke1 的回复:
楼主说的方法,我觉得还是很有道理, 就拿CET-4来说,考生应该是随机获得一个准考证号,然后按准考证号进行排考场,从而达到随机排序的目的
楼主说的方法并不是没有价值,而是在他所介绍的场景中没有道理。 实际上用数据库做伪随机记录,生产系统不是没有用到的。我所设计的系统中就采用过这种方案,数据规模是千万级别。而俺说的这个场景恰好就是要求:“随机结果可再现”。
舟之桥 2013-09-02
  • 打赏
  • 举报
回复
楼主说的方法,我觉得还是很有道理, 就拿CET-4来说,考生应该是随机获得一个准考证号,然后按准考证号进行排考场,从而达到随机排序的目的
舟之桥 2013-09-02
  • 打赏
  • 举报
回复
我觉得,第二个问题是很有讨论价值的
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
好吧,虽然我想继续和你辩论下去,我突然发现没必要了。CSDN果然是个没多大营养的地方。
引用 16 楼 ldh911 的回复:
[quote=引用 13 楼 peng_wu01 的回复:] 方案1,依赖数据库可以做成,但是问题是打破了OO,在有持久层框架存在的时候无法简单实现;格式化控件无法再导出报表时和grid显示时使用。 方案2,还是数据库函数应不应该被依赖的问题,我坚决持反对意见。
方案1,可能你接触的展示组件还比较少,HTML端组件是很丰富的。 方案2,不存在绝对不依赖数据库的方案,简单举例:分页算法你怎么来个“不依赖数据库”?而且你的方案生成随机数是固定的,这个貌似也不符合 随机 的要求。[/quote]
MiceRice 2013-09-02
  • 打赏
  • 举报
回复
引用 13 楼 peng_wu01 的回复:
方案1,依赖数据库可以做成,但是问题是打破了OO,在有持久层框架存在的时候无法简单实现;格式化控件无法再导出报表时和grid显示时使用。 方案2,还是数据库函数应不应该被依赖的问题,我坚决持反对意见。
方案1,可能你接触的展示组件还比较少,HTML端组件是很丰富的。 方案2,不存在绝对不依赖数据库的方案,简单举例:分页算法你怎么来个“不依赖数据库”?而且你的方案生成随机数是固定的,这个貌似也不符合 随机 的要求。
无聊找乐 2013-09-02
  • 打赏
  • 举报
回复
引用 4 楼 peng_wu01 的回复:
[quote=引用 3 楼 rainbowsix 的回复:] 2.每次查询的结果都一样,还叫能叫随机吗
如果是拍考场次序,那么每次查询的都是随机的,那每次打印的时候都得到不一样的排序结果,请问还如何安排考试。[/quote] 既然如此 你为何要 插入数据的时候顺手把生成的随机数插入进去 ? 有何意义?
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
引用 10 楼 rumlee 的回复:
[quote=引用 9 楼 peng_wu01 的回复:] [quote=引用 7 楼 rumlee 的回复:] 第1条说的还是有可取性,第2条说的我觉得不太可取。如果真是用于排考场这种需求的话,这种做法导致一开始每个学生对应座位就已经确定了,容易导致作弊。 我对于数据库冗余用的比较多的地方,我也分享一下: 1、用数据字典的字段,例如学历,我一般会设置两个字段,一个存储01、02这种编码,一个存储本科、大专这种用于显示。 2、与用户表关联的表内的用户字段,我一般也用两个字段,一个存储用户编码,一个存储用户名称,方便显示。
每一门的考试的考场安排肯定都是从选这门课的学生的表里选出来然后随机插入考场安排表的,每次数据插入都有可能带来顺序的变化,这样做又保证了在考试学生数目确认以后每次导出的时候得到的结果是一样的,以方便丢失了考场安排表重新查询。 话说,学生怎么会提前知道自己的考场座号呢?排考场的老师不主动去说,谁会知道?[/quote] 我觉得不应该这么做,而应该由管理员手工操作来生成随机顺序,而不是一插入就生成一个随机数,这样比较可靠。为了每次导出顺序不变,这可以生成顺序之后,再把顺序回写入数据库啊。[/quote] 管理员巴不得啥都不干就把排好的考场给他看,他能手动去做这些事情; 即使是管理员愿意做,那么把数据存回去岂不是是平白无故的多了次数据库访问又回到了原点?
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
引用 11 楼 ldh911 的回复:
[quote=引用 5 楼 peng_wu01 的回复:] 案例1您有更好的方案,请赐教! 案列2,请问您遇到随机排考场,如何解决?
方案1,除了数据库字符串运算(这个数据库一定有提供,但写法不统一),一些展示组件也能很好的解决日期格式化问题。除非是在性能上有极限需求,才会使用“静态化”的手段。 方案2,其实1楼给的建议就对了;可以放心,基本上所有数据库都提供“随机函数”,就是用这个来作为排序关键字即可。[/quote] 方案1,依赖数据库可以做成,但是问题是打破了OO,在有持久层框架存在的时候无法简单实现;格式化控件无法再导出报表时和grid显示时使用。 方案2,还是数据库函数应不应该被依赖的问题,我坚决持反对意见。
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
认真我就输了!
MiceRice 2013-09-02
  • 打赏
  • 举报
回复
引用 5 楼 peng_wu01 的回复:
案例1您有更好的方案,请赐教! 案列2,请问您遇到随机排考场,如何解决?
方案1,除了数据库字符串运算(这个数据库一定有提供,但写法不统一),一些展示组件也能很好的解决日期格式化问题。除非是在性能上有极限需求,才会使用“静态化”的手段。 方案2,其实1楼给的建议就对了;可以放心,基本上所有数据库都提供“随机函数”,就是用这个来作为排序关键字即可。
rumlee 2013-09-02
  • 打赏
  • 举报
回复
引用 9 楼 peng_wu01 的回复:
[quote=引用 7 楼 rumlee 的回复:] 第1条说的还是有可取性,第2条说的我觉得不太可取。如果真是用于排考场这种需求的话,这种做法导致一开始每个学生对应座位就已经确定了,容易导致作弊。 我对于数据库冗余用的比较多的地方,我也分享一下: 1、用数据字典的字段,例如学历,我一般会设置两个字段,一个存储01、02这种编码,一个存储本科、大专这种用于显示。 2、与用户表关联的表内的用户字段,我一般也用两个字段,一个存储用户编码,一个存储用户名称,方便显示。
每一门的考试的考场安排肯定都是从选这门课的学生的表里选出来然后随机插入考场安排表的,每次数据插入都有可能带来顺序的变化,这样做又保证了在考试学生数目确认以后每次导出的时候得到的结果是一样的,以方便丢失了考场安排表重新查询。 话说,学生怎么会提前知道自己的考场座号呢?排考场的老师不主动去说,谁会知道?[/quote] 我觉得不应该这么做,而应该由管理员手工操作来生成随机顺序,而不是一插入就生成一个随机数,这样比较可靠。为了每次导出顺序不变,这可以生成顺序之后,再把顺序回写入数据库啊。
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
引用 7 楼 rumlee 的回复:
第1条说的还是有可取性,第2条说的我觉得不太可取。如果真是用于排考场这种需求的话,这种做法导致一开始每个学生对应座位就已经确定了,容易导致作弊。 我对于数据库冗余用的比较多的地方,我也分享一下: 1、用数据字典的字段,例如学历,我一般会设置两个字段,一个存储01、02这种编码,一个存储本科、大专这种用于显示。 2、与用户表关联的表内的用户字段,我一般也用两个字段,一个存储用户编码,一个存储用户名称,方便显示。
每一门的考试的考场安排肯定都是从选这门课的学生的表里选出来然后随机插入考场安排表的,每次数据插入都有可能带来顺序的变化,这样做又保证了在考试学生数目确认以后每次导出的时候得到的结果是一样的,以方便丢失了考场安排表重新查询。 话说,学生怎么会提前知道自己的考场座号呢?排考场的老师不主动去说,谁会知道?
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
引用 1 楼 forgetsam 的回复:
select tdate from table; select tdate,to_char(tdate,'yyyy-mm-dd') from table; 基本没有性能差异。 select a,b,c from table order by c select a,b,c from table order by sys_guid() 也不见得有什么差异。 真正的冗余是在主表连接代码表时候,可以适当做些冗余,减少与代码表的连接。
另外,您是从数据库的角度考虑这个问题,如果业务代码用了持久层的框架,那么自行定义的sql脚本就对编码过程的OO产生了很大的影响。但是sql编程来说,您的思想是很正确的,但是从系统设计的角度讲,这个想法比较片面,仅仅针对了Oracle,如果技术选型中采用了mysql,那就会带来不少的麻烦。 现在的业务设计方向我觉得还是要把业务运算和处理提升到业务代码中来做,数据库中仅仅做一些CURD,这样不管减轻了数据库的压力,而且更加有利于服务端的集群配置,同时提高系统的拔插性。
rumlee 2013-09-02
  • 打赏
  • 举报
回复
第1条说的还是有可取性,第2条说的我觉得不太可取。如果真是用于排考场这种需求的话,这种做法导致一开始每个学生对应座位就已经确定了,容易导致作弊。 我对于数据库冗余用的比较多的地方,我也分享一下: 1、用数据字典的字段,例如学历,我一般会设置两个字段,一个存储01、02这种编码,一个存储本科、大专这种用于显示。 2、与用户表关联的表内的用户字段,我一般也用两个字段,一个存储用户编码,一个存储用户名称,方便显示。
peng_wu01 2013-09-02
  • 打赏
  • 举报
回复
引用 1 楼 forgetsam 的回复:
select tdate from table; select tdate,to_char(tdate,'yyyy-mm-dd') from table; 基本没有性能差异。 select a,b,c from table order by c select a,b,c from table order by sys_guid() 也不见得有什么差异。 真正的冗余是在主表连接代码表时候,可以适当做些冗余,减少与代码表的连接。
如果“to_char”函数和order by sys_guid()不在数据库里支持怎么办,如何做到多数据库支持,变更数据库的时候是不是会带来影响?
加载更多回复(5)

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧