第二个方案 我是用 , 号 分隔的 要添加时 直接在后面加 ,ID号  就OK (因为会员表中也有字段保存有这个会员有几个功能,所有不用查询功能表中的那个字段是否已包含这个会员), 删除时 直接 读 功能的那个字段 将 ,ID号, 替换成, 就OK 

解决方案 »

  1.   

    我个人支持方案二,存在问题可以再优化,,,
    1.这种所谓的动态功能,动的频率应该不高(对于每个会员而言),
    2.数据处理复杂、字段会非常大,可能通过再优化解决,比方说将功能表中一个功能对应一条记录,改为一个功能对应N条记录(根据会员ID所在区间分开存放)方案三虽然易于理解,方便实现,但效率应该不高,相比之下二更佳,个人观点,呵呵。
      

  2.   

    建一个表三ID  功能1   功能2  功能3  功能4
    1    0       0      1    1
    2    1       0      1    0这样遍历的话绝对快,就算对500w记录,也可以在几秒之内遍历完成一个数据页8k,一条记录不会超过20字节,所以每页可以容纳400条记录400×10000页面=400万记录   磁盘的容量大概是8K×10000=80M  ,80M对服务器来说小意思拉,几秒的事。
      

  3.   

    方案三
    建个表
    功能ID  会员ID
    1       1
    1       2
    2       1
    2       2
    最传统的做法,实现比较简单,也比较好维护。
    如果数据量很大且功能几乎没有变化可考虑 艺术老鼠 的方法.
      

  4.   

    如果应用服务器和数据服务器是分开的,那么你更要考虑之间的通讯成本了。还有你说要节省空间,整数当然比字符串节省空间吧?比如保存 2147483647,整数还是 4 个字节,
    如果你用 varchar 需要 10 个字节,用 nvarchar 需要 20 个字节。如果你要查找哪些会员订阅了功能 23,用数字的的话,是直接 where f = 23 的,直接就可以比较,
    用字符串是 where f like '%,23,%' 别以为写出来都一样简单,处理可不一样,like '%,23,%'
    是要在字符串中搜索子字符串“,23,”的,所有操作肯定比 直接的数字比较慢吧?
      

  5.   

    方案三:
     会员表:会员ID,.......
     功能表:功能ID,.......
     会员功能表: 会员ID,功能ID
    1、增加会员:
       只更新会员表,不影响其它表。
    2、变更会员功能:
       取消功能:delete 会员功能表 where 会员ID=@会员ID and  功能ID=@功能ID 
       新增功能:insert 会员功能表 select @会员ID,@功能ID
    3、删除会议:
       delete 会员功能表 where 会员ID=@会员ID
       其它删除会员的操作。
    4、增加功能:
       只更新功能表,不影响其它表。
    5、变更功能对应的用户:
       取消用户:delete 会员功能表 where 会员ID=@会员ID and  功能ID=@功能ID 
       新增用户:insert 会员功能表 select @会员ID,@功能ID
    6、删除功能:
       delete 会员功能表 where 功能ID=@功能ID
       其它删除功能的操作。上述6种操作都很方便,逻辑清晰,性能最佳。
    如果进行批量操作,操作的对象放在临时表中,通过两表联合完成。
      

  6.   

    功能表: Function
    id(int),title
    1,新闻订阅
    2,XX
    4,YY
    8,ZZ会员表: User
    id,FunctionId(int),Name
    1,7,xxx  --说明有功能:新闻订阅,XX,YY
    2,9,yyy --说明有功能:新闻订阅,ZZ
    3,6,zzz  --说明有功能:XX,YY--功能ID列为int类型,可以有31种功能,如果不够用bigint 可以有63种功能.--SQL查询
    如:包含"新闻订阅"功能的用户
    select * from user where functionid & 1 = 1去除所有用户的"ZZ"功能.
    update user set FunctionId=FunctionId-8 where functionid & 8 = 8
      

  7.   

    几天都没有人能回答,SQL一日不如一日了.
      

  8.   

    去除所有用户的"ZZ"功能. 
    update   user   set   FunctionId=FunctionId-8   where   functionid   &   8   =   8 
    -------------------------------------------------
    就这条语句,如果用户过百万的话,你就等着吧,即便FUNCTIONID建了索引也没用。
      

  9.   

    JiangHongTao,
    你的方法不光浪费大量空间,而且逻辑相对复杂,效率也不见得能占上风.你去测试一下,一百万还不够多,我等着看你的测试报告.
      

  10.   

    会员表:   User 
    id,FunctionId(int),Name 
    1,7,xxx     --说明有功能:新闻订阅,XX,YY 
    2,9,yyy   --说明有功能:新闻订阅,ZZ 
    3,6,zzz     --说明有功能:XX,YY --功能ID列为int类型,可以有31种功能,如果不够用bigint   可以有63种功能. 不太明白 冬眠的鼹鼠 V2.0  的这个表我一个会员拥有的功能是多个的 怎么用 int 类型?我技术不是很好。。
      

  11.   

    addwing,会员表:       User   
    id,FunctionId(int),Name   
    1,7,xxx           --说明有功能:新闻订阅,XX,YY    7=1+2+4  对应功能表中相应ID=1,2,4的功能2,9,yyy       --说明有功能:新闻订阅,ZZ           9=1+8
    3,6,zzz           --说明有功能:XX,YY            6=2+4
      

  12.   

    我细的看了下 你的那个 int 字段是 功能里面的ID 加起来的数值从来没见过这么设置的 学习了 研究下
      

  13.   

    你的功能表里面的ID 是   2的 N 次方? N 从 0开始 吧 ?--SQL查询 
    如:包含"新闻订阅"功能的用户 
    select   *   from   user   where   functionid   &   1   =   1 去除所有用户的"ZZ"功能. 
    update   user   set   FunctionId=FunctionId-8   where   functionid   &   8   =   8 
    你写的这个 &1=1 我不是很理解
      

  14.   

    还有就是 我如果删除一个  功能呢? 是不是就乱了套了? 能不能帮忙写个 删除 功能表的某一个功能 后 功能表和会员表 删除该 功能的sql语句啊?
      

  15.   

    & 是位运算符 "与"位运算是效率最高的
      

  16.   

    举例:
    create table dd_Function (
       id int not null primary key
      ,name varchar(32)
    )
    insert into dd_Function values (1,'新闻')
    insert into dd_Function values (2,'体育')
    insert into dd_Function values (3,'生活')
    ..
    create table rl_userFunctions (
       userId int primary key -- FK to bo_User
      ,functions int
    )
    ..
    insert into rl_userFunctions values (1,7)
    insert into rl_userFunctions values (9,5)
    ..userID 拥有的功能列表为 functions -- 一个int,将其转换为二进制数值,第bit位的值是是否有第bit功能的标志。
    按上面示例的字典,user9有“新闻”,“生活”的功能,则其functions值为:2^(1-1)+2^(3-1) = 5;
    若某user1的functions为7,表示其有“新闻”(bit1=1),“体育”(bit2=1),“生活”(bit3=1)功能;该方案与你的‘方案2’相似,但功能数量受限。有些系统将functions扩展为char(?)型的以允许存放更多的条目。
      

  17.   

    此方式在外部应用里处理还是不错的。SQL的位计算功能较弱
      

  18.   

    & 查了下联机丛书 在两个整型值之间执行按位逻辑与运算。感叹自己真是无知了 从来没用过这个 & 运算符
      

  19.   

    Time Space  你的写法跟 冬眠的鼹鼠 V2.0  基本一样啊 你说:此方式在外部应用里处理还是不错的。SQL的位计算功能较弱难道判断是否有这个功能的时候 不是用           功能ID & 会员功能字段  来运算吗? 这个不还是在 sql里面运算的吗?
      

  20.   

    这个讨论其实没有什么太大必要。
    第3种方案很标准,也很高效。没有必要为了存储空间计较
    而且如果是INT类型,那也占用不了多少。
      

  21.   

    to    * mengmou

    发表于:2008-02-20 15:54:0846楼 得分:0
    我就不明白这种问题有什么可讨论的,方案一和二连第一范式都不满足,反正我是不会让某个字段是逗号分隔的的字符串的,每一列应该是原子的。
    对于你说这些呢,只是范式规则而已,每一列应该是原子这也仅仅是在理论上。许多情况是需要做冗余的,可不能死守范式,呵呵。