SQL Server 2005是微软在推出SQL Server 2000后时隔五年推出的一个数据库.相对于SQL Server2000来说有了质的提高。它给我们提供了诸多新特性,例如:复制、分区、动态管理视图、CTE、性能顾问等等。现在,就这个帖子,和园子里的朋友们讨论一下分区。
   在微软TechNet上是这样介绍分区表和分区索引的:

Instruction   已分区表和已分区索引的数据划分为分布于一个数据库中多个文件组的单元。数据是按水平方式分区的,因此多组行映射到单个的分区。对数据进行查询或更新时,表或索引将被视为单个逻辑实体。单个索引或表的所有分区都必须位于同一个数据库中。
   已分区表和已分区索引支持与设计和查询标准表和索引相关的所有属性和功能,包括约束、默认值、标识和时间戳值以及触发器。因此,如果要实现位于服务器本地的已分区视图,则可能需要改为实现已分区表。
    决定是否实现分区主要取决于表当前的大小或将来的大小、如何使用表以及对表执行用户查询和维护操作的完善程度。
    通常,如果某个大型表同时满足下列两个条件,则可能适于进行分区:
  • 该表包含(或将包含)以多种不同方式使用的大量数据。
  • 不能按预期对表执行查询或更新,或维护开销超过了预定义的维护期。

例如,如果对当前月份的数据主要执行 INSERT、UPDATE 和 DELETE 操作,而对以前月份的数据主要执行 SELECT 查询,则如果按月份对表进行分区,表的管理可能要容易些。如果对表的常规维护操作只针对一个数据子集,那么此优点尤为明显。如果该表没有分区,那么就需要对整个数据集执行这些操作,这样就会消耗大量资源。例如,通过分区,可以针对具有只写数据的单个月份执行类似索引重新生成和碎片整理的维护操作,而只读数据仍可用于联机访问。  

   正如上面的描述,分区为可以将对数据的操作压力分散到各个分区文件组中,应用程序每次访问的数据只是在某个数据分区上,这样可以相应的提高数据库的性能。
   找个了数据量在200W左右的表,这个表是一个账本类型的表,可以以时间日期作为分区依据列,将200W数据依据月份分配到12个分区上。然后执行业务存储过程进行测试:
   
SP  exec proc_partitiontest  @HCompany=N'0002',@HOrg=N'00000000000000000223',

@FiscalYear=N'2008',@FiscalPeriod=N'01',

@HWareHouseID=N'',@SpeStock=N'',@ofObject=N'' ,......


 执行结果比较:
   分区前:执行时间52s ,IO cost:
              Table 'PartitionAccount'. Scan count 2, logical reads 1735, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
  分区后:执行时间47s ,IO cost:
         Table 'PartitionAccount'. Scan count 2, logical reads 76, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
 对性能提高很一般,是数据量较少的原因么?还是查询应用分区键不太合理?因为一些原因,这个sp的具体写法不能贴出,请各位朋友谅解。在这里,请朋友们谈谈分区的关键,谢谢。
