[转载]大型数据库设计原则

mikel阅读(956)

[转载]大型数据库设计原则 – 将夏♂未泯‰ – 博客园.

一个好的数据库产品不等于就有一个好的应用系统,如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且 将会影响系统实际运行的性能。一般来讲,在一个MIS系统分析、设计、测试和试运行阶段,因为数据量较小,设计人员和测试人员往往只注意到功能的实现,而 很难注意到性能的薄弱之处,等到系统投入实际运行一段时间后,才发现系统的性能在降低,这时再来考虑提高系统性能则要花费更多的人力物力,而整个系统也不 可避免的形成了一个打补丁工程。笔者依据多年来设计和使用数据库的经验,提出以下一些设计准则,供同仁们参考。

命名的规范

不同的数据库产品对对象的命名有不同的要求,因此,数据库中的各种对象的命名、后台程序的代码编写应采用大小写敏感的形式,各种对象命名长度不要超过30个字符,这样便于应用系统适应不同的数据库。

游标(Cursor)的慎用

游标提供了对特定集合中逐行扫描的手段,一般使用游标逐行遍历数据,根据取出的数据不同条件进行不同的操作。尤其对多表和大表定义的游标(大的 数据集合)循环很容易使程序进入一个漫长的等特甚至死机,笔者在某市《住房公积金管理系统》进行日终帐户滚积数计息处理时,对一个10万个帐户的游标处理 导致程序进入了一个无限期的等特(后经测算需48个小时才能完成)(硬件环境:Alpha/4000 128Mram ,Sco Unix ,Sybase 11.0),后根据不同的条件改成用不同的UPDATE语句得以在二十分钟之内完成。示例如下:

Declare Mycursor cursor for select count_no from COUNT

Open Mycursor

Fetch Mycursor into @vcount_no

While (@@SQLstatus=0)

Begin

If @vcount_no=’’ 条件1

操作1

If @vcount_no=’’ 条件2

操作2

。。。

Fetch Mycursor into @vcount_no

End

。。。

。。。

改为

Update COUNT set 操作1 for 条件1

Update COUNT set 操作2 for 条件2

。。。

。。。

在有些场合,有时也非得使用游标,此时也可考虑将符合条件的数据行转入临时表中,再对临时表定义游标进行操作,可时性能得到明显提高。笔者在某 地市〈电信收费系统〉数据库后台程序设计中,对一个表(3万行中符合条件的30多行数据)进行游标操作(硬件环境:PC服务器,PII266 64Mram ,NT4.0 Ms SQLServer 6.5)。 示例如下:

Create #tmp /* 定义临时表 */

(字段1

字段2

。。。

)

Insert into #tmp select * from TOTAL where

条件 /* TOTAL中3万行 符合条件只有几十行 */

Declare Mycursor cursor for select * from #tmp

/*对临时表定义游标*/

。。。

索引(Index)的使用原则

创建索引一般有以下两个目的:维护被索引列的唯一性和提供快速访问表中数据的策略。大型数据库有两种索引即簇索引和非簇索引,一个没有簇索引的 表是按堆结构存储数据,所有的数据均添加在表的尾部,而建立了簇索引的表,其数据在物理上会按照簇索引键的顺序存储,一个表只允许有一个簇索引,因此,根 据B树结构,可以理解添加任何一种索引均能提高按索引列查询的速度,但会降低插入、更新、删除操作的性能,尤其是当填充因子(Fill Factor)较大时。所以对索引较多的表进行频繁的插入、更新、删除操作,建表和索引时因设置较小的填充因子,以便在各数据页中留下较多的自由空间,减 少页分割及重新组织的工作。

数据的一致性和完整性

为了保证数据库的一致性和完整性,设计人员往往会设计过多的表间关联(Relation),尽可能的降低数据的冗余。表间关联是一种强制性措 施,建立后,对父表(Parent Table)和子表(Child Table)的插入、更新、删除操作均要占用系统的开销,另外,最好不要用Identify 属性字段作为主键与子表关联。如果数据冗余低,数据的完整性容易得到保证,但增加了表间连接查询的操作,为了提高系统的响应时间,合理的数据冗余也是必要 的。使用规则(Rule)和约束(Check)来防止系统操作人员误输入造成数据的错误是设计人员的另一种常用手段,但是,不必要的规则和约束也会占用系 统的不必要开销,需要注意的是,约束对数据的有效性验证要比规则快。所有这些,设计人员在设计阶段应根据系统操作的类型、频度加以均衡考虑。

事务的陷阱

事务是在一次性完成的一组操作。虽然这些操作是单个的操作,SQL Server能够保证这组操作要么全部都完成,要么一点都不做。正是大型数据库的这一特性,使得数据的完整性得到了极大的保证。

—- 众所周知,SQL Server为每个独立的SQL语句都提供了隐含的事务控制,使得每个DML的数据操作得以完整提交或回滚,但是SQL Server还提供了显式事务控制语句

BEGIN TRANSACTION 开始一个事务

COMMIT TRANSACTION 提交一个事务

ROLLBACK TRANSACTION 回滚一个事务

事务可以嵌套,可以通过全局变量@@trancount检索到连接的事务处理嵌套层次。需要加以特别注意并且极容易使编程人员犯错误的是,每个 显示或隐含的事物开始都使得该变量加1,每个事务的提交使该变量减1,每个事务的回滚都会使得该变量置0,而只有当该变量为0时的事务提交(最后一个提交 语句时),这时才把物理数据写入磁盘。

数据库性能调整

在计算机硬件配置和网络设计确定的情况下,影响到应用系统性能的因素不外乎为数据库性能和客户端程序设计。而大多数数据库设计员采用两步法进行 数据库设计:首先进行逻辑设计,而后进行物理设计。数据库逻辑设计去除了所有冗余数据,提高了数据吞吐速度,保证了数据的完整性,清楚地表达数据元素之间 的关系。而对于多表之间的关联查询(尤其是大数据表)时,其性能将会降低,同时也提高了客 户端程序的编程难度,因此,物理设计需折衷考虑,根据业务规则,确定对关联表的数据量大小、数据项的访问频度,对此类数据表频繁的关联查询应适当提高数据 冗余设计。

数据类型的选择

数据类型的合理选择对于数据库的性能和操作具有很大的影响,有关这方面的书籍也有不少的阐述,这里主要介绍几点经验。

Identify字段不要作为表的主键与其它表关联,这将会影响到该表的数据迁移。

Text 和Image字段属指针型数据,主要用来存放二进制大型对象(BLOB)。这类数据的操作相比其它数据类型较慢,因此要避开使用。

日期型字段的优点是有众多的日期函数支持,因此,在日期的大小比较、加减操作上非常简单。但是,在按照日期作为条件的查询操作也要用函数,相比其它数据类型速度上就慢许多,因为用函数作为查询的条件时,服务器无法用先进的性能策略来优化查询而只能进行表扫描遍历每行。

例如:要从DATA_TAB1中(其中有一个名为DATE的日期字段)查询1998年的所有记录。

Select * from DATA_TAB1 where datepart(yy,DATE)=1998

[转载]Meta标签——网站中必不可少的一部分

mikel阅读(1247)

[转载]Meta标签——网站中必不可少的一部分 – 清风飘过 – 博客园.

今天一个偶然的机会让笔者发现HTML语言中的META元素,它位于HTML文档头部的<HEAD>标记 和<TITLE>标记之间,它提供用户不可见的信息。meta标签通常用来为搜索引擎robots定义页面主题,或者是定义用户浏览器上的 cookie;它可以用于鉴别作者,设定页面格式,标注内容提要和关键字;还可以设置页面使其可以根据你定义的时间间隔刷新自己,以及设置RASC内容等 级,等等。

这个标签可能被大多数人给忽略掉了,最起码笔者忽略掉了它。原因笔者一般用VS2008建立网站或者B/S系统,使用控件完成设计的要求,了不 起使用<img></img>,<table></table>,<a herf>等等常用到的,也不考虑搜索引擎怎么搜索网页等等。然而今天笔者发现Meta这个元素也是很重要的。那么首先我们看看博客园首页的源代码

