www.dnnworkflow.cn

 

    06年底的时候,关于UDT的结构和其他的一些问题,和Sebastian Leupold通过邮件,因为当时费了很大的劲才弄明白数据到底是怎么给弄出来的,DotNetNuke里面像这么难懂的代码还是不太多的,我的建议是把 UDT的数据结构稍微改一下,弄成让大家更舒服一点的,不过估计是大家交流上还是有点障碍,毕竟E文都不是母语(SL是德国佬);后来想:算了,还是自己 弄吧,于是从这个数据结构出发,把它给优化了一下,成了我的数据结构,希望不会让大家觉得太烂。

    首先再贴一张图,分析一下UserDefinedTable的情况
(原来的数据结构存储)

    我把三张表的数据弄到一块了,这样大家可以看得更清楚一点。上图中可以看到,UserDefinedFields是一 个字段定义器存放的数据,比如我们的字段名称、初始值、顺序等,这个表可以理解为一个“结构表”;而下面的UserDefinedRows是“主记录表 ”,UserDefinedData是“从记录表”。我们的表格结构是存放在Fields表里面的,而所有的表格内容,都是存放在Rows和Data这两 张表中的。

    大家可以看到,UserDefinedRows这张表只有两个字段,其实,除了几乎每个用户开发模块都有的ModuleId(是为了在不同的模块中显示不同的数据),那么,就只有一个字段,也就是UserDefinedRowID,这张表太浪费了!

    而我们再回头想一下我们通常使用的列表/窗体,其实,对于“列表/窗体”这种模式来说,显示在列表上的必然只是有限的几个字段而已,而大量的字段,是不需 要显示在列表上的,所以,我们的改造就是,把需要在列表上显示的,尽量的放在UserDefinedRows这张表中,那么,其实,我们读取数据的时候, 就不需要弄那么复杂的LEFT JOIN,也不需要在内存中动态生成DataTable了,这种方式,当然是可以大大提高执行效率的。改进后的数据结构,可能是如下图所示的:

    OK,其实看过这张图大家应该知道我的想法了,就是把数据分成两部分,一部分是需要(或者是可能需要)在列表上进行展示的(还有,比如要在查询条件中出现 的、要参与系统查询接口的等等),我们尽量将之放在UserDefinedRows这张表中;另外一部分是只是在打开表格中才会用到或者读取的,我们将之 放在UserDefinedData这张表中。这个时候,如果我们再要读取数据的话,那就非常简单的,可能的SQL语句就是如下这种样式的:

     SELECT UserDefinedID, Field1 AS 姓名, Field2 AS 性别, Field3 AS 年龄 FROM UserDefinedRows

    只是在编辑或者查看详细的内容的时候,我们才需要去读取UserDefinedData这张表,所以,效率上肯定不会有问题。既然我们对这个数据结构作了 修改,那么,字段定义表UserDefinedFields这张表的结构当然也需要修改一下,至少要标明哪些字段是“基本字段”(也就是在 UserDefinedRows中出现的字段),哪些是扩展字段(也就是在UserDefinedData中出现的字段),其他的,根据我们的业务需要去 进行扩展就可以了。

    在让用户进行表单定义的时候,可以告诉用户,如果需要在列表上显示和查询的,就尽量使用基本字段;其他的,则任意定义。

    通过这种方式,我们把UserDefinedTable这个模块往前提升了一步,仍然支持无限的字段定义,但是,在缺省的Control(也就是View界面)上读取数据的时候,我们尽量抛弃UDT原来的非常让人头疼的方式。

    为了让数据更加规范,我们在增加UserDefinedRows表的字段的时候,做严格的数据类型限制(而不需要像 UDTData表那样统一的采用ntext类型,或者是varchar类型),这样的好处就是存储的数据是绝对严格的,程序出错的几率更小。如果大家用 varchar字段存储过日期格式、数值格式,而又碰到过需要对这些字段进行拼凑SQL语句查询的话,大家就明白我在说什么了,那种出错的痛苦(数据格式不规范,如本来应该是日期型,结果实际存储的不是,于是,日期转换函数报错),简直就是让人欲哭无泪。

    所以……,是的,在大家崩溃之前,我要告诉大家,我已经把UserDefinedRows的两个字段扩展到几十个字段 了,就是上图这个庞然的数据结构,看到其中的ParentID了?是的,我让这个玩意儿也支持树形结构了!如果大家有足够的耐心给我足够的时间的话,应该可以看到我的解释。(还有FormID、KeyID等,也需要解释)

    反倒是UserDefinedData这张表,和原来没什么太大的不同,这里我们就不贴图了。

    好了!为了遍历和查询的快捷性以及准确性,我们把UserDefinedRows这张表给扩展了,增加了数据结构,并且要求严格限制数据类型;而为了支持动态窗体的无限字段支持,我们仍然保留了UserDefinedData这张表。不要LEFT JOIN,不要在内存里面动态生成DataTable,那都是太浪费效率的方式。

    弄完数据结构之后,马上我们就面临一个问题了,那就是用存储过程是不太好更新我们的数据结构的,所以,下面我们要做的 事情,就是把DotNetNuke传统的使用存储过程保存数据的方式也改掉(当然,仍然没有动及DotNetNuke的开发结构,这个是我们不能动的)。 我们下一部分来谈这个问题,我们将会使用哈希表的结构,来动态的更新这张表。
 posted on 2008-10-29 11:37  DnnWorkflow  阅读(1843)  评论(3编辑  收藏  举报