2008年01月
昨天,由Sisley Lin 处得知,我将被推荐成了“十大杰出开发技术英雄”候选人之一,有点激动。推荐的理由是我为CSDN 这个最大的中文技术社区的成长所贡献的这些年。当我回首看自己在CSDN经历时,发现自己已为CSDN公司工作了7年半,在CSDN 论坛活动了8年。蓦然回首,八年光阴已匆匆而过,心中真是感慨万千呀。 记得那是在99年底,2000年初时,我从大学毕业刚半年,跟随一个我的铁哥们跳槽到一家新成立的电子商务的网站(http://www.ego88.com/, 不过这个网站现在已经无法访问了)。由于之前我是在一家使用Delphi开发ERP,医院信息系统的公司,我对Delphi非常感兴趣,当时最常去的就是大富翁论坛(http://www.delphibbs.com/)。经这次跳槽后,由于转行做网站,就开始学习ASP技术。在大富翁论坛时,听说新开了一个程序员的论坛CSDN,而CSDN有个板块在讨论ASP,于是乎,就整天泡CSDN论坛的A阅读全文>
发表于 @ 2008年01月24日 09:50:00|评论(loading...)|编辑
我们书写查询语句的时候,Join 参数之前可以是下面三个 { LOOP | MERGE | HASH } JOIN 。 如果不使用,则系统自己分析那种方式快,使用那种方式。 这其实是SQL Server 联结时候使用的三种算法。尽管每种算法都并不是很复杂,但考虑到性能优化,在产品级的优化器实现时往往使用的是改进过的变种算法。譬如SQL Server 支持block nested loops、index nexted loops、sort-merge、hash join以及hash team。我们在这里只对上述三种基本算法的原型做一个简单的介绍。 知识点: Tables join总是两个两个进行的。所以下面的算法都是两个表的联结。 Hash Join (哈希联结) 下图是 SQL Server 标示这种联结的图标,从图标我们就可以看到这个查询的逻辑。 逻辑步骤,如下图: 以数据少的数据表的 Join 字段建立 Hash 值。 对应的数据表计算 Join 字段的 Hash ,再与阅读全文>
发表于 @ 2008年01月23日 16:05:00|评论(loading...)|编辑
我们仍然是通过例子来理解OR运算符的特征 我们仍然使用 http://blog.joycode.com/ghj/archive/2008/01/18/113870.aspx 中的 member 表,这时候,这个表的索引如下: 名字 描述 列 member_corporation_link nonclustered located on PRIMARY corp_no member_ident clustered, unique, primary key located on PRIMARY member_no member_region_link nonclustered located on PRIMARY region_no MemberFirstName nonclustered located on PRIMARY firstname MemberLastName nonclustered located on PRIMARY lastname 我们执行下面的查询SELECT m.LastName, m.FirstName, m.Region_NoFROM db阅读全文>
发表于 @ 2008年01月18日 14:33:00|评论(loading...)|编辑
我在SQL Server 索引基础知识系列中,第一篇就讲了记录数据的基本格式。那里主要讲解的是,数据库的最小读存单元:数据页。一个数据页是8K大小。 对于数据库来说,它不会每次有一个数据页变化后,就存到硬盘。而是变化达到一定数量级后才会作这个操作。 这时候,数据库并不是以数据页来作为操作单元,而是以64k的数据(8个数据页,一个区)作为操作单元。 区是管理空间的基本单位。一个区是八个物理上连续的页(即 64 KB)。这意味着 SQL Server 数据库中每 MB 有 16 个区。 为了使空间分配更有效,SQL Server 不会将所有区分配给包含少量数据的表。SQL Server 有两种类型的区: 统一区,由单个对象所有。区中的所有 8 页只能由所属对象使用。 混合区,最多可由八个对象共享。区中八页的每页可由不同的对象所有。 通常从混合区向新表或索引分配页。当表或索引增长到 8 页时,将变成使用统一区进行后续分配。如果对现有表创建索引,并且该表包含的行足以在索引中生成 8 页,则对该索引的所有分配都使用统一区进行。 为何会这样呢? 其实很简单: 读或写 8KB 的时间与读阅读全文>
发表于 @ 2008年01月18日 11:18:00|评论(loading...)|编辑
我们通过一个实例来看 有And 操作符时候的最常见的一种情况。我们有下面一个表,CREATE TABLE [dbo].[member]( [member_no] [dbo].[numeric_id] IDENTITY(1,1) NOT NULL, [lastname] [dbo].[shortstring] NOT NULL, [firstname] [dbo].[shortstring] NOT NULL, [middleinitial] [dbo].[letter] NULL, [street] [dbo].[shortstring] NOT NULL, [city] [dbo].[shortstring] NOT NULL, [state_prov] [dbo].[statecode] NOT NULL, [country] [dbo].[countrycode] NOT NULL, [mail_code] [dbo].[mailcode] NOT NULL, [phone_no] [dbo].[phonenumber] NULL, [photograph] [image] NU阅读全文>
发表于 @ 2008年01月18日 10:09:00|评论(loading...)|编辑
前几天给同事培训了聚集索引,非聚集索引的知识后,在一个同事新作的项目中,竟然出现了滥用聚集索引的问题。看来没有培训最最基础的索引的意义,代价,使用场景,是一个非常大的失误。这篇博客就是从这个角度来罗列索引的基础知识。 使用索引的意义 索引在数据库中的作用类似于目录在书籍中的作用,用来提高查找信息的速度。 使用索引查找数据,无需对整表进行扫描,可以快速找到所需数据。 使用索引的代价 索引需要占用数据表以外的物理存储空间。 创建索引和维护索引要花费一定的时间。 当对表进行更新操作时,索引需要被重建,这样降低了数据的维护速度。 创建索引的列 主键 外键或在表联接操作中经常用到的列 在经常查询的字段上最好建立索引 不创建索引的列 很少在查询中被引用 包含较少的惟一值 定义为 text、ntext 或者 image 数据类型的列 Heaps是staging data的很好选择,当它没有任何Index时 Exc阅读全文>
发表于 @ 2008年01月16日 14:34:00|评论(loading...)|编辑
在 ASP.net 2.0 构建的Web页面中,查看源文件,我们经常会看到下面的Html文本 <script src="/WebResource.axd?d=QfRKDnWw93T08KaF3ioSKQ2&t=633313193233609691" type="text/javascript"></script> <script src="/WebResource.axd?d=9iVKU5SS0wd5al1SYg8zjL8XXbP97LbENHerY4aLtJk1&t=633313193233609691" type="text/javascript"></script> 这是 ASP.net 2.0 提供的新的资源管理方式产生的脚本。 新的资源管理方式如何使用,你可以参看以下几篇博客: 使用ASP.NET 2.0提供的WebResource管理资源 http://birdshome.cnblogs.com/archive/2004/12/19/79309.html 在自定义Server Contr阅读全文>
发表于 @ 2008年01月14日 10:30:00|评论(loading...)|编辑
在SQL Server 2005 中新增了一个函数:newsequentialid(),MSDN 中对这个函数的描述如下: 在指定计算机上创建大于先前通过该函数生成的任何 GUID 的 GUID。NEWSEQUENTIALID() 不能在查询中引用。NEWSEQUENTIALID() 只能与 uniqueidentifier 类型表列上的 DEFAULT 约束一起使用。 这个函数的具体用法在下面这篇博客中已经有详细的描述了。 使用NEWSEQUENTIALID解决GUID聚集索引问题http://www.cnblogs.com/Mirricle/archive/2007/08/15/856726.html 简单来说,newsequentialid 函数比起 newid 函数最大的好处是: 如果你在一个 UNIQUEIDENTIFIER 字段上建立索引,使用 newid 产生的新的值是不固定的,所以新的值导致索引B+树的变化是随机的。 而 newsequentialid 产生的新的值是有规律的,则索引B+树的变化是有规律的。有规律和无规律就会带来性能的改进。 上面阅读全文>
发表于 @ 2008年01月08日 15:06:00|评论(loading...)|编辑
最近碰到一个问题,我的一个把数据库中记录的信息暴露出来的Web Service调用时候出问题了。报下面的错误信息: System.InvalidOperationException was unhandled Message="XML 文档(1, 823)中有错误。" Source="System.Xml" Message="“”(十六进制值 0x0E)是无效的字符。 行 1,位置 823。" Source="System.Xml" 当这个错误发生时,Web Service 服务器端不会有任何错误,而调用这个 Web Service 的客户端则会报上述错误。是何原因导致的这个问题呢? 答案很简单,是WEB Service 暴露的XML文档中存在低序位非打印 ASCII 字符所致。我们查看 Web Service 返回的XML 文档文档中,会有下面的XML文档节:其中的 &#xE; 就是低序位 ASCII 字符阅读全文>
发表于 @ 2008年01月08日 13:40:00|评论(loading...)|编辑
有些人可能对主键和聚集索引有所混淆,其实这两个是不同的概念,下面是一个简单的描述。不想看绕口文字者,直接看两者的对比表。尤其是最后一项的比较。 主键(PRIMARY KEY ) 来自MSDN的描述: 表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。在创建或修改表时,您可以通过定义 PRIMARY KEY 约束来创建主键。 一个表只能有一个 PRIMARY KEY 约束,并且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束可保证数据的唯一性,因此经常对标识列定义这种约束。 如果为表指定了 PRIMARY KEY 约束,则 SQL Server 2005 数据库引擎 将通过为主键列创建唯一索引来强制数据的唯一性。当在查询中使用主键时,此索引还可用来对数据进行快速访问。因此,所选的主键必须遵守创建唯一索引的规则。 创建主键时,数据库引擎 会自动创建唯一的索引来强制实施 PRIMARY KEY 约束的唯一性要求。如果表中不存在聚集索引或未显式指定非聚集索引,则将创建唯一的聚集索引以强制实阅读全文>
发表于 @ 2008年01月04日 14:06:00|评论(loading...)|编辑
之前的两篇博客中有2个例子,来演示要讲述的内容。其中提到了部分查看数据库状态的方法,那里并不是很全面,这篇博客罗列几个我们在后面系列博客中会用到查看这些状态,数据的地方。以及测试中清除缓存的方法。前面两篇博客的链接地址如下: SQL Server 索引基础知识(1)--- 记录数据的基本格式 http://blog.joycode.com/ghj/archive/2008/01/02/113290.aspx SQL Server 索引基础知识(2)----聚集索引,非聚集索引 http://blog.joycode.com/ghj/archive/2008/01/02/113291.aspx 如何获得索引的一些信息 比如:查看索引的深度SQL 脚本如下:select INDEXPROPERTY (OBJECT_ID('ChargeHeap'),'ChargeHeap_NCInd','IndexDepth')其中的 'ChargeHeap' 为我们要查看索引所在的表名,'ChargeHeap_NCInd' 为所要查看的索引名,'IndexDepth' 为所要查看的索引属性。更多属性请参看阅读全文>
发表于 @ 2008年01月04日 10:33:00|评论(loading...)|编辑
由于需要给同事培训数据库的索引知识,就收集整理了这个系列的博客。发表在这里,也是对索引知识的一个总结回顾吧。通过总结,我发现自己以前很多很模糊的概念都清晰了很多。 不论是 聚集索引,还是非聚集索引,都是用B+树来实现的。我们在了解这两种索引之前,需要先了解B+树。如果你对B树不了解的话,建议参看以下几篇文章:BTree,B-Tree,B+Tree,B*Tree都是什么 http://blog.csdn.net/manesking/archive/2007/02/09/1505979.aspx B+ 树的结构图: B+ 树的特点: 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的; 不可能在非叶子结点命中; 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层; B+ 树中增加一个数据,或者删除一个数据,需要分多种情况处理,比较复杂,这里就不详述这个内容了。 聚集索引(Clustered Index) 聚集索引的叶节点就是实际的数据页 在数据页中数据按照索引顺序存储 行的物理位置和行在索引中的位阅读全文>
发表于 @ 2008年01月02日 14:37:00|评论(loading...)|编辑
由于需要给同事培训数据库的索引知识,就收集整理了这个系列的博客。发表在这里,也是对索引知识的一个总结回顾吧。通过总结,我发现自己以前很多很模糊的概念都清晰了很多。 不论是缓存的数据信息,还是物理保存的信息,他们的基本单位都是数据页。所以理解数据页是最最基础的知识点,本篇博客就介绍跟索引有关的数据页的一些基础知识。 数据页的基础知识 SQL Server 中数据存储的基本单位是页(Page)。数据库中的数据文件(.mdf 或 .ndf)分配的磁盘空间可以从逻辑上划分成页(从 0 到 n 连续编号)。磁盘 I/O 操作在页级执行。也就是说,SQL Server 每次读取或写入数据的最少数据单位是数据页。 注意:日志文件不是用这种方式存储的,而是一系列日志记录。 数据库被分成逻辑页面(每个页面8KB),并且在每个文件中,所有页面都被连续地从0到x编号,其中x是由文件的大小决定的。我们可以通过指定一个数据库ID、一个文件ID、一个页码来引用任何一个数据页。当我们使用ALTER DATABASE命令来扩大一个文件时,新的空间会被加到文件的末尾。也就是说,我们所扩大文件的新空间第一个数据页的页阅读全文>
发表于 @ 2008年01月02日 14:34:00|评论(loading...)|编辑