在看codeproject网站

都用到了大量的<meta>标签,如果没看懂上面meta的作用不要紧,下面笔者就为大家介绍下meta

http-equiv属性

http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参

meta标签的http-equiv属性语法格式是:<meta http-equiv=”参数” content=”参数变量值”> ;

A、Expires(期限)

说明:可以用于设定网页的到期时间。一旦网页过期,必须到服务器上重新传输。

用法:<meta http-equiv=”expires” content=”Fri, 12 Jan 2001 18:18:18 GMT”>

注意:必须使用GMT的时间格式。

B、Pragma(cache模式)

说明:禁止浏览器从本地计算机的缓存中访问页面内容。

用法:<meta http-equiv=”Pragma” content=”no-cache”>

注意:这样设定,访问者将无法脱机浏览。

C、Refresh(刷新)

说明:自动刷新并指向新页面。

用法:<meta http-equiv=”Refresh” content=”2;URL=http://www.root.net”>

注意:其中的2是指停留2秒钟后自动刷新到URL网址。

D、Set-Cookie(cookie设定)

说明:如果网页过期,那么存盘的cookie将被删除。

用法:<meta http-equiv=”Set-Cookie” content=”cookievalue=xxx; expires=Friday, 12-Jan-2001 18:18:18 GMT; path=/”>

注意:必须使用GMT的时间格式。

E、Window-target(显示窗口的设定)

说明:强制页面在当前窗口以独立页面显示。

用法:<meta http-equiv=”Window-target” content=”_top”>

注意:用来防止别人在框架里调用自己的页面。

F、content-Type(显示字符集的设定)

说明:设定页面使用的字符集。

用法:<meta http-equiv=”content-Type” content=”text/html; charset=gb2312″>

name属性

name属性主要用于描述网页,与之对应的属性值为content,content中的内容主要是便于搜索引擎机器人查找信息和分类信息用的。这 个属性设置好了,很有利于在搜索引擎上找到我们的网站。最重要的就是对Keywords和description的设置。因为按照搜索引擎的工作原理,搜 索引擎首先派出机器人自动检索页面中的keywords和description,并将其加入到自己的数据库,然后再根据关键词的密度将网站排序。因此大 家可以看到博客园对Keywords描述可以说是相当的全面。

A、Keywords(关键字)

说明:keywords用来告诉搜索引擎你网页的关键字是什么。

举例:<meta name =”keywords” content=”science, education,culture,politics,ecnomics,relationships, entertaiment, human”>

B、description(网站内容描述)

说明:description用来告诉搜索引擎你的网站主要内容。

举例:<meta name=”description” content=”This page is about the meaning of science, education,culture.”>

C、robots(机器人向导)

说明:robots用来告诉搜索机器人哪些页面需要索引,哪些页面不需要索引。

content的参数有all,none,index,noindex,follow,nofollow。默认是all。

举例:<meta name=”robots” content=”none”>

D、author(作者)

说明:标注网页的作者

举例:<meta name=”author” content=”root,root@21cn.com”>

那么我们可以看到以上两个网站,都利用此元素做出了详细的描述,为的就是让网站更了有利于出现在搜索引擎上。

好了,既然了解了Meta元素,那么笔者建议把我们一些个人网站,商业网站,没有对meta很重视的,或者描述不详细的可以在此做出更改

参考:百度百科 http://baike.baidu.com/view/953191.htm?fr=ala0_1

一位园有的随笔 http://www.cnblogs.com/esshs/articles/157588.html

[转载]SQL Server——存储过程

mikel阅读(959)

[转载]SQL Server——存储过程 – 潇湘隐者 – 博客园.

我想从下面几个方面大概的讲述下存储过程,可能有些知识点是你没有注意的,也可能有些知识点我不知道,欢迎大家指点指点。如有不足,欢迎指教!

存储过程概念

存储过程优点

存储过程的接口

存储过程的解析、编译过程

存储过程安全性

查看存储过程

加密、解密存储过程

存储过程概念

存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(带参存储过程)来执行它。

存储过程优点

开发过程中使用存储过程的优点, 概括起来大体有下面一些:
1: 速度快、性能好。存储过程是一组已经编译过的SQL脚本,它已经进过解析、编译、优化器优化。调用存储过程可以 重复使用它的缓存执行计划。这样节省了解析、分析等所      需消耗的CPU资源。时间
2: 存储过程存储在数据库服务器,可以减少网络通信,减少网络阻塞。 调用存储过程只需存储过程名字和参数,从而避免了    把长串的SQL语句传送到SQL 服务器,可以大大减      轻网络负担。
3: 业务逻辑封装,可以把相当一部分业务逻辑封装到存储过程中,当业务逻辑变更的时候,只要接口不变,只需修改存储过程内部逻辑就OK了,避免了业务逻辑放在代码层,业务      逻辑变动改动大的痛苦。
4: 安全性  参数化的存储过程可以减少SQL Injiection攻击,而且可以通过检验参数、授予对象执行权限提高了安全性。
存储过程按类型分为:系统存储过程、扩展存储过程、用户存储过程(包括CLR存储过程)、临时存储过程(其中又分为全局临时存储过程、局部临时存储过程)。系统存储过程一般以SP做前缀开头。扩展存储过程一般以XP为前缀,自定义存储过程命名,我习惯以USP为前缀。
存储过程的接口
存储过程的参数可以是输入参数、输出参数。先看看下面两个存储过程,第一个存储过程:有两个输入参数@EmployeeID、@EmployeeName,其中@EmployeeID 的默认值是 -1, @EmployeeName 的默认值是 NULL。
USE MyAssistant;
GO

IF OBJECT_ID(Ndbo.USP_GetEmployeById) IS NOT NULL
BEGIN
DROP PROC dbo.USP_GetEmployeById;
END
GO

====================================================================================================
Function              :        按员工号获取员工信息
Author                :        Kerry
Create Date           :        2010-08-10
Description           :
—————————————————————————————————-
2010-08-13            :        修改…….增加…..
2010-08-14            :        修改…….增加…..
====================================================================================================
CREATE PROCEDURE dbo.USP_GetEmployeById
@EmployeeID INT = 1,
@EmployeeName NVARCHAR(30) = NULL
AS

SET NOCOUNT ON;

BEGIN

IF (@EmployeeID = 1 AND @EmployeeName IS NULL)
BEGIN
PRINT 请输入员工ID号或是用户名字;
END

IF @EmployeeID = 1
SELECT * FROM dbo.Employee WHERE EmployeeName = @EmployeeName;
ELSE
SELECT * FROM dbo.Employee WHERE EmployeeID = @EmployeeID;

END
GO

代码

USE MyAssistant;
GO

IF OBJECT_ID(Ndbo.USP_AddEmploye) IS NOT NULL
BEGIN
DROP PROC dbo.USP_AddEmploye;
END
GO

==========================================================================================================
Function              :        新增一条员工记录。
Author                :        Kerry
Create Date           :        2010-08-10
Description           :
———————————————————————————————————–
2010-08-13            :        修改…….增加…..
2010-08-14            :        修改…….增加…..
==========================================================================================================
CREATE PROCEDURE dbo.USP_AddEmploye
@EmployeeName NVARCHAR(30),
@Sex BIT = 1,
@Department NVARCHAR(20),
@Success NVARCHAR(4) OUTPUT
AS

SET NOCOUNT ON;

BEGIN TRY

IF (@EmployeeName IS NULL OR LEN(@EmployeeName) =0)
BEGIN
PRINT (员工姓名不能为空);
SET @Success =失败;
RETURN;
END

INSERT INTO Employee
VALUES(@EmployeeName, @Sex, @Department)

IF @@error = 0
SET @Success =成功;
END TRY

BEGIN CATCH
SET @Success =失败;

