首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

请各位数据库高手来讨论下这个 数据库设计的效率有关问题!星星、钻石最好

2012-01-21 
请各位数据库高手来讨论下这个 数据库设计的效率问题!星星、钻石最好!我现在设计个 数据库功能是 : 一个会

请各位数据库高手来讨论下这个 数据库设计的效率问题!星星、钻石最好!
我现在设计个 数据库 功能是 : 一个会员表 还有就是 系统的功能表 功能是变化的 就是说 有时添加有时 删除 比如 有网站新闻订阅功能。。 
我疑问是 怎么设置字段 程序实现时 效率最高 。 一个是 新闻订阅时 要把所有 订阅的会员 发送订阅信息 另一个是 我功能变化时 要把所有 跟这个功能相关的会员 更新下 我这么说 能理解吗?

=============
就是 动态功能
-----------------

我现在有三种方案:一 会员表中其中一个字段 以 , 分割 来储存 这个会员所拥有的功能, 但这种方案 弊端是 假如 有个订阅功能 我要发信息时 必须遍历整个会员表 把所有会员的这个字段拿出来 拆分 有这个功能的 发,没有的不发 。。
-----------------

方案二 在一的基础上 在 功能表里加一个字段 这个字段以 , 分隔 储存有这个功能的所有的会员的ID 号 这样 订阅信息时 就好弄多了 。但如果会员 上百万以后 某个功能的这个字段会非常大 。。。
---------------

方案三 再建一个表 表里储存 1个关键ID 一个 功能ID 一个 会员ID 。。但这个表会 很大 。 如果修改某个会员的某个功能是否具备时 最多要检索 会员总数*功能总数 次 。这样要多个会员操作是 数据库吞吐会非常大 。。

我没做过实际数据测试 不知道 实际运行时 哪个 效率高 。。我现在暂时 采用第二个 。不知道 谁有好的建议??


[解决办法]
个人观点: 方案3! 这是传统方式的解决方案。便于理解,处理方便,容易实现。关于"多个会员操作时数据库吞吐会非常大"的说法未必存在,它的数据吞吐量应该不比方案1、2大。
[解决办法]
鉴于功能和人员都是动态的,所以建议方案三
[解决办法]
若某功能的会员变化(会员订阅\退订某个功能):方案2的处理复杂,数据量大(尤其是某功能的订阅者较多时)
[解决办法]
个人观点:方案三
[解决办法]
推荐:第三套
[解决办法]
方案二的问题:
1. 数据存在冗余(会员表中其中一个字段,以","分割来储存这个会员所拥有的功能;功能表里一个字段","分隔储存有这个功能的所有的会员的ID号);冗余易导致数据一致性问题。
2. 数据处理过程复杂;
3. 数据处理量大;
[解决办法]
我个人支持方案二,存在问题可以再优化,,,
1.这种所谓的动态功能,动的频率应该不高(对于每个会员而言),
2.数据处理复杂、字段会非常大,可能通过再优化解决,比方说将功能表中一个功能对应一条记录,改为一个功能对应N条记录(根据会员ID所在区间分开存放)

方案三虽然易于理解,方便实现,但效率应该不高,相比之下二更佳,个人观点,呵呵。
[解决办法]
建一个表三

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对服务器来说小意思拉,几秒的事。

[解决办法]
第三个好,更符合范式,只要会员ID加上索引就不会影响到效率
大部分多对多的表都是这个结构
[解决办法]
方案三
建个表
功能ID 会员ID
1 1
1 2
2 1
2 2
最传统的做法,实现比较简单,也比较好维护。
如果数据量很大且功能几乎没有变化可考虑 艺术老鼠 的方法.
[解决办法]
方案三
[解决办法]
方案三比较好
[解决办法]
我建议方案三
[解决办法]
方案3,数字比较比字符拆分不知道快多少倍,

对于排序了的字段,就算1024*1024*1024条记录,最多也就是比较 30 此而已
你的数据有多大?
[解决办法]
方案三:
 会员表:会员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种操作都很方便,逻辑清晰,性能最佳。
如果进行批量操作,操作的对象放在临时表中,通过两表联合完成。




[解决办法]
功能表: 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

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

发表于:2008-02-20 15:54:0846楼 得分:0
我就不明白这种问题有什么可讨论的,方案一和二连第一范式都不满足,反正我是不会让某个字段是逗号分隔的的字符串的,每一列应该是原子的。


对于你说这些呢,只是范式规则而已,每一列应该是原子这也仅仅是在理论上。许多情况是需要做冗余的,可不能死守范式,呵呵。



[解决办法]
对于方案三 如果有10个功能那么10W个用户就有100W条记录 20个功能200W记录 此时每个ID列已经重复20次..

还是同意artmouse的做法 对每个功能0/1记录(bit类型) 对每个用户单行列出所有功能 占用页面少 并发性也不差 你说的不清楚所有功能无法给出全部列在方案三中还不是要解决?
[解决办法]
我就不明白在不考虑查询的情况下为什么不采用方案3
[解决办法]
看来石林没有正确理解方案三. 
对于方案三,如果某个用户(用户ID)选择了某项功能(功能ID),就在表三中出入一条记录,记录就两列,用户ID,功能ID 
极端的情况是所有的用户都没有选择功能,则表三为空表。 
----------------------
TO:蒋洪涛

方案3查询基本上都是三个表的join操作 如涉及到具体某用户ID所有状态查询

select 用户表.用户名,功能表.功能名 
from 用户表 inner join 详表 on 用户表.id = 详表.id 
inner join 功能表 on 功能表.功能ID=详表.功能ID 
where 用户表.id= xxx

而且 这个结果可观性较差 即不容易满足格式上的要求 如果是报表或者统计 还要做行列转换

另外 从结构上讲 数据较大的情况下 详表面临的数据重复率(用户ID 功能ID)越高

同时 如果表更频率高的话 页面碎片不不容忽视
[解决办法]
方案三。
方案一、二都会受到数据表中字段长度的限制,以及定义变量长度的限制。
The maximum allowed for any data type is 8000

热点排行