项目里的分类设计:12230000,一共八位,每两位表示一个分类层级。例如:12000000表示“家装建材”12230000表示“家装建材”->“瓷砖地板”12230100表示“家装建材”->“瓷砖地板”->“防水地板”设计的优点:对于获取某个分类(瓷砖地板)下面的子分类直接:select * from table where id > 12230000 and id <= 12239900,然后从这个结果里面踢掉最后两位非0的记录。

这样设计随即的麻烦来了,我们怎么求出:12239900?对于计算一个二级分类下的子类这个最大值是12239900,但对于计算一级分类下的子类这个最大值就变成:12990000,同样计算三级分类子类这个最大值为:12239999。

怎么可以很优雅地计算这个最大值?现在的做法很笨:字符串截取,连接然后再str_pad。

2011-02-02 15:00:38

6 Answers

每个层级的位数可以确定那么 可以这样设计:
增加pid字段, 每条记录的 的 pid 为 上级的pid
增加level字段,为当前分类等级
举例:
id       name     pid level
12     家装建材     0 1
13     瓷砖地板     12 2
14     防水地板     13 3

如果查找 id为 13 下边的之类,pid=13 level=3

2011-02-02 19:02:23

你这样设计有个问题,那就是三级分类下的物品不能超过99个,我估计挡不住吧?
如果非要这样,分析如下:
对于计算一级分类下的子类这个最大值小于12000000+1000000;
对于计算二级分类下的子类这个最大值小于12230000+10000;
对于计算三级分类下的子类这个最大值小于12239900+100。
所以有这么个逻辑关系:
一级分类下的+1000000
二级分类下的+10000
三级分类下的+100

2011-02-02 20:02:36
给你写了一个简单的方法,不用截字符串


function getMax($start){ $decimal = rtrim($start, 0); $remainder = $start/$decimal; $cop = ($remainder * 99)/100; return $start + $cop; } $start =122300000000; echo getMax($start);
2011-02-02 21:27:36
function getMaxId($id){ //最大支持9位数 if($id<0 || $id>999999999) return -1; $mod = 100; $n=99; if($id) while(!($n=($id%$mod))) $mod*=100; return $id-$n + $mod*.99; } function getMinId($id){ //最大支持9位数 if($id<0 || $id>999999999) return -1; $mod = 100; $n=0; if($id) while(!($n=($id%$mod))) $mod*=100; return $id-$n; } $id = 12345678; echo 'Min:', getMinId($id), "\r\n"; echo 'Max:', getMaxId($id); /* 输出: Min:12345600 Max:12345699 */

这样子够优雅了吗?

2011-02-02 23:43:37
function getMaxChild($pid){ //$pid=12206100; $str=''; for($i=1;$i<=4;$i++){ $test=substr($pid,0,2); $pid=substr($pid,2,strlen($pid)); if($test=="00"){ return $str.'99'.$pid;break; }elseif($i==4){ return false; }else{ $str.=$test; } } } echo getMaxChild('12200000');
2011-02-03 00:35:08
$num = 12011000; $level = 0; while(($num % 100) === 0) { $level++; $num /= 100; } echo $level; //an=a1+(n-1)*d //a1 = 2; //a2 = 2 + (2-1)*2 = 4; //a3 = 2 + (3-2)*2 = 6; //max = num + pow(10, an) //$sql = select * from table where id > num and id < max
2011-02-02 16:38:03
您不能回答该问题或者回答已经关闭!

相关文章推荐

  • C#中using指令的几种用法

    using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到

  • C#实例解析适配器设计模式

    将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作

  • 使用托管C++粘合C#和C++代码(二)

    本文实现一下C++代码调用C#代码的过程。我构造一个简单并且直观的例子:通过C++ UI 触发C# UI.

  • C#开发高性能Log Help类设计开发

    项目中要在操作数据库的异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多

  • Async和Await使异步编程更简单

    C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作

  • C#开发中的反射机制

    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等

  • C#运行时相互关系

    C#运行时相互关系,包括运行时类型、对象、线程栈和托管堆之间的相互关系,静态方法、实例方法和虚方法的区别等等

  • C#协变和逆变

    “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型,“逆变”则是指能够使用派生程度更小的类型

  • C#基础概念之延迟加载

    延迟加载(lazy load)是Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作

  • C#中的索引器的简单理解和用法

    C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作

  • 使用托管C++粘合C#和C++代码(一)

    C#在xml读写,数据库操纵,界面构造等很多方面性能卓越;C++的效率高,是底层开发的必备武器

  • 深入C# 序列化(Serialize)、反序列化(Deserialize)

    C#中的序列化和反序列化,序列化是.NET运行时环境用来支持用户定义类型的流化的机制