SELECT
ERROR_NUMBER()
AS ErrorNumber
,ERROR_SEVERITY()
AS ErrorSevertiy
,ERROR_STATE()
AS ErrorState
,ERROR_LINE()
AS ErrorLine
,ERROR_PROCEDURE()
AS ErrorProcedure
,ERROR_MESSAGE()
AS ErrorMessage
END CATCH
GO

你可以这样去调用、执行存储过程 ,也可以不用添加@EmployeeName这样的参数。

DECLARE @Result NVARCHAR(4);


SET @Result = ;
EXEC dbo.USP_AddEmploye
@EmployeeName =张飞,
@Sex =1 ,
@Department = 市场部,
@Success = @Result OUTPUT

SELECT @Result;
GO

一 般在执行存储过程是,最好加上架构名称,例如:dbo.USP_AddEmploye  这样可以可以减少不必要的系统开销,提高性能。 因为如果在存储过程名称前面没有加上架构名称、SQL SERVER 首先会从当前数据库sys schema开始查找,如果没有找到,则会去其它schema查找,最后在dbo架构里面查找。

存储过程的解析、编译过程

创建存储过程时,首先分析检查语法的正确性。如果在过程定义中遇到语法错误,将会返回错误,创建存储过程失败。如果语法正确,存储过程的文本将会存储在SYS.SQL_MODULES 目录视图中。

SELECT * FROM SYS.SQL_MODULES WHERE object_id =OBJECT_ID(Ndbo.USP_GetEmployeById)

下面我们来看看一个有趣的小列子,你也可以试试。创建一个存储过程USP_GetTableTest,它里面引用了表Test,表Test根本不存在。

CREATE PROCEDURE USP_GetTableTest
AS
BEGIN
SELECT * FROM TEST;
END

创建该存储过程时,不会出错,但是执行存储过程时,会爆出下面这样的错误

这 是因为在存储过程创建时,它先做语法检查,如果通过了语法检查,它会尝试解析它包含的对象名,如果存在也会解析该对象引用的对象是否存在。如果引用的对象 名不存在,解析会在存储过程首次执行时触发。即在首次执行存储过程时,查询处理器从 sys.sql_modules 目录视图中读取该存储过程的文本,并检查该过程所使用的对象名称是否存在。这一过程称为延迟名称解析,因为存储过程引用的表对象不需要在创建该存储过程时 就存在,而只需在执行该存储过程时存在。

注意:

只有当引用的表对象不存在时才能使用延迟名称解析。所有其他对象在创建所存储的过程时必须存在。例如,引用所存储的过程中的一个现有表时,不能列出该表不存在的列。

看看下面的列子就知道了,我们先创建表TEST(col1); 然后在存储过程 USP_GetTableTest中查询它不存在的列col2

代码

CREATE TABLE TEST (col1 INT);
GO

IF OBJECT_ID(NUSP_GetTableTest) IS NOT NULL
BEGIN
DROP PROC USP_GetTableTest;
END
GO

CREATE PROCEDURE USP_GetTableTest
AS
BEGIN
SELECT col2 FROM TEST;
END

创建存储过程时,它会报如下错误提示。

在 解析阶段,Microsoft SQL Server 2005 还执行其他验证活动(例如,检查列数据类型与变量的兼容性)。如果执行存储过程时存储过程所引用的对象丢失,则存储过程在到达引用丢失对象的语句时将停止 执行。在这种情况下,或在解析阶段发现其他错误时,将返回错误信息。

如果执行过程时成功通过解析阶段,则 Microsoft SQL Server 查询优化器将分析存储过程中的 Transact-SQL 语句并创建一个执行计划。执行计划描述执行存储过程的最快方法,所依据的信息包括:

表中的数据量。

表的索引的存在及特征,以及数据在索引列中的分布。

WHERE 子句条件所使用的比较运算符和比较值。

是否存在联接以及 UNION、GROUP BY 和 ORDER BY 关键字。

查询优化器在分析完存储过程中的这些因素后,将执行计划置于内存中。分析存储过程和创建执行计划的过程称为编译。优化的内存中的执行计划将用来执行该查询。执行计划将驻留在内存中,直到重新启动 SQL Server 或其他对象需要存储空间时为止。

如果随后执行了存储过程,而现有执行计划仍留在内存中,则 SQL Server 将重用现有执行计划。如果执行计划不再位于内存中,则创建新的执行计划。

存储过程安全性

在sa账号下面,执行了下面这条语句

DENY INSERT ON dbo.Employee TO Kerry;
GRANT EXECUTE ON dbo.USP_AddEmploye TO Kerry;

然后我们用Kerry这个账号登陆,往表Employee离插入一条数据

而你调用存储过程,往表Employee离插入一条数据,则如图所示

这种安全模式能让你很灵活的控制用户允许进行的活动.

查看存储过程

查看存储过程的方式很多,你可以如图所示,你可以在MSMS工具中选择“修改存储过程”或是“编写存储过程为”来查看存储过程,也可以通过查询视图,或是系统存储过程来查看你想要看的存储过程

代码

SP_HELP dbo.USP_GetEmployeById 查看存储过程的基本信息:例如参数等

SP_HELPTEXT
dbo.USP_GetEmployeById 查看具体的存储过程

SELECT * FROM SYS.SQL_MODULES WHERE object_id =OBJECT_ID(Ndbo.USP_GetEmployeById) 查看具体的存储过程

加密、解密存储过程

存 储过程加密一般是为了安全需要、或是保护源代码需要而加密存储过程,它一般通过关键字ENCRYPTION 来实现。SQL Server 将 CREATE PROCEDURE 语句的原始文本转换为模糊格式。模糊代码的输出在 SQL Server 2005 的任何目录视图中都不能直接显示。对系统表或数据库文件没有访问权限的用户不能检索模糊文本。但是,可通过 DAC 端口访问系统表的特权用户或直接访问数据库文件的特权用户可使用此文本。此外,能够向服务器进程附加调试器的用户可在运行时从内存中检索已解密的过程。

我们先把刚才那个存储过程加密吧

代码

USE MyAssistant;
GO

IF OBJECT_ID(Ndbo.USP_GetEmployeById) IS NOT NULL
BEGIN
DROP PROC dbo.USP_GetEmployeById;
END
GO

================================================================================================
Function              :        按员工号获取员工信息
Author                :        Kerry
Create Date           :        2010-08-10
Description           :
————————————————————————————————
2010-08-13            :        修改…….增加…..
2010-08-14            :        修改…….增加…..
================================================================================================
CREATE PROCEDURE dbo.USP_GetEmployeById
@EmployeeID INT = 1,
@EmployeeName NVARCHAR(30) = NULL
WITH ENCRYPTION
AS

SET NOCOUNT ON;

BEGIN

IF (@EmployeeID = 1 AND @EmployeeName IS NULL)
BEGIN
PRINT 请输入员工ID号或是用户名字;
END

IF @EmployeeID = 1
SELECT * FROM dbo.Employee WHERE EmployeeName = @EmployeeName;
ELSE
SELECT * FROM dbo.Employee WHERE EmployeeID = @EmployeeID;

END
GO

执行以后,你可以看见加密过后的存储过程,它的图标多了个小锁,而且你再也不能通过上面查看存储过程的方式来查看存储过程了。使用MSMS查看则会弹出下面错误提示

而用SP_HELPTEXT 则提示:对象 ‘dbo.USP_GetEmployeById’ 的文本已加密。

SQLServer2005 里使用WITH ENCRYPTION选项创建的存储过程仍然和SQLServer2000里一样,都是使用XOR进行了的加密。和2000不一样的是,在2005的系统 表syscomments里已经查不到加密过的密文了。要查密文必须使用DAC(专用管理员连接)连接到数据库后,如果你接手了数据库管理,里面有些存储 过程加密了,你又没有创建加密存储过程的那些脚本,你是否干着急啊。别急,呵呵,网上有位叫王成辉翻译整理了国外大牛写的解密加密存储过程的一个存储过程 usp_decrypt。呵呵,有兴趣的可以找来看看,我在SQL SERVER 05下面实验过了,确实能解密已经被加密的存储过程。

[转载].NET2.0下使用LinqMySQL

mikel阅读(1040)

