??xml version="1.0" encoding="utf-8" standalone="yes"?>
文章内容引用自:
全面了解数据库设计中分类法
http://blog.csdn.net/hyzhx/archive/2008/03/21/2201465.aspx
在数据库中存储层ơ数据实现无限分层
http://www.52web.com/52article/?view-250.html
http://www.thinkly.cn/index.php/archives/354
商品无限分类的算法如何优?
http://www.javaeye.com/topic/170744
关于无限分类的设计网上讨论有很多Q说白了是在数据库中设计树(wi)的问题,在这里仅Ҏ(gu)所知的做些记录与对比?br />
假设表结构ؓ下图Qƈ且ؓ某表的外键引用。要求:
1、实现无限层ơ?br />
2、能扑ֈ节点的\径?br />
3、能扑ֈ所有子孙节炚w合(获取?wi))?br />
引用Q?在数据库中存储层ơ数据实现无限分层"
Ҏ(gu)1Q邻接列表模?The Adjacency List Model)/递归Ҏ(gu)
http://www.52web.com/52article/?view-250-page-2.html
引用Q?在数据库中存储层ơ数据实现无限分层"
优点Q结构简单明了,对于节点的维护ƈ不需要额外的工作?br /> ~点Q实现要??需要进行大量的递归操作Q每一ơ数据库查询都需要花费一Ҏ(gu)间?br />
Ҏ(gu)2Q递归Ҏ(gu)改进
Ҏ(gu)?的扩展,新增 path字段以存储节点\径,arrayChild字段存储其下所有节炏V?/p>
优点Q实现要??只需要一ơ查询?br /> ~点Q当节点发生改变旉要维护对应的字段Q且 path?arrayChild以拼串Ş式存储于文本字段Q容易限制节炚w度,q且对于查询效率有媄响?/p>
Ҏ(gu)3Q改q前序遍历树(wi)
http://www.52web.com/52article/?view-250-page-2.html
如果作ؓ主键标识的节点编号存在外部引用,q需要定义一个链表编?linkId来确保其主键标识固定Qƈ重新定义光表左双围?br />
优点Q实现要??只需要一ơ查询,但比Ҏ(gu)2l护h更见方便Q减大量的gQ,而且因ؓ左右DC的是链表的范围Q所以查询效率更高?br /> ~点Q算法未l说明前不如Ҏ(gu)1?直观?nbsp;
1.Ҏ(gu)询进行优化,应尽量避免全表扫描,首先应考虑?where ?order by 涉及的列上徏立烦引?
2.应尽量避免在 where 子句中对字段q行 null 值判断,否则导致引擎放弃用烦引而进行全表扫描,如:
select id from t where num is null
可以在num上设|默认?Q确保表中num列没有null|然后q样查询Q?
select id from t where num=0
3.应尽量避免在 where 子句中?=?lt;>操作W,否则引擎放弃用烦引而进行全表扫描?
4.应尽量避免在 where 子句中?or 来连接条Ӟ否则导致引擎放弃用烦引而进行全表扫描,如:
select id from t where num=10 or num=20
可以q样查询Q?
select id from t where num=10
union all
select id from t where num=20
5.in ?not in 也要慎用Q否则会D全表扫描Q如Q?
select id from t where num in(1,2,3)
对于q箋的数|能用 between ׃要用 in 了:
select id from t where num between 1 and 3
6.下面的查询也导致全表扫描:
select id from t where name like '%abc%'
若要提高效率Q可以考虑全文索?
7.如果?where 子句中用参敎ͼ也会D全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将讉K计划的选择推迟到运行时Q它必须在编译时q行选择。然而,如果在编译时建立讉K计划Q变量的D是未知的Q因而无法作为烦引选择的输入项。如下面语句进行全表扫描:
select id from t where num=@num
可以改ؓ强制查询使用索引Q?
select id from t with(index(索引?) where num=@num
8.应尽量避免在 where 子句中对字段q行表达式操作,q将D引擎攑ּ使用索引而进行全表扫描。如Q?
select id from t where num/2=100
应改?
select id from t where num=100*2
9.应尽量避免在where子句中对字段q行函数操作Q这导致引擎放弃用烦引而进行全表扫描。如Q?
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
应改?
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10.不要?where 子句中的“=”左边q行函数、算术运或其他表达式运,否则pȝ可能无法正用烦引?
11.在用烦引字D作为条件时Q如果该索引是复合烦引,那么必须使用到该索引中的W一个字D作为条件时才能保证pȝ使用该烦引,否则该烦引将不会被用,q且应尽可能的让字段序与烦引顺序相一致?
12.不要写一些没有意义的查询Q如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
q类代码不会q回Ml果集,但是会消耗系l资源的Q应Ҏ(gu)q样Q?
create table #t(...)
13.很多时候用 exists 代替 in 是一个好的选择Q?
select num from a where num in(select num from b)
用下面的语句替换Q?
select num from a where exists(select 1 from b where num=a.num)
14.q不是所有烦引对查询都有效,SQL是根据表中数据来q行查询优化的,当烦引列有大量数据重复时QSQL查询可能不会d用烦引,如一表中有字DsexQmale、female几乎各一半,那么即在sex上徏了烦引也Ҏ(gu)询效率v不了作用?
15.索引q不是越多越好,索引固然可以提高相应?select 的效率,但同时也降低?insert ?update 的效率,因ؓ insert ?update 时有可能会重建烦引,所以怎样建烦引需要慎重考虑Q视具体情况而定。一个表的烦引数最好不要超q?个,若太多则应考虑一些不怋用到的列上徏的烦引是否有必要?
16.应尽可能的避免更?clustered 索引数据列,因ؓ clustered 索引数据列的序是表记录的物理存储序Q一旦该列值改变将D整个表记录的序的调_会耗费相当大的资源。若应用pȝ需要频J更?clustered 索引数据列,那么需要考虑是否应将该烦引徏?clustered 索引?
17.量使用数字型字D,若只含数g息的字段量不要设计为字W型Q这会降低查询和q接的性能Qƈ会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字W,而对于数字型而言只需要比较一ơ就够了?
18.可能的使用 varchar/nvarchar 代替 char/nchar Q因为首先变长字D存储空间小Q可以节省存储空_其次对于查询来说Q在一个相对较?yu)的字段内搜索效率显然要高些?
19.M地方都不要?select * from t Q用具体的字D列表代?#8220;*”Q不要返回用不到的Q何字Dc?
20.量使用表变量来代替临时表。如果表变量包含大量数据Q请注意索引非常有限Q只有主键烦引)?
21.避免频繁创徏和删除(f)时表Q以减少pȝ表资源的消耗?
22.临时表ƈ不是不可使用Q适当C用它们可以某些例程更有效,例如Q当需要重复引用大型表或常用表中的某个数据集时。但是,对于一ơ性事Ӟ最好用导?
23.在新Z(f)时表Ӟ如果一ơ性插入数据量很大Q那么可以?select into 代替 create tableQ避免造成大量 log Q以提高速度Q如果数据量不大Qؓ了缓和系l表的资源,应先create tableQ然后insert?
24.如果使用C临时表,在存储过E的最后务必将所有的临时表显式删除,?truncate table Q然?drop table Q这样可以避免系l表的较长时间锁定?
25.量避免使用游标Q因为游标的效率较差Q如果游标操作的数据过1万行Q那么就应该考虑改写?
26.使用Z游标的方法或临时表方法之前,应先LZ集的解决Ҏ(gu)来解决问题,Z集的Ҏ(gu)通常更有效?
27.与(f)时表一P游标q不是不可用。对型数据集?FAST_FORWARD 游标通常要优于其他逐行处理Ҏ(gu)Q尤其是在必d用几个表才能获得所需的数据时。在l果集中包括“合计”的例E通常要比使用游标执行的速度快。如果开发时间允许,Z游标的方法和Z集的Ҏ(gu)都可以尝试一下,看哪一U方法的效果更好?
28.在所有的存储q程和触发器的开始处讄 SET NOCOUNT ON Q在l束时设|?SET NOCOUNT OFF 。无需在执行存储过E和触发器的每个语句后向客户端发?DONE_IN_PROC 消息?
29.量避免大事务操作,提高pȝq发能力?
30.量避免向客L(fng)q回大数据量Q若数据量过大,应该考虑相应需求是否合理?