posted @ 2008-07-17 11:09 Eric zhou 阅读(1230) | 评论 (10)编辑
   这几天,正好做oracle下数据库结构比较,比较具体详细差异,例如:2个库具体有那些表不同,不同在什么地方,主键、长度、类型......,要求是用一句sql实现,对于我这个sql菜鸟来说,的确是个挑战。好在有个SQL Server例子可以借鉴。先贴一下oracle下的sql
 1 
 2 
 3 --------------------------------------------------------------------------------------
 4 --oracle数据库帐套比较,
 5 --在本例中,databaseA数据库,
 6           --databaseB是数据库。
 7 --在实际的运行过程中,请依据需要修改本sql
 8 --------------------------------------------------------------------------------------
 9 select (case when a.表名1 is null and b.序号=1 then '库1缺少表:'||b.表名2
10                      when b.表名2 is null and a.序号=1 then '库2缺少表:'||a.表名1
11                      when a.字段名 is null and exists(select 1 from (select table_name as 表名1  from DBA_TAB_COLUMNS where upper(DBA_TAB_COLUMNS.owner) =upper('databaseB')) where 表名1=b.表名2) then '库1 ['||b.表名2||'] 缺少字段:'||b.字段名
12                      when b.字段名 is null and exists(select 1 from (select table_name as 表名2  from DBA_TAB_COLUMNS where upper(DBA_TAB_COLUMNS.owner) =upper('databaseA')) where 表名2=a.表名1) then '库2 ['||a.表名1||'] 缺少字段:'||a.字段名
13                      when a.主键<>b.主键 then '主键不同'
14                      when a.类型<>b.类型 then '类型不同'
15                      when a.字段长度<>b.字段长度 then '字段长度不同'
16                      when a.精度<>b.精度 then '精度不同'                    
17                      when a.小数位<>b.小数位 then '小数位不同'
18                      when a.允许空<>b.允许空 then '允许空不同'
19                 else '' end) result,a.*,b.*      
20 from (select a.table_name as 表名1, a.column_name as 字段名,b.constraint_type as 主键, a.data_type as 类型,column_id as 序号, a.data_length as 字段长度, a.data_precision as 精度,  a.data_scale as 小数位, a.nullable as 允许空   
21    from all_tab_columns a left join (select d.constraint_type,e.column_name,e.table_name from all_constraints d,all_cons_columns e
22  where  d.owner  =  e.owner  and d.table_name  =  e.table_name and
23   d.constraint_name  =  e.constraint_name and d.constraint_type  = 'P') b on a.COLUMN_NAME = b.column_name and a.TABLE_NAME = b.table_name
24    where  a.owner  = upper('databaseB'order by 表名1 asc) a
25 
26 full join (select a.table_name as 表名2, a.column_name as 字段名,b.constraint_type as 主键, a.data_type as 类型,column_id as 序号, a.data_length as 字段长度, a.data_precision as 精度,  a.data_scale as 小数位, a.nullable as 允许空   
27    from all_tab_columns a left join (select d.constraint_type,e.column_name,e.table_name from all_constraints d,all_cons_columns e
28  where  d.owner  =  e.owner  and d.table_name  =  e.table_name and
29   d.constraint_name  =  e.constraint_name and d.constraint_type  = 'P') b on a.COLUMN_NAME = b.column_name and a.TABLE_NAME = b.table_name
30    where  a.owner  = upper('databaseA'order by 表名2 asc) b
31 on a.表名1=b.表名2 and a.字段名=b.字段名      
32 where  a.表名1 is null or a.字段名 is null or b.表名2 is null or b.字段名 is null  or a.类型<>b.类型 or a.字段长度<>b.字段长度 or a.精度<>b.精度 or a.小数位<>b.小数位 or a.允许空<>b.允许空 or a.主键<>b.主键
33 order by nvl(a.表名1,b.表名2),nvl(a.序号,b.序号)

执行结果显示的差异信息比较详细。可以依据这个来修改数据库,比较方便。
现在分析下这句sq的语法。
1.将两个数据库oracle叫schema下的所有表结构select出来,即:
所有表结构select a.table_name as 表名1, a.column_name as 字段名,b.constraint_type as 主键, a.data_type as 类型,column_id as 序号, a.data_length as 字段长度, a.data_precision as 精度,  a.data_scale as 小数位, a.nullable as 允许空   
  from all_tab_columns a left join (select d.constraint_type,e.column_name,e.table_name from all_constraints d,all_cons_columns e
  where  d.owner  =  e.owner  and d.table_name  =  e.table_name and
   d.constraint_name  =  e.constraint_name and d.constraint_type  = 'P') b on a.COLUMN_NAME = b.column_name and a.TABLE_NAME = b.table_name
  where  a.owner  = upper('databaseB'order by 表名1 asc
通过上述sql就可以将某个数据库下的表结构select出来,通过left join 关联列的主键。
2. 将要比较的两个库的表结构用full join 关联起来。
3. 同在用case来比较具体不同信息。然后在加上where条件。

综述,比较oracle中,2个数据库的表结构基本就用上述sql比较了,效率有些慢,朋友们有好的建议可以谈谈。谢谢。
posted @ 2008-06-25 10:37 Eric zhou 阅读(147) | 评论 (0)编辑
   最近,我一值在考虑一些问题,想想自己当前的境况,想想自己的未来。感到一丝惆怅的同时,也有一些顿悟。
   从学校里,我们便被灌输:你要适应社会,不要让社会来适应你。当时考虑这些话是很对的,的确,当你刚步入社会,你的个人能力和社会经验是少的可怜,也许你有很多个性,很多理想,但在现实面前你不得不低头而放弃。那时,我明白了可以有机会去追求自己的理想是件多么快乐的事情。随着你慢慢适应社会,你的能力和社会经验得到提升,你从一个学生转变为一个职业人,你开始慢慢总结你自己,想一些事情,想自己的未来。你发现你的刺慢慢被磨平,你的理想离你越来越远,而你在做的还是不断的改变自己适应环境。这样到底对还是不对,有没有意义......一个非常矛盾的问题。
   当你很弱小时,你不得不在一些事情上低头,强制自己干一些自己不喜欢的事情,这也就应了一句话:天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,行拂乱其所为......,对啊。当你变强时,你提高了自己,但仍旧继续着不喜欢的事情,偶尔还有些郁郁不得志的感觉。这时,社会的舆论又会告诉你:不要浮躁,要塌下心干一些事情。你所在的环境——企业一边在培养你的忠诚,一边在剥削着你的剩余价值,这时的你又该如何去选择......
   程序员,是一个即充满乐趣又充斥的痛苦的职业,痛并快乐着。我们成就在自己的代码、设计思想里面,为了更强,跟得上技术的更新,不断的学习,不断的战胜自己。然而,此消彼长,这样的生活间接降低了我们生活的质量,有限的闲暇时间,休息时间......,努力提高自己的同时而放弃了很多很多,例如:爱情、友情、EQ。你会经常问自己这到底值不值?答案是肯定的:值。因为我们已经付出了努力,努力就会有回报。但你自己不想改变些什么么?
   难道你不想拥有高质量的,快乐而轻松的的生活吗?是啊,做梦都想,所以才不知疲倦的努力。其实,我们应该更具有一些魄力,重新找回自己的理想,做自己的主人。当我们在努力适应了一个发现自己不喜欢的环境后,我们可不可以换一个自己喜欢的环境呢?怎么不可以呢?也许有人会说你对企业不忠诚,但是他们怎么不说企业不善于培养员工的企业忠诚度呢?严介和:“一流企业家做人不做事,二流企业家做人又做事,三流企业家不做人只做事,一流企业做文化,二流企业做品牌,三流企业做项目。这是一句至理名言,很有道理。
    所以,我们是否应该清晰的看好当前的环境,而做出自己正确的选择呢?在这个社会找到更适应自己的环境呢?我个人感觉,我们在自我努力的同时应该更好的实现自己的价值。走自己的路让别人说去吧。
   希望作为程序员的战友们,都能找到自己的方向,自己美好的未来。
 
posted @ 2008-06-23 13:40 Eric zhou 阅读(66) | 评论 (0)编辑
   最近,在探索SQL Server2005的新特性,例如,SSIS,Replication.....,利用SSIS(Microsoft SQL Server Integration Services )将Oracle数据库整体迁移到SQL Server2005中(),Replication 实现了多个数据库服务器之间的数据同步,间接的提高的数据库的性能。相信朋友们一定很熟悉,在这里就不再赘述了。那么,今天和朋友们一起讨论讨论,利用SQL Server2005提供的namespace 编程

    在SQL Server2005 的使用当中,从2000起便提供了Script 支持,即

    
 
   这种脚本支持很方便,但需要你去选择,再去执行,time and time again,so boring.....,想个办法用程序实现。
   在TechNet searcher 一下,找到了Table,Index..... 这些class,ok,接着找到SQLServer2005联机丛书上有相关介绍:
   
Here

The Index object represents a Microsoft SQL Server index.

Namespace: Microsoft.SqlServer.Management.Smo
Assembly: Microsoft.SqlServer.Smo (in microsoft.sqlserver.smo.dll)

  仔细看了看Index的Methods,找到了script()方法,对,就这个方法。Now, coding......
 
 1private void indexScript(string servername,string username,string userpwd,string dbname,string tablename,string )schemaname
 2        {
 3            try
 4            {
 5                Server server = new Server(new ServerConnection(servername,username, userpwd));
 6                DatabaseCollection dbcollection = server.Databases;
 7                Database db = dbcollection[dbname];
 8                TableCollection tabCollection = db.Tables;
 9                Table tab = tabCollection[tablename, schemaname];
10                IndexCollection indexCollection = tab.Indexes;
11
12                for (int h = 0; h < indexCollection.Count; h++)
13                {                                       
14                    StringCollection sc = indexCollection[h].Script();
15                    StringBuilder stringbuilder = new StringBuilder();
16                    for (int i = 0; i < sc.Count; i++)
17                    {
18                        stringbuilder.Append(sc[i].ToString() + " ");
19                    }

20
21                    MessageBox.Show(stringbuilder.ToString());
22                 }

23               catch (Exception ex)
24              {
25                   throw new Exception(ex.Message);
26                 }

27           }
   这样就可以将所有 index的script 显示出来,然后你可以再操纵这些script了,例如导称sql文件再执行。至于其他object都可以使用上面的方法。
   上面这个方法只能用于rebuilder数据库对象,因为script():Generates a Transact-SQL script that can be used to re-create the index.
其他select、alter脚本估计也可以用程序实现,我正在找......,找到了再补充,呵呵。
  
posted @ 2008-05-24 17:01 Eric zhou 阅读(1269) | 评论 (3)编辑
  这些天,需要由Oracle移植到SQL Server,用到了Microsoft 的Microsoft SQL Server Migration Assistant 2005 for Oracle,用到了数据类型,所以对SQL Server 的数据类型来了个全面的学习,先总结几个关键点,于朋友们分享
The difference between char and nchar  CHAR是固定长度的字节,VARCHAR是可变长度的字节,NCHARUNICODE编码的固定字符长度。  
 
如:12345     CHAR(6)存储为123456加一个空格,共6个字节。  
         
中国       CHAR(6)存储为中国加两个空格,共6个字节。  
          12345    
VARCHAR(6)存储为123456,共5个字节。  
         
中国       VARCHAR(6)存储为中国,共4个字节。  
  NCHAR(6)
对汉字和半角字符处理时一样的, NCHARchar类似,采用Unicode标准字符集,每个字符占用两个字节空间。
The difference between Char and Varchar         char数据类型用来存储指定长度的定长非统一编码型的数据。当定义一列为此类型时,你必须指定列长。当你总能知道要存储的数据的长度时,此数据类型很有用。例如,当你按邮政编码加4个字符格式来存储数据时,你知道总要用到10个字符。此数据类型的列宽最大为8000 个字符;

varchar数据类型,同char类型一样,用来存储非统一编码型字符数据。与char 型不一样,此数据类型为变长。当定义一列为该数据类型时,你要指定该列的最大长度。它与char数据类型最大的区别是,存储的长度不是列长,而是数据的长度

The difference between Varchar and Nvarchar  varchar(n)
长度为 n 个字节的可变长度且非 Unicode 的字符数据。n 必须是一个介于 1 8,000 之间的数值。存储大小为输入数据的字节的实际长度,而不是 n 个字节。
   nvarchar(n)
 
包含 n 个字符的可变长度 Unicode 字符数据。n 的值必须介于 1 4,000 之间。字节的存储大小是所输入字符个数的两倍。

两字段分别有字段值:我和coffee
那么varchar字段占2×2+6=10个字节的存储空间,而nvarchar字段占8×2=16个字节的存储空间。
如字段值只是英文可选择varchar,而字段值存在较多的双字节(中文、韩文等)字符时用nvarchar


   就这些了,呵呵。
posted @ 2008-04-17 15:29 Eric zhou 阅读(404) | 评论 (3)编辑
园子里的朋友们:
    你们好,小弟想问大家个问题,关于个人职业发展与方向的。我现在的公司的部门调整,我以后就负责项目的性能调优,以及程序debug,还有一些维护工作,性能调优占40%,维护的占35%,程序debug占25%,维护其实在走量,学不到什么,差不多在浪费青春,性能调优和debug比较好,我个人比较喜欢设计和 写程序。
    关于性能调优和debug,咨询各位,以后发展怎么样啊?前景如何?谢谢。
posted @ 2008-04-10 09:05 Eric zhou 阅读(11) | 评论 (0)编辑
  今天看了AnyTao博客上 -------[你必须知道的.NET] 第一回:恩怨情仇:is和as ,通过MSDN,对As 和Is在C#里的用法来了个深刻的理解,现总结一下,和园子里朋友共享。
  先引用AnyTao的解释:比较好,
      
Hereis的规则如下:
  • 检查对象类型的兼容性,并返回结果,true或者false;
  • 不会抛出异常;
  • 如果对象为null,则返回值永远为false。

as的规则如下:

  • 检查对象类型的兼容性,并返回结果,如果不兼容就返回null;
  • 不会抛出异常;
  • 如果结果判断为空,则强制执行类型转换将抛出NullReferenceException异常。

 



我对“is/as操作符,提供了更加灵活的类型转型方式,但是as操作符在执行效率上更胜一筹”不太理解.......
在MSDN上search了一下,

 
As
as(C# 参考)

用于在兼容的引用类型之间执行转换。例如:

string s = someObject as string;
if (s != null)
{
    
// someObject is a string.
}
as 运算符类似于强制转换操作;但是,如果转换不可行,as 会返回 null 而不是引发异常。更严格地说,这种形式的表达式

      expression as type

equal to------>

      expression is type ? (type)expression : (type)null

只是 expression 只被计算一次。

注意,as 运算符只执行引用转换和装箱转换。as 运算符无法执行其他转换,如用户定义的转换,这类转换应使用 cast 表达式来执行

Is
is(C# 参考)

检查对象是否与给定类型兼容。例如,可以确定对象是否与 string 类型兼容,如下所示:

if (obj is string)
{
}

如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则 is 表达式的计算结果将是 true

如果已知表达式将始终是 true 或始终是 false,则 is 关键字将导致编译时警告,但是,通常在运行时才计算类型兼容性。

不能重载 is 运算符。

请注意,is 运算符只考虑引用转换、装箱转换和取消装箱转换。不考虑其他转换,如用户定义的转换。

  现在清晰多了,呵呵。
posted @ 2008-03-29 13:45 Eric zhou 阅读(1691) | 评论 (12)编辑
  前几天写了个ASP.NET程序,用到了treeview作为左边菜单,依据用户的角色来初始treeview,比较简单实用,所以现在总结一下,和博友们共享一下。
  首先需要一个关系数据库表结构:就这个结构


NodeId ModualID NodeName NodeURL
1 <null> head1 URL
2 <null> head2 URL
3 <null> head3 URL
4 1 head11 URL
5 2 head21 URL
6 3 head31 URL

public void inimenu(string strrole)
        
{
            InitTree(
this.TreeView_Menu, Appclass.TreeDataSet(strrole));            
        }

//这里Appclass.TreeDataSet(strrole)为通过用户角色strrole来初始绑定treeview对应DataSet
public static DataSet TreeDataSet(string Role)
{
   
}


public bool InitTree(TreeView treeview, DataSet ds)
        
{
            treeview.Nodes.Clear();
            ds.Relations.Add(
"NodeRelation", ds.Tables[0].Columns["NodeId"], ds.Tables[0].Columns["ModualID"], false);

            
foreach (DataRow dbRow in ds.Tables[0].Rows)
            
{
                
if (dbRow.IsNull("ModualID"))
                
{
                    TreeNode newNode 
= CreateNode(dbRow["NodeName"].ToString(), dbRow["NodeId"].ToString(), dbRow["NodeURL"].ToString());
                    treeview.Nodes.Add(newNode);
                    SubTree(dbRow, newNode);
                }

            }
          
            treeview.ExpandAll();
            
return true;
        }



  
private void SubTree(DataRow dbRow, TreeNode node)
        
{
            
foreach (DataRow childRow in dbRow.GetChildRows("NodeRelation"))
            
{
                TreeNode childNode 
= CreateNode(childRow["NodeName"].ToString(), childRow["NodeId"].ToString(), childRow["NodeURL"].ToString());
                node.ChildNodes.Add(childNode);
                SubTree(childRow, childNode);
            }

        }


        
private TreeNode CreateNode(string text, string tag,string url)
        
{
            TreeNode node 
= new TreeNode();
            node.Text 
= text;
            node.Value 
= tag;
            node.NavigateUrl 
= url;
            
return node;
        }



run ------>

可以了,呵呵
posted @ 2008-03-12 10:14 Eric zhou 阅读(222) | 评论 (1)编辑
Hi all,
  I registered my blog in here last year.As a member of cnblogs.I am pound of that.I get very much usefull knowledge from here. Now ,I am a .net software engineer.I have a long way to go.So communication is very important. Then I decide to try my best to do everything for our blog.
  Thank you.


 Eric zhou
posted @ 2008-01-18 09:50 Eric zhou 阅读(35) | 评论 (0)编辑
  这几个写程序,又不怎么熟到慢慢熟练,不仅知识上提高了,而且能力上提高了,现在独立性相当重要,对自己以后有帮助。还有,以后多考虑,在行动。这样比较好。
posted @ 2007-10-13 11:07 Eric zhou 阅读(16) | 评论 (0)编辑