[转载].NET2.0下使用LinqMySQL – 沉默的代码 – 博客园.

一、准备工作,我们需要安装一些东西,并拷贝一些东西。

0.打开VS2008或VS2010,新建工程控制台项目LinqMySQL,目标程序集为.NET 3.5

1.下载并一路NEXT安装MySQL

2.下载并一路NEXT安装MySQLWorkBench 打开,并创建test数据库,Customers和Orders两张表

—————————————————–

create table Customers
(
CustomerID varchar(50) not null primary key,
ContractName varchar(50) not null,
Phone varchar(50) not null,
City varchar(50) not null,
Country varchar(50) not null
)
create table Orders
(
OrderID int not null primary key,
OrderDate DateTime,
CustomerId varchar(50) not null,

foreign key(CustomerID) references Customers(CustomerID)
)

—————————————————–

3.下载并一路NEXT安装MySQL .NET Connector 6.3.2

4.下载并解压DbLinq,并设置路径到系统环境变量

5.在LinqMySQL目录下新建LinqDlls文件夹

打开文件夹 C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5

拷贝以下几个Dll到LinqDlls文件夹

—————————————————–

System.Core.dll
System.Data.DataSetExtensions.dll
System.Data.Linq.dll
System.Runtime.Serialization.dll
System.Xml.Linq.dll

—————————————————–

6.进入MySQL\MySQL Connector Net 6.3.2\Assemblies\v2.0目录下拷贝

—————————————————–

MySql.Data.dll

—————————————————–

到DbLinq的安装目录

二、开始工作了,我们一步步来。

1.打开CMD,CD到DbLinq目录使用DbMetal.exe创建MySQL的DataContext,命令如下:

—————————————————–

DbMetal.exe

-provider=MySql

-database:MyDatebase

-server:localhost

-user:mysqluser

-password:yourpassword

-namespace:LinqMySql

-code:TestDataContext.cs

-sprocs

—————————————————–

将生成的TestDataContext.cs剪切到LinqMySql项目根目录,并添加到LinqMySql项目

2.在Main函数里面添加如下代码

—————————————————–

string connStr = @"server=localhost;database=test;user=mysqluser;pwd=yourpassword;";
using (var conn = new MySqlConnection(connStr))
{
    var t = new Test(conn);
    var data = from customer in t.Customers
                select customer.ContractName;
    foreach (var d in data)
    {
        Console.WriteLine(d);
    }
}
-----------------------------------------------------

3.编译并运行,成功。

4.接下来我们要将.NET 3.5退化到.NET2.0,首先将工程的目标程序集改为.NET2.0,

然后会发现Reference里面有几个dll变为感叹号,将他们都删除,然后将LinqDlls文件夹下的

几个Dll都添加至Referece,然后分别将这几个Dll属性里面的copy local设置为True,将Specify Version设置为False

5.再次编译,则成功!

三、其他故事呢?尝试在.NET2.0下使用LinqDataSet,并且数据库使用MySQL

1.重启VS,使得刚刚添加到MySQL连接器被VS加载。

2.打开Server Explorer,右键Data Connection,添加新链接,改变数据连接器

选择MySql Connector,一路NEXT输入必要的服务器地址,用户名,密码,并测试连接是否成功。

3.将LinqMySql目标程序集更改为.NET3.5,右键工程添加强类型DataSet。

将Server Explorer里的Mysql test数据库下的Customers和Orders表添加到DataSet里。

4.在Main函数里编写测试代码

-----------------------------------------------------

Snippetusing (var dataSet = new DataSet1())
{
    var customerAdapter = new DataSet1TableAdapters.CustomersTableAdapter();
    var orderAdapter = new DataSet1TableAdapters.OrdersTableAdapter();
    customerAdapter.Fill(dataSet.Customers);
    orderAdapter.Fill(dataSet.Orders);
    var query =
        from order in dataSet.Orders
        where order.OrderDate.Date > new DateTime(2010, 8, 1)
        select new { order.OrderID, order.CustomerID };
    foreach (var order in query)
    {
        Console.WriteLine(order.CustomerID);
    }
}
-----------------------------------------------------

5.编译并运行,成功!

6.等等,现在还只是.NET3.5的,如何来改变到.NET2.0?

尝试直接将目标程序集改变为.NET2.0,编译,失败!

7.TMD查看了下DataSet1.designer.cs,发现在.NET3.5下的如下代码

-----------------------------------------------------
public partial class customersDataTable : global::System.Data.TypedTableBase<customersRow>

-----------------------------------------------------

现在变成了

-----------------------------------------------------

Snippetpublic partial class customersDataTable : 
global::System.Data.DataTableglobal::System.Collections.IEnumerable
-----------------------------------------------------

8.所以呢?怎么办?重新将目标程序集设置为.NET3.5,然后到LinqMySql目录下将

—————————————————–

DataSet1.Designer.cs
DataSet1.xsc
DataSet1.xsd
DataSet1.xss

——————————————————

几个文件拷贝出来做一个备份,然后将目标程序集再次设置为.NET2.0,然后。。

然后将刚才备份的以上几个文件重新拷贝回工程目录,再次编译运行,成功!

9.至此,我们成功在.NET2.0下使用LinqSQL和LinqDataSet来使用MySql了,但是

我并没有成功在.NET2.0下成功使用LinqEntity来使用MySql。以后再说吧。

[转载]InfoQ: Google提出Web性能优化新方法

mikel阅读(992)

[转载]InfoQ: Google提出Web性能优化新方法——Diffable.

Google Maps的开发人员Josh和James最近提出并实现了一种Web性能优化新方法——Diffable,即在浏览器加载Web页面时,促使其比较相关文件(Html、JavaScript等)在服务器端和客户端缓存区的版本并只下载差量(Deltas),降低网络下载造成的延迟。本文简要介绍了Diffable方法的背景、原理、优势和实现情况。

背景

众所周知,Google Maps是一款“重量级”的富互联网应用,主要JavaScript文件大小接近300K,而一个平常的补丁更新只有不到20K,这意味着如果用户的浏览 器已经缓存了旧版本的JavaScript文件,那么在通常情况下,用户不得不下载多余的280K(内容没有变化),页面加载速度就会受此影响。为了解决 类似问题,Google Maps的工程师提出了Diffable方法。

原理

Diffable方法需要在服务器端和客户端同时实施,如图1所示。

  • 服务器组件记录网页相关文件版本更新的差量,以便在客户端需要时向其发送补丁以更新过时的缓存文件。
  • 客户端组件(采用JavaScript编写)检测是否缓存了过时文件并在必要时请求新版本的差量补丁,与缓存的文件合并完成更新。

