DotNetNuke自定义窗体模块的数据结构(一)


在讲我们自己的数据结构之前,我们还是先来分析一下DotNetNuke的UserDefinedTable这个模块的数据结构,我个人从这个模块中受益匪浅。

  我们之前曾经说过,UserDefinedTable用三张表,就完成了支持无限字段的动态窗体的数据结构,这似乎已经是绝对不可能再精简的数据结构了(当然,还需要借助系统的Users表,来区分用户),这三张表是UserDefinedFields、 UserDefinedRows和UserDefinedData这三张表,所有的用户数据,都存储在UserDefinedData这张表中,我们将这个数据结构截一张图放在下面,让大家可以看清楚。

  为了存储所有格式的字段(如日期型、大文本型等等),因此,FieldValue采用了ntext字段。其实,这样的存储在DotNetNuke中已经有了,就是我们的模块设置表TabModuleSettings,为了存储各种类型的数据,比如布尔型、整数型、日期型等等,但是TabModuleSettings采用的是nvarchar(2000)。

  这样的数据结构就是为了可以为一条记录提供无限的字段数量,而不需要我们去动数据结构;这样的数据库设计方式其实在国内各种应用里面也是屡见不鲜的。我们举一个例子,来讲一下数据是如何存储的,比如,我们有一个定义的窗体,是用来做人员登记的,存储姓名、性别和年龄(靠,非常弱智的例子),我们最终的结果是这样的:

  张三     男  25

  (为了简单起见,性别我们也直接用字符串了,不过为了避免砖头横飞,还是解释一下。)而在数据库中,是这么存储的,见下图:

  上面这些,其实写过程序的朋友们基本上都比较清楚了,这里只是做一个简单的介绍而已。这样的存储,比较痛苦的就是如何把数据“拿出来”了,比如我们写一条SQL语句,把RowID为2的那三个字段拿出来,形成一张横表的话,需要用到LEFT JOIN方法,我们将SQL语句写在下面:

  SELECTR.UserDefinedRowID,D1.FieldValueAs姓名,D2.FieldValueAs性别,D3.FieldValueAs年龄
  FROMUserDefinedRowsR
  LEFTJOINUserDefinedDataD1ONR.UserDefinedRowID=D1.UserDefinedRowIDANDD1.UserDefinedFieldID=10
  LEFTJOINUserDefinedDataD2ONR.UserDefinedRowID=D2.UserDefinedRowIDANDD2.UserDefinedFieldID=11
  LEFTJOINUserDefinedDataD3ONR.UserDefinedRowID=D3.UserDefinedRowIDANDD3.UserDefinedFieldID=12
  WHERER.UserDefinedRowID=2

  而最后得到的结果,就是我们希望的一张横表,如下图所示:

  在论坛中,UDT的TeamLeader Sebastian Leupold曾经这样描述过他的UDT数据结构,大家有兴趣的话可以去看一下。

  OK,现在想象一下,如果我们有30个自定义字段,这个SQL语句会有多长呢?而一个自定义的Form 中,有30个字段,应该不是什么过分的要求吧?更重要的是,LEFT JOIN这种方式,还是效率比较低下的。而更过分的是,我们的UserDefinedTable模块,采用了应该是更为低下的方式来处理数据,就是将数据一条条取出来,然后在内存中动态生成一张DataTable,然后再将这个DataTable绑定到显示控件上。按照我个人的理解,我觉得这种方式毫无疑问是比LEFT JOIN更为效率低下的一种处理方式,所以,在另外一个帖子里(抱歉,翻了半天,仍然找不到那个帖子,顺便鄙视一下DotNetNuke Forum的搜索功能,基本上没有能用的时候),Sebastian Leupold也亲口承认说,UDT对于超大量的数据是不适合的。所以,其实UDT的问题,是“结构性问题”,如果我们需要超越UDT,开发我们的 Form,并且可以容纳比如百万级数据的话,一定要重新设计一下UDT的结构,将其中有用的为我所用;其中不好的予以改进。

  下一节我们讨论如何对这个数据结构进行优化,从而达到我们的要求


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3