项目要求注册页面上有四个下拉菜单,分别对应国家专业分类标准(材料已具备)的四级目录
一级目录对应N个二级目录,一个二级目录对应N个三级目录,一个三级目录对应N个四级目录,这些都是固定好的(相当长一段时间不会发生改变),考虑到程序的灵活性,打算将国家标准导入到MySQL中,全部文本信息大概254K大小,在设计数据库的时候有一些疑问。我打算这样设计表的:
产生四个innodb,分别为:
oneposition(name)//一级目录表,包含一级目录名称
twoposition(name,oneposition)//二级目录表,包含二级目录的名称,和其对应的一级目录的名称;
threeposition(name,twoposition)//三级目录表,包含三级目录的名称,和其对应的二级目录名称;
fourposition(name,threeposition)//四级目录表,包含四级目录名称,和其对应的三级目录名称;
四张表之间用外键约束关系定好。后来团队中有朋友质疑第一张表的存在必要,也就是oneposition表的必要性,可以直接从第二张表开始建,检索一级目录的时候直接用distinct关键字检索第二张表的oneposition字段就可以得出所有一级目录名称。经过广泛的讨论,自己觉得在数据量不小的情况下,我这样的设计比较糟糕,因为每个目录名称都重复了两次,不知道专业数据库设计者们,如果你们碰到这种情况该如何设计数据库呢。PS:国家专业分了标准示例:
11自然科学--------------------------------------(一级目录)
110 数学------------------------------------------(二级目录)
110.11 数学史-------------------------------------------(三级目录)
110.14 数理逻辑与数学基础-------------------------------------(三级级目录)
110.1410 演绎逻辑学(亦称符号逻辑学)------------------------------------(四级目录)
110.1420 证明论(亦称元数学)
110.1430 递归论
110.1440 模型论
110.1450 公理集合论
110.1460 数学基础
110.1499 数理逻辑与数学基础其他学科
110.17 数论
110.1710 初等数论
110.1720 解析数论
110.1730 代数数论
110.1740 超越数论
110.1750 丢番图逼近
110.1760 数的几何
110.1770 概率数论
110.1780 计算数论
110.1799 数论其他学科
110.21 代数学
110.2110 线性代数
110.2115 群论
110.2120 域论
110.2125 李群
110.2130 李代数
110.2135 Kac-Moody代数
110.2140 环论
110.2145 模论
110.2150 格论
110.2155 泛代数理论
110.2160 范畴论
110.2165 同调代数
……

解决方案 »

  1.   

    根据实际情况,我可能会选只用1张表id ,     Level  description
    -------- ------ -----------------
    11       0      自然科学
    110      1      数学
    110.11   2      数学史
    110.1410 4      演绎逻辑学(亦称符号逻辑学)
    110.1420 4      证明论(亦称元数学)
    110.1430 4      递归论
    110.1440 4      模型论
    110.1450 4      公理集合论
    == 思想重于技巧 ==
      

  2.   

    id ,     Level  description
    -------- ------ -----------------
    11       0      自然科学
    110      1      数学
    110.11   2      数学史
    110.14   3      数理逻辑与数学基础
    110.1410 4      演绎逻辑学(亦称符号逻辑学)
    110.1420 4      证明论(亦称元数学)
    110.1430 4      递归论
    110.1440 4      模型论
    110.1450 4      公理集合论
    for 110.1430 递归论select * from yourTable where INSTR("110.1430",id) and Level=3
    == 思想重于技巧 ==
      

  3.   

    select * from yourTable where INSTR("110.1430",id)>0 and Level=3
    == 思想重于技巧 ==
      

  4.   

    连level字段都可省
    yourTable (id ,   description)select *
    from yourTable 
    where INSTR("110.1430",id)>0
    and LENGTH(id)= (
    select max(LENGTH(id))
    from yourTable 
    where INSTR("110.1430",id)>0)
    == 思想重于技巧 ==
      

  5.   

    麻烦讲一下那个函数instr("110.1430",id)>0是什么意思阿,谢谢了
      

  6.   

    手册上有INSTR(str,substr) 
    == 思想重于技巧 ==
      

  7.   

    知道了那个instr函数什么意思了,可是不明白你的那句SQL语句。
    比方说,我的第一个下拉菜单要显示所有的一级目录,也就是id为11-99的数据。
    我的二级下拉菜单要显示相应一级目录的二级目录,也就是如果一级下拉菜单的id为11,那我就要搜索id为110-119的所有数据,
    同理,我的三级下拉菜单要搜索id为110.11-110.99的所有数据
    我的四级下拉菜单要显示id为110.1101-110.1199的所有数据
    麻烦给出这样一个SQL语句,谢谢了
      

  8.   

    我的第一个下拉菜单要显示所有的一级目录,也就是id为11-99的数据。
    select * from yourTable 
    where level=0orselect * from yourTable where LENGTH(id)=2
    == 思想重于技巧 ==
      

  9.   

    我的二级下拉菜单要显示相应一级目录的二级目录,也就是如果一级下拉菜单的id为11,那我就要搜索id为110-119的所有数据,select * from yourTable where level=1 and id like '11%';
    or
    select * from yourTable where LENGTH(id)=3 and id like '11%';
    == 思想重于技巧 ==
      

  10.   

    同理,我的三级下拉菜单要搜索id为110.11-110.99的所有数据
    select * from yourTable where level=2 and id like '110.%';
    or
    select * from yourTable where LENGTH(id)=6 and id like '110.%';
    == 思想重于技巧 ==
      

  11.   

    我的四级下拉菜单要显示id为110.1101-110.1199的所有数据
    select * from yourTable where level=3 and id like '110.11%';
    or
    select * from yourTable where LENGTH(id)=8 and id like '110.11%';
    == 思想重于技巧 ==