图1. Diffable方法原理图 (来源:Velocity 2010年会演讲资料

性能优势

对于Google Maps来说,Diffable方法节省了1200毫秒(减少页面加载时间的25%),请注意这种方法只对已经缓存旧版页面文件的Google Maps用户有效,此类用户约占全部用户的20%-25%,参见图2所示:

图2. Diffable方法在Google Maps应用的性能对比 (来源:Velocity 2010年会演讲资料

实现

Diffable方法是一种Web性能优化思想,目前Google的开发人员已经针对J2EE应用完成了相应的开源实现,采用Apache License 2.0授权,具体细节可以参考以下文档:

感兴趣的朋友可以登陆Diffable开源项目官方网站了解更多详情。

[转载]Google核心技术

mikel阅读(865)

[转载]Google核心技术 – 榆钱沽酒 – 博客园.

本篇将主要介绍Google的十个核心技术,而且可以分为四大类:

    1. 分布式基础设施:GFS,Chubby和Protocol Buffer。
    2. 分布式大规模数据处理:MapReduce和Sawzall。
    3. 分布式数据库技术:BigTable和数据库Sharding。
    4. 数据中心优化技术:数据中心高温化,12V电池和服务器整合。

分布式基础设施

GFS

由于搜索引擎需要处理海量的数据,所以Google的两位创始人Larry Page和Sergey Brin在创业初期设计一套名为“BigFiles”的文件系统,而GFS(全称为“Google File System”)这套分布式文件系统则是“BigFiles”的延续。

首先,介绍它的架构,GFS主要分为两类节点:

    1. Master节点:主要存储与数据文件相关的元数据,而不是Chunk(数据块)。元数据包括一个能将64位标签映射到数据块的位置及其组成文件 的表格,数据块副本位置和哪个进程正在读写特定的数据块等。还有Master节点会周期性地接收从每个Chunk节点来的更新(”Heart- beat”)来让元数据保持最新状态。
    2. Chunk节点:顾名思义,肯定用来存储Chunk,数据文件通过被分割为每个默认大小为64MB的Chunk的方式存储,而且每个Chunk有唯一一个64位标签,并且每个Chunk都会在整个分布式系统被复制多次,默认为3次。

下图就是GFS的架构图:

GFS  Architecture

图1. GFS的架构图(参片[15])

接着,在设计上,GFS主要有八个特点:

    1. 大文件和大数据块:数据文件的大小普遍在GB级别,而且其每个数据块默认大小为64MB,这样做的好处是减少了元数据的大小,能使Master节点能够非常方便地将元数据放置在内存中以提升访问效率。
    2. 操作以添加为主:因为文件很少被删减或者覆盖,通常只是进行添加或者读取操作,这样能充分考虑到硬盘线性吞吐量大和随机读写慢的特点。
    3. 支持容错:首先,虽然当时为了设计方便,采用了单Master的方案,但是整个系统会保证每个Master都会有其相对应的复制品,以便于在 Master节点出现问题时进行切换。其次,在Chunk层,GFS已经在设计上将节点失败视为常态,所以能非常好地处理Chunk节点失效的问题。
    4. 高吞吐量:虽然其单个节点的性能无论是从吞吐量还是延迟都很普通,但因为其支持上千的节点,所以总的数据吞吐量是非常惊人的。
    5. 保护数据:首先,文件被分割成固定尺寸的数据块以便于保存,而且每个数据块都会被系统复制三份。
    6. 扩展能力强:因为元数据偏小,使得一个Master节点能控制上千个存数据的Chunk节点。
    7. 支持压缩:对于那些稍旧的文件,可以通过对它进行压缩,来节省硬盘空间,并且压缩率非常惊人,有时甚至接近90%。
    8. 用户空间:虽然在用户空间运行在运行效率方面稍差,但是更便于开发和测试,还有能更好利用Linux的自带的一些POSIX API。

现在Google内部至少运行着200多个GFS集群,最大的集群有几千台服务器,并且服务于多个Google服务,比如 Google搜索。但由于GFS主要为搜索而设计,所以不是很适合新的一些Google产品,比YouTube、Gmail和更强调大规模索引和实时性的 Caffeine搜索引擎等,所以Google已经在开发下一代GFS,代号为“Colossus”,并且在设计方面有许多不同,比如:支持分布式 Master节点来提升高可用性并能支撑更多文件,chunk节点能支持1MB大小的chunk以支撑低延迟应用的需要。

Chubby

简单的来说,Chubby属于分布式锁服务,通过Chubby,一个分布式系统中的上千个client都能够对于某项资源进行“加锁”或者“解 锁”,常用于BigTable的协作工作,在实现方面是通过对文件的创建操作来实现“加锁”,并基于著名科学家Leslie Lamport的Paxos算法。

Protocol Buffer

Protocol Buffer,是Google内部使用一种语言中立,平台中立和可扩展的序列化结构化数据的方式,并提供java、c++ 和python这三种语言的实现,每一种实现都包含了相应语言的编译器以及库文件,而且它是一种二进制的格式,所以其速度是使用xml进行数据交换的10 倍左右。它主要用于两个方面:其一是RPC通信,它可用于分布式应用之间或者异构环境下的通信。其二是数据存储方面,因为它自描述,而且压缩很方便,所以 可用于对数据进行持久化,比如存储日志信息,并可被Map Reduce程序处理。与Protocol Buffer比较类似的产品还有Facebook的Thrift,而且Facebook号称Thrift在速度上还有一定的优势。

分布式大规模数据处理

MapReduce

首先,在Google数据中心会有大规模数据需要处理,比如被网络爬虫(Web Crawler)抓取的大量网页等。由于这些数据很多都是PB级别,导致处理工作不得不尽可能的并行化,而Google为了解决这个问题,引入了 MapReduce这个编程模型,MapReduce是源自函数式语言,主要通过”Map(映射)”和”Reduce(化简)”这两个步骤来并行处理大规 模的数据集。Map会先对由很多独立元素组成的逻辑列表中的每一个元素进行指定的操作,且原始列表不会被更改,会创建多个新的列表来保存Map的处理结 果。也就意味着,Map操作是高度并行的。当Map工作完成之后,系统会先对新生成的多个列表进行清理(Shuffle)和排序,之后会这些新创建的列表 进行Reduce操作,也就是对一个列表中的元素根据Key值进行适当的合并。

下图为MapReduce的运行机制:

Map Reduce

图2. MapReduce的运行机制(参[19])

接下来,将根据上图来举一个MapReduce的例子:比如,通过搜索Spider将海量的Web页面抓取到本地的GFS 集群中,然后Index系统将会对这个GFS集群中多个数据Chunk进行平行的Map处理,生成多个Key为URL,value为html页面的键值对 (Key-Value Map),接着系统会对这些刚生成的键值对进行Shuffle(清理),之后系统会通过Reduce操作来根据相同的key值(也就是URL)合并这些键 值对。

最后,通过MapReduce这么简单的编程模型,不仅能用于处理大规模数据,而且能将很多繁琐的细节隐藏起来,比如自动并行化,负载均衡和机器宕 机处理等,这样将极大地简化程序员的开发工作。MapReduce可用于包括“分布grep,分布排序,web访问日志分析,反向索引构建,文档聚类,机 器学习,基于统计的机器翻译,生成Google的整个搜索的索引“等大规模数据处理工作。Yahoo也推出MapReduce的开源版本Hadoop,而 且Hadoop在业界也已经被大规模使用。

Sawzall

Sawzall可以被认为是构建在MapReduce之上的采用类似Java语法的DSL(Domain-Specific Language),也可以认为它是分布式的AWK。它主要用于对大规模分布式数据进行筛选和聚合等高级数据处理操作,在实现方面,是通过解释器将其转化 为相对应的MapReduce任务。除了Google的Sawzall之外,yahoo推出了相似的Pig语言,但其语法类似于SQL

分布式数据库技术

BigTable

由于在Google的数据中心存储PB级以上的非关系型数据时候,比如网页和地理数据等,为了更好地存储和利用这些数据,Google开发了一套数 据库系统,名为“BigTable”。BigTable不是一个关系型的数据库,它也不支持关联(join)等高级SQL操作,取而代之的是多级映射的数 据结构,并是一种面向大规模处理、容错性强的自我管理系统,拥有TB级的内存和PB级的存储能力,使用结构化的文件来存储数据,并每秒可以处理数百万的读 写操作。

什么是多级映射的数据结构呢?就是一个稀疏的,多维的,排序的Map,每个Cell由行关键字,列关键字和时间戳三维定位.Cell的内容是一个不 解释的字符串,比如下表存储每个网站的内容与被其他网站的反向连接的文本。 反向的URL com.cnn.www是这行的关键字;contents列存储网页内容,每个内容有一个时间戳,因为有两个反向连接,所以archor的Column Family有两列:anchor: cnnsi.com和anchhor:my.look.ca。Column Family这个概念,使得表可以轻松地横向扩展。下面是它具体的数据模型图:

Big Table Data Model

图3. BigTable数据模型图(参[4])

在结构上,首先,BigTable基于GFS分布式文件系统和Chubby分布式锁服务。其次BigTable也分为两部分:其一是Master节 点,用来处理元数据相关的操作并支持负载均衡。其二是tablet节点,主要用于存储数据库的分片tablet,并提供相应的数据访问,同时tablet 是基于名为SSTable的格式,对压缩有很好的支持。Big Table  Architecture

图4. BigTable架构图(参[15])

BigTable正在为Google六十多种产品和项目提供存储和获取结构化数据的支撑平台,其中包括有Google Print, Orkut,Google Maps,Google Earth和Blogger等,而且Google至少运行着500个BigTable集群。

随着Google内部服务对需求的不断提高和技术的不断地发展,导致原先的BigTable已经无法满足用户的需求,而 Google也正在开发下一代BigTable,名为“Spanner(扳手)”,它主要有下面这些BigTable所无法支持的特性:

    1. 支持多种数据结构,比如table,familie,group和coprocessor等。
    2. 基于分层目录和行的细粒度的复制和权限管理。
    3. 支持跨数据中心的强一致性和弱一致性控制。
    4. 基于Paxos算法的强一致性副本同步,并支持分布式事务。
    5. 提供许多自动化操作。
    6. 强大的扩展能力,能支持百万台服务器级别的集群。
    7. 用户可以自定义诸如延迟和复制次数等重要参数以适应不同的需求。

数据库Sharding

Sharding就是分片的意思,虽然非关系型数据库比如BigTable在Google的世界中占有非常重要的地位,但是面对传统OLTP应用, 比如广告系统,Google还是采用传统的关系型数据库技术,也就是MySQL,同时由于Google所需要面对流量非常巨大,所以Google在数据库 层采用了分片(Sharding)的水平扩展(Scale Out)解决方案,分片是在传统垂直扩展(Scale Up)的分区模式上的一种提升,主要通过时间,范围和面向服务等方式来将一个大型的数据库分成多片,并且这些数据片可以跨越多个数据库和服务器来实现水平 扩展。

Google整套数据库分片技术主要有下面这些优点:

    1. 扩展性强:在Google生产环境中,已经有支持上千台服务器的MySQL分片集群。
    2. 吞吐量惊人:通过巨大的MySQL分片集群能满足巨量的查询请求。
    3. 全球备份:不仅在一个数据中心还是在全球的范围,Google都会对MySQL的分片数据进行备份,这样不仅能保护数据,而且方便扩展。

在实现方面,主要可分为两块:其一是在MySQL InnoDB基础上添加了数据库分片的技术。其二是在ORM层的Hibernate的基础上也添加了相关的分片技术,并支持虚拟分片(Virtual Shard)来便于开发和管理。同时Google也已经将这两方面的代码提交给相关组织。

数据中心优化技术

数据中心高温化

大中型数据中心的PUE(Power Usage Effectiveness)普遍在2左右,也就是在服务器等计算设备上耗1度电,在空调等辅助设备上也要消耗一度电。对一些非常出色的数据中心,最多也 就能达到1.7,但是Google通过一些有效的设计使部分数据中心到达了业界领先的1.2,在这些设计当中,其中最有特色的莫过于数据中心高温化,也就 是让数据中心内的计算设备运行在偏高的温度下,Google的能源方面的总监Erik Teetzel在谈到这点的时候说:“普通的数据中心在70华氏度(21摄氏度)下面工作,而我们则推荐80华氏度(27摄氏度)“。但是在提高数据中心 的温度方面会有两个常见的限制条件:其一是服务器设备的崩溃点,其二是精确的温度控制。如果做好这两点,数据中心就能够在高温下工作,因为假设数据中心的 管理员能对数据中心的温度进行正负1/2度的调节,这将使服务器设备能在崩溃点5度之内工作,而不是常见的20度之内,这样既经济,又安全。还有,业界传 言Intel为Google提供抗高温设计的定制芯片,但云计算界的顶级专家James Hamilton认为不太可能,因为虽然处理器也非常惧怕热量,但是与内存和硬盘相比还是强很多,所以处理器在抗高温设计中并不是一个核心因素。同时他也 非常支持使数据中心高温化这个想法,而且期望将来数据中心甚至能运行在40摄氏度下,这样不仅能节省空调方面的成本,而且对环境也很有利。

12V电池

由于传统的UPS在资源方面比较浪费,所以Google在这方面另辟蹊径,采用了给每台服务器配一个专用的12V电池的做法来替换了常用的UPS, 如果主电源系统出现故障,将由该电池负责对服务器供电。虽然大型UPS可以达到92%到95%的效率,但是比起内置电池的 99.99%而言是非常捉襟见肘的,而且由于能量守恒的原因,导致那么未被UPS充分利用的电力会被转化成热能,这将导致用于空调的能耗相应地攀升,从而 走入一个恶性循环。同时在电源方面也有类似的“神来之笔”,普通的服务器电源会同时提供5V和12V的直流电。但是Google设计的服务器电源只输出 12V直流电,必要的转换在主板上进行,虽然这种设计会使主板的成本增加1美元到2美元,但是它不仅能使电源能在接近其峰值容量的情况下运行,而且在铜线 上传输电流时效率更高。

服务器整合

谈到虚拟化的杀手锏时,第一个让人想到肯定是服务器整合,而且普遍能实现1:8的整合率来降低各方面的成本。有趣的是,Google在硬件方面也引 入类似服务器整合的想法,它的做法是在一个机箱大小的空间内放置两台服务器,这些做的好处有很多,首先,减小了占地面积。其次,通过让两台服务器共享诸如 电源等设备,来降低设备和能源等方面的投入。

http://www.chinakdd.com/portal.php?mod=view&aid=125347

[转载]MonoRail学习笔记十三:NVelocity的增强功能

mikel阅读(1103)

[转载]MonoRail学习笔记十三:NVelocity的增强功能 – 永春阁 – 博客园.

之前我转载过一篇:Velocity 模板使用指南》中文版[转] ,这个是基于最开始的Java版下的Velocity来说的。后来在castle的.NET版下又提供了一些增强功能,详见:NVelocity Improvements
本文结合一些小例子来具体谈谈这些增强功能的使用。
(有部分内容是直接翻译自NVelocity Improvements -_-)

一、支持数组参数
比如在Controller中定义如下方法:

public void Index()
{
PropertyBag.Add(
instance, this);
}

public static string Welcome(params String[] args)
{
return String.Join(, args);
}

在vm中写:

$instance.Welcome(arg1, arg2)

那么回输出如下结果:
arg1-arg2

二、内置字典支持
对于一些传参的地方很方便,比如我们常用的一种方式:

$HtmlHelper.LabelFor(elementid, Name:, %{class=’required’, accessKey=’N’})

那么会自动生成一个字典,里面包含class和accessKey两个条目

内置字典我们可以在很多场合用到,比如我们在Controller中定义一个方法:

public string DictionaryTest(string name, IDictionary attributes)
{
StringBuilder sResult
= new StringBuilder(<input type=\text\ name=’ + name + );
foreach (object key in attributes.Keys)
{
object value = attributes[key];
sResult.Append(
+ key + =’ + value + );
}


sResult.Append(
/>);

return sResult.ToString();
}

然后在vm中调用:

$instance.DictionaryTest(‘id’, “%{aa=’aa1′, value=’aa2′, value2=’aa3′}”)

会在页面中生成一个输入框,具体的html代码是:

<input type=”text” name=’id’ aa=’aa1′ value=’aa2′ value2=’aa3′ />

三、更强的foreach功能(这个功能比较好)
可以指定在foreach之前、之后等特定时候执行一些语句,具体语法如下:

#foreach($i in $items)
#each (this is optional since its the default section)
text which appears for each item
#before
text which appears before each item
#after
text which appears after each item
#between
text which appears between each two items
#odd
text which appears for every other item, including the first
#even
text which appears for every other item, starting with the second
#nodata
Content rendered if $items evaluated to null or empty
#beforeall
text which appears before the loop, only if there are items
matching condition
#afterall
text which appears after the loop, only of there are items
matching condition
#end

比如如下的一个例子:

#foreach($person in $people)
#beforeall
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
#before
<tr
#odd
Style
=’color:gray’>
#even
Style=’color:white’>

#each
<td>$person.Name</td>
<td>$person.Age</td>

#after
</tr>

#between
<tr><td colspan=’2′>$person.bio</td></tr>

#afterall
</table>

#nodata
Sorry No Person Found
#end

当我们$people中有两条记录时会生成以下html:

<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tr style=’color:white’>
<td>John</td>
<td>32</td>
</tr>
<tr><td colspan=’2′>Monorail programmer</td></tr>
<tr style=’color:gray’>
<td>Jin</td>
<td>12</td>
</tr>
<tr><td colspan=’2′>Castle guru</td></tr>
</table>

当$people为null时会直接输出:

Sorry No Person Found

四、枚举类型的改进
为了可读性,可以自己使用枚举类型的文字表达进行比较。
例:

public enum OrderStatus
{
Undefined,
Created,
Dispatched
}

那么可以在vm中如下比较:

#if($order == “Undefined”)
Sorry, but we don’t know this order.
#elseif($order == “Created”)
Your order is being processed. Hold on!
#elseif($order == “Dispatched”)
Your order has been dispatched through UPS. Cross your fingers!
#end

(原文中好像有点问题,我重新改了一些代码)

Castle1.0 RC3中的新功能:
1、在vm中,方法和属性不再区分大小写,使用时可以不必记住大小写了
2、字典功能改进,在vm字典调用时可以直接使用以下方式(参见上面的内置字典支持):
key='value' key=1 key=1.2 key='1' $key='value' key=$value key='some$value'

[转载]Flash 报表之 LineChart & PieChart

mikel阅读(1317)

[转载]Flash 报表之 LineChart & PieChart – 情缘 – 博客园.

1.LineChart 主要用于用线条显示数据图表信息

2. LineChart 的使用代码

代码

1 <?xml version=1.0 encoding=utf-8?>
2 <mx:Application xmlns:mx=http://www.adobe.com/2006/mxml layout=absolute>
3 <mx:Script>
4 <![CDATA[
5 import mx.collections.ArrayCollection;
6
7 public var scores:ArrayCollection=new ArrayCollection([
8 {id:1,name:贺臣,Maths:98,Chinese:82},
9 {id:2,name:菜包,Maths:66,Chinese:77},
10 {id:3,name:张三,Maths:23,Chinese:99},
11 {id:4,name:王五,Maths:88,Chinese:55}
12 ]);
13
14 ]]>
15 </mx:Script>
16 <mx:Panel x=98 y=40 width=485 height=392 layout=absolute>
17 <mx:LineChart x=10 y=10 id=myLineChart width=445 height=261 showDataTips=true dataProvider={scores}>
18 <mx:horizontalAxis>
19 <mx:CategoryAxis dataProvider={scores} categoryField=name/>
20 </mx:horizontalAxis>
21 <mx:series>
22 <mx:LineSeries yField=Maths xField=name displayName=数学/>
23 <mx:LineSeries yField=Chinese xField=name displayName=中文/>
24 </mx:series>
25 </mx:LineChart>
26 <mx:Legend dataProvider={myLineChart} x=10 y=289 width=445/>
27 </mx:Panel>
28 </mx:Application>

3. LineChart 属性

xField 用于横坐标数据显示

yField 用于纵坐标数据显示

4. PieChart 主要用于圆饼图显示相关数据,圆饼图分块显示数据所占份额

5.PieChart 的使用代码

代码

1 <?xml version=1.0 encoding=utf-8?>
2 <mx:Application xmlns:mx=http://www.adobe.com/2006/mxml layout=absolute>
3 <mx:Script>
4 <![CDATA[
5 import mx.collections.ArrayCollection;
6
7 public var scores:ArrayCollection=new ArrayCollection([
8 {id:1,name:贺臣,Maths:98,Chinese:82},
9 {id:2,name:菜包,Maths:66,Chinese:77},
10 {id:3,name:张三,Maths:23,Chinese:99},
11 {id:4,name:王五,Maths:88,Chinese:55}
12 ]);
13
14 ]]>
15 </mx:Script>
16 <mx:Panel x=98 y=40 width=485 height=392 layout=absolute>
17 <mx:PieChart x=10 y=10 id=myPieChart height=268 width=445 dataProvider={scores} showDataTips=true>
18 <mx:series>
19 <mx:PieSeries field=Maths nameField=name labelPosition=callout displayName=数学/>
20 </mx:series>
21 </mx:PieChart>
22 <mx:Legend dataProvider={myPieChart} x=10 y=289 width=445/>
23
24 </mx:Panel>
25 </mx:Application>
26

6.PieChart 属性介绍

field 用于显示的数据项

nameField 用于显示数据项的名称

[转载]百度K淘客站的解决方法

mikel阅读(1187)

在大概一个月前,所有淘宝客站长发现了很严重的问题,尤其是用TOPAPI来做全站的淘宝客站长,问题相当严重

在问题中,我们透过问看内部。首先是一则新闻。说淘宝客遭百度封杀,起因是淘宝和百度的商业竞争所致。看完了发现更加的杯具。但是我冷静的分析了一下。这个就是我一起杯具的站汽车用品 www.gogotao.com

1、有人说百度是人工来分析数据库中的收录链接中的淘宝客,而且这个舆论很主流。但是我观察并且调查过,发现不止那些有名气的淘宝客大站,就连 刚刚起步不久的小站都被K。但是你要想,这些淘宝客小站多如牛毛,百度要想人工来K,要雇佣多少人,就是全部是兼职的来做,也不现实。

2、根据以上结论,我得出百度肯定是用机器程序来分析出淘宝客。我又进入各个淘宝客群里还有相关论坛里。发现还真有人的淘宝客站没有被K,或者说没有受到多大影响。并且这其中有很多站也是一直以来比较牛的淘客站。这点说明,还是有可能来逃避百度这次的大屠杀。

3、上面已经给了我们希望,然后就是分析为什么他们没有被K,我发现他们都有一个特点,有列表页和商品详细页!并且所有连接都是内部的列表页和详细页的连接,只在详细页有一个明式的淘宝客连接跳转,并且他们除了商品详细页以外没有任何淘宝相关的连接!

以上我得出了,淘宝是根据你整站外链的淘宝外链数来推断的,并且我分析那些被K的淘客站,发现他们都是出站外链的淘宝外链数量太多。

我把这个分析告诉了几个曾经的牛人站长,让他们重新做站来根据我这个分析来做。目前已经过去了将近一个月。那些站长反馈告诉我他们的新站都有了 不错的收录和排名没有被百度K掉,所以我来发这篇文章来联合广大淘宝客一起和百度斗争到底。我也做了一个新站,采用的资讯式的方式来少量的放淘宝客连接指甲油 www.laoniangmen.com

[转载]SQL Server 的锁定和阻塞

mikel阅读(964)

[转载]快速搞懂 SQL Server 的锁定和阻塞 – Wizard 编程网 – 博客园.

本帖提供两种做法,可避免让 client-side 程序,持续等待 SQL Server 中事务锁定造成的不正常或长时间阻塞,而让用户也无限期等待,甚至造成 connection pooling 连接数超过容量。

日前公司 server-side 有组件,疑似因撰写时 exception-handling 做得不周全,导致罕见的特殊例外发生时,让 SQL Server 的事务未执行到 cmmmit 或 rollback,造成某些表或记录被「锁定 (lock)」。后来又有大量的 request,要透过代码访问这些被锁定的记录,结果造成了严重的长时间「阻塞」,最后有大量 process 在 SQL Server 呈现「等待中」的状态。

由于 SQL Server 的「事务隔离级别」默认是 READ COMMITTED (事务期间别人无法读取),加上 SQL Server 的锁定造成阻塞时,默认是别的进程必须无限期等待 (LOCK_TIMEOUT = -1)。结果这些大量的客户端 request 无限期等待永远不会提交或回滚的事务,并一直占用着 connection pool 中的资源,最后造成 connection pooling 连接数目超载。
查了一些书,若我们要查询 SQL Server 目前会话中的 lock 超时时间,可用以下的命令:

SELECT @@LOCK_TIMEOUT
默认为 -1,意即欲访问的对象或记录被锁定时,会无限期等待。若欲更改当前会话的此值,可用下列命令:

SET LOCK_TIMEOUT 3000

后面的 3000,其单位为毫秒,亦即会先等待被锁定的对象 3 秒钟。若事务仍未释放锁,则会抛回如下代号为 1222 的错误信息,可供程序员编程时做相关的逾时处理:

消息 1222,级别 16,状态 51,第 3 行
已超过了锁请求超时时段。
若将 LOCK_TIMEOUT 设置为 0,亦即当欲访问对象被锁定时,完全不等待就抛回代号 1222 的错误信息。此外,此一 SET LOCK_TIMEOUT 命令,影响范例只限当前会话,而非对某个表做永久的设置。

——————————————————————————————-
接下来我们在 SSMS 中,开两个会话 (查询窗口) 做测试,会话 A 创建会造成阻塞的事务进程,会话 B 去访问被锁定的记录。

会话 A
BEGIN TRAN;
UPDATE Orders SET EmployeeID=7 WHERE OrderID=10248
rollback; –故意不提交或回滚
会话 B
SELECT * FROM Orders WHERE OrderID=10248

分别执行后,因为欲访问的记录是同一条,按照 SQL Server 「事务隔离级别」和「锁」的默认值,会话 B 将无法读取该条数据,而且会永远一直等下去 (若在现实项目里写出这种代码,就准备被客户和老板臭骂)。

——————————————————————————————-
若将会话 B 先加上 SET LOCK_TIMEOUT 3000 的设置,如下,则会话 B 会先等待 3 秒钟,才抛出代号 1222 的「锁请求已超时」错误信息:

SET LOCK_TIMEOUT 3000
UPDATE Orders SET EmployeeID=7 WHERE OrderID=10248
SET LOCK_TIMEOUT -1

执行结果:

消息 1222,级别 16,状态 51,第 3 行
已超过了锁请求超时时段。
语句已终止。

——————————————————————————————-
另根据我之前写的文章「30 分钟快快乐乐学 SQL Performance Tuning」所述:
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html

撰写不当的 SQL 语句,会让数据库的索引无法使用,造成全表扫描或全聚集索引扫描。例如不当的:NOT、OR 算符使用,或是直接用 + 号做来串接两个字段当作 WHERE 条件,都可能造成索引失效,变成全表扫描,除了性能变差之外,此时若这句不良的 SQL 语句,是本帖前述会话 B 的语句,由于会造成全表扫描,因此就一定会被会话 A 的事务阻塞 (因为扫描全表时,一定也会读到 OrderID=10248 的这一条记录)。
下方的 SQL 语句,由于 OrderID 字段有设索引,因此下图 1 的「执行计划」,会以算法中的「二分搜寻法」在索引中快速查找 OrderID=10250 的记录。

SELECT * FROM Orders WHERE OrderID=10250

SELECT * FROM Orders WHERE OrderID=10250 AND ShipCountry=’Brazil’

图 1 有正确使用到索引的 SQL 语句,以垂直的方向使用索引。用 AND 算符时,只要有任一个字段有加上索引,就能受惠于索引的好处,并避免全表扫描
此时若我们将这句 SQL 语句,当作前述会话 B 的语句,由于它和会话 A 所 UPDATE 的 OrderID=10248 不是同一条记录,因此不会受会话 A 事务未回滚的影响,会话 B 能正常执行 SELECT 语句。
但若我们将会话 B 的 SQL 语句,改用如下的 OR 算符,由于 ShipCountry 字段没有加上索引,此时会造成全表扫描。如此一来,除了性能低落以外,还会因为在全表扫描时,读到会话 A 中锁定的 OrderID=10248 那一条记录,造成阻塞,让会话 B 永远呈现「等待中」的状态。

SELECT * FROM Orders WHERE OrderID=10250 OR ShipCountry=’Brazil’

图 2 未正确使用索引的 SQL 语句,以水平的方向使用索引。用 OR 算符时,必须「所有」用到的字段都有加上索引,才能真正有效使用索引、避免全表扫描

——————————————————————————————-
发生阻塞时,透过以下命令,可看出是哪个进程 session id,阻塞了哪几个进程 session id,且期间经过了多少「毫秒 (ms)」。如下图 3 里 session id = 53 阻塞了 session id = 52 的进程。另透过 SQL Server Profiler 工具,也能看到相同的内容。

SELECT blocking_session_id, wait_duration_ms, session_id FROM sys.dm_os_waiting_tasks

图 3 本帖前述会话 A 的 UPDATE 语句 (53),阻塞了会话 B 的 SELECT 语句 (52)
透过以下两个命令,我们还能看到整个数据库的锁定和阻塞详细信息:

SELECT * FROM sys.dm_tran_locks

EXEC sp_lock

图 4 session id = 52 的 process 因阻塞而一直处于等待中 (WAIT)
另透过 KILL 命令,可直接杀掉造成阻塞的 process,如下:

KILL 53

——————————————————————————————-
欲解决无限期等待的问题,除了前述的 SET LOCK_TIMEOUT 命令外,还有更省事的做法,如下,在会话 B 的 SQL 语句中,在表名称后面加上 WITH (NOLOCK) 关键字,表示要求  SQL Server,不必去考虑这个表的锁定状态为何,因此也可减少「死锁 (dead lock)」发生的机率。但 WITH (NOLOCK) 不适用 INSERT、UPDATE、DELETE。

SELECT * FROM Orders WITH (NOLOCK) WHERE OrderID=10248
类似的功能,也可如下,在 SQL 语句前,先设置「事务隔离级别」为可「脏读 (dirty read)」。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM Orders WHERE OrderID=10248
两种做法的效果类似,让会话 B 即使读到被锁阻塞的记录,也永远不必等待,但可能读到别人未提交的数据。虽然说这种做法让会话 B 不用请求共享锁,亦即永远不会和其他事务发生冲突,但应考虑项目开发实际的需求,若是会话 B 要查询的是原物料的库存量,或银行系统的关键数据,就不适合用这种做法,而应改用第一种做法的 SET LOCK_TIMEOUT 命令,明确让数据库抛回等候逾时的错误代号 1222,再自己写代码做处理。
——————————————————————————————-
归根究柢,我们在编程时,就应该避免写出会造成长时间阻塞的 SQL 语句,亦即应最小化锁定争用的可能性,以下为一些建议:

  • 尽可能让事务轻薄短小、让锁定的时间尽量短,例如把不必要的命令移出事务外,或把一个大量更新的事务,切成多个更新较少的事务,以改善并发性。
  • 将组成事务的 SQL 语句,摆到一个「批 (batch) 处理」,以避免不必要的延迟。这些延迟常由 BEGIN TRAN … COMMIT TRAN 命令之间的网络 I/O 所引起。
  • 考虑将事务的 SQL 语句写在一个存储过程内。一般来说,存储过程的执行速度会比批处理的 SQL 语句快,且存储过程可降低网络的流量和 I/O,让事务可更快完成。
  • 尽可能频繁地认可 Cursor 中的更新,因为 Cursor 的处理速度较慢,会让锁定的时间较长。
  • 若无必要,使用较宽松的事务隔离级别,如前述的 WITH (NOLOCK) 和 READ UNCOMMITTED。而非为了项目开发方便,全部使用默认的 READ COMMITTED 级别。
  • 避免在事务执行期间,还要等待用户的反馈或交互,这样可能会造成无限期的持有锁定,如同本帖一开始提到的状况,最后造成大量的阻塞和数据库 connection 被占用。
  • 避免事务 BEGIN TRAN 后查询的数据,可能在事务开始之前先被引用。
  • 避免在查询时 JOIN 过多的表,否则除了性能较差外,也很容易读到正被锁定或阻塞中的表和字段。
  • 应注意在一个没有索引的表上,过量的「行锁」,或一些锁定使用了过多的内存和系统资源时,SQL Server 为了有效地管理这些锁定,会尝试将锁定扩展为整个表的「表锁」,此时会很容易造成其他 process 在访问时的阻塞和等待。