我的分页控件(未完,待续)——控件件介绍及思路
2007-03-01 16:05
288 查看
一、 工作的层次
UI层和逻辑层。
UI层:显示首页、末页、上一页、下一页、页号导航、文本框输入页号;共计多少条记录、多少页、当前页号等信息。
逻辑层:提供分页算法(SQL语句),根据分页控件的属性,在运行的时候生成分页用的SQL语句。
二、 流程
l 设置分页控件的属性
l 根据算法和属性生成SQL语句,通过“我的数据访问层”访问数据库
l 得到记录集(比如DataTable)
l 把记录集绑定到指定的控件(比如DataGrid)
三、 分页算法
1、 数据库因素
因为不同的数据库对于T_SQL都有不同的标准,在分页的地方差别就更大了。比如MSSQL2000可以使用嵌套的top ,而其它的数据库就不可以。它们的差别是很大的。
理想的情况下是不同的数据库生成相对应的分页算法,但是由于我目前只使用MSSQL,所以其他数据库的算法还没有研究,不过听说都挺方便的。
2、 分页要求
第二个要考虑的就是分页的要求。好多人都在寻求一个通用的算法,通用的算法可以找到,但是要牺牲一些效率。
A 简单分页
顾名思义,就是最简单的分页情况,按照一个字段来排序,而且排序字段的值没有重复(或者很少有重复)的情况。比如新闻列表,帖子列表。
B 复杂分页
上面的情况确实是很简单的,我们来看一下复杂一点的情况:按照多个字段来排序,最后一个排序字段没有重复的值;按照多个字段(或者一个字段)排序,最后一个字段有很多的重复值。
好像是两种情况,但是后者可以转换为前者,再加一个没有重复值的字段最为最后一个排序字段,这样后一种情况就变成了前一种情况了。
C 主键
我的看法是每一个表都要有一个主键,而且是单一字段的主键(不是复合主键)。复合主键会带来很多的麻烦,应该尽量避免,方法也很简单,在原来的设计上加一个自增的int字段就可以了,把这个自增的字段最为主键即可。
为什么提倡单一主键呢?因为这样可以提高效率,不仅在分页的时候,其他的地方也会很方便。
3、 实际情况
对于一个列表页面来说,哪个页面访问率最高呢?毫无疑问是第一页。大多数情况都是先看第一页的,所以我感觉有必要为第一页单独写一个分页算法,任意页再写一个算法,如果有必要的话最后一页也要再写一个算法。
第一页单独写分页算法的另一个原因是——好写(对于MSSQL来说)select top 20 * from table where … order by … 。如果排序字段有索引的话,那么这样的语句的效率是最高的,而且where 和order by 可以随意添加。
4、 具体算法(MSSQL数据库)
A 高效算法
这是一个非常追求效率的算法,依据MSSQL的特性,为简单分页的情况量身定做的。
第一个特性:select top 11 @id = ID from Table
Top 和 给变量赋值都是很常用的方法,但是这种组合不太常见吧。这是我在一个偶然的情况下发现的,这么写有什么作用呢?先来看看@id会得到什么值。@id 得到的是最后一条记录的ID字段的值,前面的记录的值会被覆盖。
假设分页要求是:每页显示10条记录,按照ID字段升序显示。那么这时候 select top 10 * from Table where ID >= @ID 得到的记录集就是第二页所需要的数据。第三页的数据只要把第一个语句 top 后面的 “11”改成“21”就可以了。公式:PageSize * (PageIndex - 1) + 1
要想使用这个特性必须满足几个条件:排序字段只能有一个,排序字段的值不能有太多重复的,有重复值会造成分页不准,甚至无法翻到下一页的情况。所以这个算法只适用于“简单分页”的情况。不过好在一个网站里面有很多情况都是“简单分页”的情况,随意这个算法还是有价值的。
Ps:这个特性好像只有MSSQL才有,SQLAnywhere是不容许这样写的,除非记录集只有一条记录,oracle 根本就没有top,其它的数据库没有研究过。
思路:先定位(数数),后取记录集(ID >= 的方法)。
优点:第一个语句只取一个字段,即使是top 10000也可以把占用的资源降到最低。如果排序字段有索引的话效果更佳。
B 一般算法
针对上面的算法的不足,可以采用这个算法,颠颠倒倒法,就是top嵌套。还有一个大名,忘记了(研究出算法后才发现的)。
select [*] fromwhere [ID] in (
UI层和逻辑层。
UI层:显示首页、末页、上一页、下一页、页号导航、文本框输入页号;共计多少条记录、多少页、当前页号等信息。
逻辑层:提供分页算法(SQL语句),根据分页控件的属性,在运行的时候生成分页用的SQL语句。
二、 流程
l 设置分页控件的属性
l 根据算法和属性生成SQL语句,通过“我的数据访问层”访问数据库
l 得到记录集(比如DataTable)
l 把记录集绑定到指定的控件(比如DataGrid)
三、 分页算法
1、 数据库因素
因为不同的数据库对于T_SQL都有不同的标准,在分页的地方差别就更大了。比如MSSQL2000可以使用嵌套的top ,而其它的数据库就不可以。它们的差别是很大的。
理想的情况下是不同的数据库生成相对应的分页算法,但是由于我目前只使用MSSQL,所以其他数据库的算法还没有研究,不过听说都挺方便的。
2、 分页要求
第二个要考虑的就是分页的要求。好多人都在寻求一个通用的算法,通用的算法可以找到,但是要牺牲一些效率。
A 简单分页
顾名思义,就是最简单的分页情况,按照一个字段来排序,而且排序字段的值没有重复(或者很少有重复)的情况。比如新闻列表,帖子列表。
B 复杂分页
上面的情况确实是很简单的,我们来看一下复杂一点的情况:按照多个字段来排序,最后一个排序字段没有重复的值;按照多个字段(或者一个字段)排序,最后一个字段有很多的重复值。
好像是两种情况,但是后者可以转换为前者,再加一个没有重复值的字段最为最后一个排序字段,这样后一种情况就变成了前一种情况了。
C 主键
我的看法是每一个表都要有一个主键,而且是单一字段的主键(不是复合主键)。复合主键会带来很多的麻烦,应该尽量避免,方法也很简单,在原来的设计上加一个自增的int字段就可以了,把这个自增的字段最为主键即可。
为什么提倡单一主键呢?因为这样可以提高效率,不仅在分页的时候,其他的地方也会很方便。
3、 实际情况
对于一个列表页面来说,哪个页面访问率最高呢?毫无疑问是第一页。大多数情况都是先看第一页的,所以我感觉有必要为第一页单独写一个分页算法,任意页再写一个算法,如果有必要的话最后一页也要再写一个算法。
第一页单独写分页算法的另一个原因是——好写(对于MSSQL来说)select top 20 * from table where … order by … 。如果排序字段有索引的话,那么这样的语句的效率是最高的,而且where 和order by 可以随意添加。
4、 具体算法(MSSQL数据库)
A 高效算法
这是一个非常追求效率的算法,依据MSSQL的特性,为简单分页的情况量身定做的。
第一个特性:select top 11 @id = ID from Table
Top 和 给变量赋值都是很常用的方法,但是这种组合不太常见吧。这是我在一个偶然的情况下发现的,这么写有什么作用呢?先来看看@id会得到什么值。@id 得到的是最后一条记录的ID字段的值,前面的记录的值会被覆盖。
假设分页要求是:每页显示10条记录,按照ID字段升序显示。那么这时候 select top 10 * from Table where ID >= @ID 得到的记录集就是第二页所需要的数据。第三页的数据只要把第一个语句 top 后面的 “11”改成“21”就可以了。公式:PageSize * (PageIndex - 1) + 1
要想使用这个特性必须满足几个条件:排序字段只能有一个,排序字段的值不能有太多重复的,有重复值会造成分页不准,甚至无法翻到下一页的情况。所以这个算法只适用于“简单分页”的情况。不过好在一个网站里面有很多情况都是“简单分页”的情况,随意这个算法还是有价值的。
Ps:这个特性好像只有MSSQL才有,SQLAnywhere是不容许这样写的,除非记录集只有一条记录,oracle 根本就没有top,其它的数据库没有研究过。
思路:先定位(数数),后取记录集(ID >= 的方法)。
优点:第一个语句只取一个字段,即使是top 10000也可以把占用的资源降到最低。如果排序字段有索引的话效果更佳。
B 一般算法
针对上面的算法的不足,可以采用这个算法,颠颠倒倒法,就是top嵌套。还有一个大名,忘记了(研究出算法后才发现的)。
select [*] from