2019年6月25日 By mikel 分类: Debug, 数据库

来源: SQL 2005 的存储过程和触发器调试大法(转) – ct – 博客园

昨天晚上我找遍了互联网也没有发现关于SQL2005存储过程和触发器的调试方法,研究到凌晨2点多钟,终于找到方法了,不干独享,拿出来分享。如果要转载,请保留版权,谢谢!
SQL2000中,我们想要调试存储过程非常简单,只需要在对象浏览器中找到存储过程,然后点击鼠标右键选择“执行(调试)”就可以弹出一个工具栏出来,进行调试。然而到了SQL2005中同样的操作却变成了生成一段SQL语法,没有调试功能,如果使用了Express版本会更加郁闷,连“执行”菜单都没有,如图所示:Express版本中,菜单中根本没有“执行”功能。

那么调试功能到什么地方去了呢?
别急,我找到了。原来微软把调试功能放在了VS2005中了。注意是VS2005,不是SQL2005,打开VS2005,选择工具、再选择“连接到数据库”。选择正确的数据库名和表名,填入正确的登陆信息就可以了,如图:


在”服务器资源管理“就可以看到写在数据库中的存储过程和触发器代码了,右击相应的存储过程,便可以看见”单步执行调试“的字样如图所示:如果这段存储过程可以触发”触发器“中代码,那么触发器的代码也是可以调试的。

我来举个例子调试一下。
1、在数据中建立一个表AllMoney
列 ID   类型 INT ,该字段为自增字段,每插入一条数据就增加一个。
列 MyMoney 类型 Money

2、在数据中建立一个表LastID
列 ALLMoneyID 类型为INT,该字段将通过触发起自动更新值,当表AllMoney每插入一列的时候,这个字段就自动更新为AllMoney中的最大ID值。

3、建立存储过程给AllMoney添加数据:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE SP_InsertMoney
@MyMoney AS MONEY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO AllMoney(MyMoney) VALUES(@MyMoney)
END
GO

4、在表AllMoney中建立触发器,更新表LastID
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER INSERT_LastID
ON AllMoney
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE @ID AS INT
SELECT @ID = MAX(ID) FROM AllMoney
UPDATE LastID SET AllMoneyID=@ID
END
GO

当上面两个添加好后,然后再VS中来调试。

首先打开触发器代码。并设置断点:

然后选择存储过程,点击右键选择单步调试存储过程。
在弹出的对话框填入正确的参数:

这是就可以按F10来进行调试了,当数据插入成功后,就会触发”触发器“代码,前面我们在触发器中设置断点就会断下来了,如图:

还可以看见变量的值,很不错吧!

SQL 2005 的存储过程和触发器调试大法(转) – ct – 博客园已关闭评论
2019年6月20日 By mikel 分类: C#, Debug, 项目管理

来源: (1条消息)[已解决]:调用 LoadLibraryEx 失败,在 ISAPI 筛选器 “c:\Windows\Microsoft.NET\Framework\v4.0.30319\\aspnet_filter. – keenweiwei的专栏 – CSDN博客

在IIS上部署网站时遇到这样一个问题:“HTTP 错误 500.0 – Internal Server Error调用 LoadLibraryEx 失败,在 ISAPI 筛选器 “C:\Program Files (x86)\Sybase\PowerDynamo\win32\dyisa03.dll” 上”。

具体的问题展示如图:

 

通过网络,我发现部署网站时遇到此问题的有很多人,试了一个最简单的方法:修改对应IIS应用程序的应用程序池高级设置为:启用32位应用程序

想到之前部署网站时遇到excel导入数据库失败的问题,详见博客《

asp.net<Web版> —将excel表数据导入到数据库问题<一>—未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0” 提供程序

》。这两个问题的解决方法竟然是一样的,上次没有注意到启用32位应用程序带来的作用,这次仔细看了一下这项的说明!

 

(1条消息)[已解决]:调用 LoadLibraryEx 失败,在 ISAPI 筛选器 “c:\Windows\Microsoft.NET\Framework\v4.0.30319\\aspnet_filter. – keenweiwei的专栏 – CSDN博客已关闭评论
2019年6月15日 By mikel 分类: 数据库

来源: 大数据入门指南(GitHub开源项目) – heibaiying – 博客园

项目GitHub地址:https://github.com/heibaiying/BigData-Notes

✒️ 前 言

  1. 大数据技术栈思维导图
  2. 大数据常用软件安装指南

一、Hadoop

  1. 分布式文件存储系统——HDFS
  2. 分布式计算框架——MapReduce
  3. 集群资源管理器——YARN
  4. Hadoop单机伪集群环境搭建
  5. Hadoop集群环境搭建
  6. HDFS常用Shell命令
  7. HDFS Java API的使用
  8. 基于Zookeeper搭建Hadoop高可用集群

二、Hive

  1. Hive简介及核心概念
  2. Linux环境下Hive的安装部署
  3. Hive CLI和Beeline命令行的基本使用
  4. Hive 常用DDL操作
  5. Hive 分区表和分桶表
  6. Hive 视图和索引
  7. Hive常用DML操作
  8. Hive 数据查询详解

三、Spark

Spark Core :

  1. Spark简介
  2. Spark开发环境搭建
  3. 弹性式数据集RDD
  4. RDD常用算子详解
  5. Spark运行模式与作业提交
  6. Spark累加器与广播变量
  7. 基于Zookeeper搭建Spark高可用集群

Spark SQL :

  1. DateFrame 和 DataSet
  2. Structured API的基本使用
  3. Spark SQL外部数据源
  4. Spark SQL常用聚合函数
  5. Spark SQL JOIN 操作

Spark Streaming :

  1. Spark Streaming 简介
  2. Spark Streaming 基本操作
  3. Spark Streaming 整合 Flume
  4. Spark Streaming 整合 Kafka

四、Storm

  1. Storm和流处理简介
  2. Storm核心概念详解
  3. Storm单机环境搭建
  4. Storm集群环境搭建
  5. Storm编程模型详解
  6. Storm项目三种打包方式对比分析
  7. Storm集成Redis详解
  8. Storm集成HDFS/HBase
  9. Storm集成Kafka

TODO

六、HBase

  1. Hbase 简介
  2. HBase系统架构及数据结构
  3. HBase基本环境搭建(Standalone /pseudo-distributed mode)
  4. HBase集群环境搭建
  5. HBase常用Shell命令
  6. HBase Java API
  7. Hbase 过滤器详解
  8. HBase 协处理器详解
  9. HBase 容灾与备份
  10. HBase的SQL中间层——Phoenix
  11. Spring/Spring Boot 整合 Mybatis + Phoenix

七、Kafka

  1. Kafka 简介
  2. 基于Zookeeper搭建Kafka高可用集群
  3. Kafka 生产者详解
  4. Kafka 消费者详解
  5. 深入理解Kafka副本机制

八、Zookeeper

  1. Zookeeper 简介及核心概念
  2. Zookeeper单机环境和集群环境搭建
  3. Zookeeper常用Shell命令
  4. Zookeeper Java 客户端——Apache Curator
  5. Zookeeper ACL权限控制

九、Flume

  1. Flume简介及基本使用
  2. Linux环境下Flume的安装部署
  3. Flume整合Kafka

十、Sqoop

  1. Sqoop简介与安装
  2. Sqoop的基本使用

十一、Azkaban

  1. Azkaban简介
  2. Azkaban3.x 编译及部署
  3. Azkaban Flow 1.0 的使用
  4. Azkaban Flow 2.0 的使用

十二、Scala

  1. Scala简介及开发环境配置
  2. 基本数据类型和运算符
  3. 流程控制语句
  4. 数组——Array
  5. 集合类型综述
  6. 常用集合类型之——List & Set
  7. 常用集合类型之——Map & Tuple
  8. 类和对象
  9. 继承和特质
  10. 函数 & 闭包 & 柯里化
  11. 模式匹配
  12. 类型参数
  13. 隐式转换和隐式参数

十三、公共内容

  1. 大数据应用常用打包方式

📑 后 记

大数据入门指南(GitHub开源项目) – heibaiying – 博客园已关闭评论
2019年6月14日 By mikel 分类: C#, 架构设计

来源: abp(net core)+easyui+efcore仓储系统——ABP总体介绍(一) – DotNet菜园 – 博客园

     在前面我已经介绍了ASP.NET MVC、ASP.NET Razor、WEBAPI等技术。我准备通过一个实践项目来整体应用一下之前介绍的技术。本系列是介绍基于ABP+EasyUI的Web开发框架的形成过程,期间包括一些ABP的介绍,ASP.NET MVC Core技术、EasyUI技术、JQuery技术、WebAPI 技术,以及一些我对整体框架改造的基础性东西,力求更加稳定、通用、高效、简洁,最少的代码做最多的事情。我所使用的ABP版本是4.3,是2019年3月14日的版本。

一、ABP 的由来

“DRY——避免重复代码”是一个优秀的开发者在开发软件时所具备的最重要的思想之一。我们在开发企业WEB应用程序时都有一些类似的需求,例如:都需要登录页面、用户/角色管理、权限验证、数据有效性验证、多语言/本地化等等。一个高品质的大型软件都会运用一些最佳实践,例如分层体系结构、领域驱动设计、依赖注入等。我们也可能会采用ORM、数据库迁移(Database Migrations)、日志记录(Logging)等工具。

从零开始创建一个企业应用程序是一件繁琐的事,因为需要重复做很多常见的基础工作。许多公司都在开发自己的应用程序框架来重用于不同的项目,然后在框架的基础上开发一些新的功能。但并不是每个公司都有这样的实力。假如我们可以分享的更多,也许可以避免每个公司或每个项目的重复编写类似的代码。作者之所以把项目命名为“ASP.NET Boilerplate”,就是希望它能成为开发一般企业WEB应用的新起点,直接把ABP作为项目模板。

二、ABP是什么?

ABP是为新的现代Web应用程序使用最佳实践和使用最流行工具的一个起点。可作为一般用途的应用程序的基础框架或项目模板。它的功能包括:

服务器端:

  • 基于最新的.NET技术 (我使用的是ASP.NET Core MVC、Web API 2、C#
  • 实现领域驱动设计(实体、仓储、领域服务、领域事件、应用服务、数据传输对象,工作单元等等)
  • 实现分层体系结构(领域层,应用层,展现层和基础设施层)
  • 提供了一个基础架构来开发可重用可配置的模块
  • 集成一些最流行的开源框架/库,也许有些是你正在使用的。
  • 提供了一个基础架构让我们很方便地使用依赖注入
  • 提供Repository仓储模式支持不同的ORM(已实现Entity Framework 、NHibernate、MangoDb和内存数据库)
  • 支持并实现数据库迁移(EF 的 Code first)
  • 模块化开发(每个模块有独立的EF DbContext,可单独指定数据库)
  • 包括一个简单的和灵活的多语言/本地化系统
  • 包括一个 EventBus来实现服务器端全局的领域事件
  • 统一的异常处理(应用层几乎不需要处理自己写异常处理代码)
  • 数据有效性验证
  • 通过Application Services自动创建Web Api层
  • 提供基类和帮助类让我们方便地实现一些常见的任务
  • 使用“约定优于配置原则”

客户端:

  • Bootstrap、React、AngularJs、JQuery、Vue和其他JS库: JQuery.validate、jQuery.form、jQuery.blockUI、json2等
  • 为单页面应用程序(AngularJs、Vue 、React)和多页面应用程序(Bootstrap+jQuery)提供了项目模板。
  • 自动创建JavaScript 的代理层来更方便使用Web Api
  • 封装一些JavaScript 函数,更方便地使用ajax、消息框、通知组件、忙状态的遮罩层等等

 除ABP框架项目以外,还开发了名叫“Zero”的模块,实现了以下功能:

  • 身份验证与授权管理(通过ASP.NET Identity实现的)
  • 用户&角色管理
  • 系统设置存取管理(系统级、租户级、用户级,作用范围自动管理)
  • 审计日志(自动记录每一次接口的调用者和参数)

 

三、ABP不是什么?

ABP 提供了一个应用程序开发模型用于最佳实践。它拥有基础类、接口和工具使我们容易建立起可维护的大规模的应用程序。

它不是RAD工具之一,RAD工具的目的是无需编码创建应用程序。相反,ABP提供了一种编码的最佳实践。

它不是一个代码生成工具。在运行时虽然它有一些特性构建动态代码,但它不能生成代码。

它不是一个一体化的框架。相反,它使用流行的工具/库来完成特定的任务(例如用EF做ORM,用Log4Net做日志记录,使得Castle Windsor作为赖注入容器, AngularJs 用于SPA 框架)。

四、进入官网创建项目模板

  1. 在浏览器中输入https://aspnetboilerplate.com/Templates。然后依次按下图选择:
  2. 下载提示,如下图。

五、开发工具

Visual Studio 2017(以上)

SQL Server 2012  以上

六、启动项目

      1.使用Visual Studio  2017打开我们刚才在官网上创建的项目“ABP.TPLMS”,Visual Studio 2017会自动还原Nuget包,如下图。

      2. 设置“ABP.TPLMS.Web.Mvc”为启动项目,如下图。

      3.打开“appsettings.json”文件,修改连接字符串,如下图。(因为我本地装的SQLServer是实例是.\SQLexpress,所以需要手动修改server。)

      4. 在Visual Studio 2017中,选择“菜单>工具>NuGet包管理器>程序包管理器控制台”,打开程序包管理器控制台。 如下图。

      5.在程序包管理器控制台中的“默认项目”选择“ABP.TPLMS.EntityFrameworkCore”项目,并执行Update-Database,以创建数据库。如下图。

 

      6.在Visual Studio 2017中按F5运行应用程序,然后在浏览器中显示的登录页面中使用账号admin/123qwe,登陆即可。如下图。

      7.在正常登录之后,浏览器中显示如下图。

 

      8.默认是英文,可以选择其他语言。如下图1,图2。

 

图1

 

图2

abp(net core)+easyui+efcore仓储系统——ABP总体介绍(一) – DotNet菜园 – 博客园已关闭评论
2019年6月12日 By mikel 分类: 架构设计

来源: 小强开饭店-从单体应用到微服务 – detectiveHLH – 博客园

本篇博客通过小强开饭店的通俗易懂的故事,带你了解后端服务是如果从单体应用演变到微服务的。如果有说的不对的地方,欢迎各位大佬强势怼。

小强开饭店

有一天,小强为了早日奔赴小康生活,打算开一个饭店来帮他快速的实现这个目标。

饭店开业了

于是他盘下了一个店面,一顿装修之后,雇了一个厨师,便开业了。

饭店生意变好了

刚刚开业那段时间还好,店里的人虽然多,但是都还能应付的过来。

小强请的厨师手艺很好,再加上小强经营得当,宣传的也不错,慢慢的店里的生意越来越好。

慢慢的,顾客越来越多。很多时候厨师都忙不过来,大家只有排队在外面等着。渐渐的有些顾客变得十分不耐烦,等不下去了就走了,然后给了这家店差评。这种情况愈演愈烈,小强看到这不是个办法啊,得做点什么。

招聘厨师

小强下了血本,又另外聘请了几位厨艺很好的厨师。

有了这些厨师的加盟,虽然客人很多,饭店的经营也还是能够勉强的应付的来。口碑也慢慢的由差变好。随着口碑的变好,慕名而来的也随之越来越多。

生意火爆

随着顾客越来越多,即使厨房的厨师已经招聘满了,都还是应付不过来。

于是厨师也变成了暴躁的厨师。有的时候因为太忙了还罢工不干了。还得小强去苦口婆心的劝。小强心想这也不是个办法,再这么下去口碑又得下去。于是小强摇身一变,变成了强老板。

强老板开了分店

强老板拿着开饭店赚的钱,在城里的很多地方开了分店,十分的膨胀。这样一来,客人不用大老远的跑到那一家店去了,可以选择离自己近的店。很快,原来的那家生意也渐渐的恢复正常,各个分店的业绩也有所提高。

但是随着强老板的强势宣传,以及顾客之间的自传播,这个参考被越来越多的人知道了。但是由于顾客分散,每家店的火爆程度都不同。有的店甚至陷入了跟最开始的店一样的境地,大量的顾客排队。但是有的店的生意却又十分冷清。

强老板心想,这肯定不行啊,这样下去早晚得血亏。于是强老板摇身一变,变成了强总。

强总开了个顾客中心

所有想去餐馆用餐的顾客都来这里,由强老板统一安排的大巴再送至各个分店。每辆车轮流的送至每一家分店。这样一来,就不存在某一家分店生意十分火爆而另外的店生意惨淡的情况了。

强总已达成奔赴小康的目标

读后感

其实这个想法是很久以前不知道在哪儿看博客的时候,看到一位大佬的类比,确实是忘了。而最近刚好在准备分享,所以就打算详细的以图文和故事的方式来让没有了解过这方面的人快速的了解一下。

其实我也纠结过要不要将里面类比概念的解释穿插到故事里,但是后面想了一下,这样应该会干扰到大家对故事本身的理解,从而达不到通俗易懂的效果。所以我将解释单独放在了最后面。

单个饭店

最开始的单个饭店其实就是一个App或者一个网站,来给用户提供服务。可以理解为前端,或者客户端。

单个饭店的厨师

而单个饭店中的厨师,其实就是后端,提供数据,提供服务。一个厨师就对应着一个后端服务的实例。

随着App的访问量越来越大,最初的单体应用已经无法扛住这么大的压力了。导致其他的用户进入系统时,系统无法正常的服务。就跟我们现在打开一个网站一样,凡是超过2-3秒没有反应就直接宣告它的死刑了,直接退出-卸载二连。

单个饭店的多个厨师

多个厨师则是相应的后端服务启动了多个实例,每个实例都是完全一样的,只不过是运行在不同的机器上或者不同的端口上。

每次的请求由这些实例来均摊,这样也的确能够暂时解决访问量大的问题。但是维护起来十分的麻烦,部署的流程也很繁琐。每次部署你得更新所有的实例,万一数量多,又在不同的机器上,很有可能因为操作失误引发线上的事故。而且有可能让老版本的服务兼容新版的前端或者客户端,造成不必要的BUG。

再退一万步,就算所有的实例都在同一个服务器上,万一真的访问量到了一定的量级,你得维护多少个实例啊。人工成本巨大。而且一不小心,一觉起来,本身没有问题的服务,因为一晚上发生了事件引发了热点,导致你的应用访问量剧增,增到超过你的所有实例能够承受的极限,服务挂了。

再退一万万步,就算你自己维护没有烦死,前端的兄弟可能早就收拾你了。你没有做请求分发的话,所有的服务器地址得由前端去维护。

分店

这里的分店指微服务中的一个服务的多个实例。与之前人工维护的多个实例不同,这个是由工具帮我们维护。

这里我拿Docker Swarm举个例子。在Portainer中,你新建了一个服务之后可以选择设置Replicas,也就是实例的数量,当然默认是一个。你可以起10个,20个,但是这里得考虑到你的服务是否支持这样做。如果你的服务不是无状态应用,就很难做到可以自动的做横向扩展。

分店的生意火爆

其实也是一样的,即使有很多个实例,你如果不能控制请求打到哪个服务上的话,某些实例承受的压力大了一样的会挂。

强总的顾客中心

顾客中心大家可以理解为网关。更具体点可以理解为Zuul。

你的服务有了网关之后,所有的请求都从网关走。根据以及配置的路由,网关可以判断到你想具体到哪个服务去。

然后就会从自己的服务集群中找到对应的服务,获取到所有的服务实例的服务器IP以及端口。前面说到有可能请求会集中到某几个实例上。而我们可以使用工具来解决这个问题。例如,使用Spring Cloud的核心组件Ribbon。

这个组件的作用是做负载均衡,它可以使所有到某个服务的请求,平均的分发到该服务的每个实例上去。从而避免某几个服务的请求超过其能承受的阙值。当然,Ribbon需要和Spring Cloud的其他核心组件相互协作的。

另外一个版本的故事

小强搞了个新闻App,用Spring Boot搭了一个后端,找人用React Native写了个App,就这样上线了。因为其内容和推广都还不错,所以受到了用户的喜爱。

但是随着访问量越来越大,服务器渐渐扛不住压力。有的用户进App之后甚至要5-6秒才有反应,而且慢的出奇。于是小强开始给服务尽量的无状态化,然后在一个服务器上启动了几个实例。

一段时间之后,访问量又增大了。小强只好硬着头皮,继续加实例数量,你强任你强,加实例我在行。

有一天,小强一觉起来,发现服务炸了…啊不是,是挂了。因为发生了一些事情引发了巨大的社会舆论,App的访问量剧增。导致新加的实例也没能扛住。

就这样,小强老实的开始了重构。使用Spring Cloud搭建了一个微服务集群,把服务拆分之后,给每个服务启动了几个实例。同时使用Eureka和Feign来进行服务之间的通信,使用Ribbon来做负载均衡。

就这样,这个App暂时稳定了下来。不过还有很多事情可以继续去做。

参考:

往期文章:

相关:

  • 个人网站: Lunhao Hu
  • 微信公众号: SH的全栈笔记(或直接在添加公众号界面搜索微信号LunhaoHu)
小强开饭店-从单体应用到微服务 – detectiveHLH – 博客园已关闭评论
2019年6月12日 By mikel 分类: 项目管理

来源: 从搞笑到高效,构建敏捷团队的基础原则 – Worktile – 博客园

翁云峰 –稿定科技敏捷教练,厦门敏捷社区组织者

在印度有这么一个神奇的团队,他们有5000名左右的员工,每天要运送20多万份餐,一份盒饭要经过3-4个人的手才能抵达目的地,交通工具只有火车,自行车,板车和双腿,没有任何单据,甚至都不需要客户填写地址。

在这样的状况下,每6百万次运送中只有1次错误,准时正确到达率却超过99.99999%,这远超六西格玛的标准。在业界,如果一个企业能达到 六西格玛,就说明它能接近完美地达成顾客要求。在这一点上,达巴瓦拉甚至远远超过了联邦快递等使用现代技术和工具的快递公司。

 

屏幕快照 2019-06-11 上午9.40.08.png
 

大家可能在想,能够把事情做到这么好,他们一定很贵吧?他们团队的管理水平这么高,是不是成员的基础素质很高?

答案却不是如此,这个团队基本上都是半文盲或者文盲,每个月的收入也很低,平均每人400-500人民币。

这个神奇的团队,叫做达巴瓦拉。

 

屏幕快照 2019-06-11 上午10.15.53.png
 

大家有没有注意到,外卖的每一个饭盒上都有编号?没有英文单词或者太复杂的词,只有一串编号而已(因为他们很多人都是半文盲,所以编号信息也力求简单)。这些彩色代码告诉这些外卖小哥饭盒来自何处,输送过程中经过了哪些火车站,最终要投递到哪个建筑物的哪一个办公室。这个代码就是他们的通讯协议,可以保证饭盒并准确无误的送达。如果出错了,是谁出了错可以非常精准被定义到。

他们获得成功的法宝是时间管理,简单的色彩分类体系和团队协作。

我们很多的研发团队,文化程度都很高,我们能不能做到这样的准时交付率?很难。我们的团队可以在发生问题的时候,能不能非常精确的定位问题和处理?也很难。

虽然达巴瓦拉是属于另外一个行业的案例,相信也会对我们软件研发有重要的参考意义。我想通过这个案例的分析提出一个关于团队协作的观点,也是我今天想谈的东西。

1-团队协作的境界

现在我们来看一张图,大家试着想一想,我们团队目前经常沟通的频道是哪一个?

 

屏幕快照 2019-06-11 上午9.46.50.png
 

我们大部分的时候,都是在公开象限里进行协作。而公开象限的大小,反映了团队协作中的“信息披露”和协作水平。

假如我们都在一个团队里,一般大家都很乐意谈隐私象限,因为你需要把你知道的跟别人进行沟通,让他们配合你。你需要贡献一些秘密,一些私人的信息,让别人更加了解你。

当你不太清楚你自己的时候,比如你不知道有哪些东西需要改善,你需要请求反馈。你不知道你的代码写的如何,这时候有个人跟你说你的代码写得还不错,他是在给你反馈,接触你的潜能象限,这样的人是教练。

教练在鼓励你做自我揭示,你在不断请求教练给你反馈,让你知道你的潜能是什么。

 

屏幕快照 2019-06-11 上午9.48.42.png
 

喜欢天文学的人应该都知道“熵增”这个概念。举个例子,大家觉得你家是PPT左边的样子还是右边的样子?如果是左边,那就特别好。如果你是右边的状态,怎么办?你需要整理。

大家有没有意识到,你的团队也可能是右边的这种状态?出了问题不知道原因是什么,效率很低不知道怎么改进,流程无法预估,交付总是看天气。我们需要做的事情是什么?教练除了帮你揭示自我帮你反馈之外,还需要帮你做整理,把过去无序的东西变得有序。梳理流程,梳理团队,梳理产出,暴露问题并推动问题的解决,这个过程是“反熵增”,防止协作系统陷入到混乱和无序中。

增强沟通,反熵增之后,我们希望团队协作达到什么样的境界呢?

 

屏幕快照 2019-06-11 上午9.50.23.png
 

我想要用八个字来总结,叫做“既定规则,无脑执行”。

规则是什么?规则就是做事的方法和标准,比如DoR(就绪的标准), DoD(完成的标准)和很多的working agreement(团队一起制定的工作公约)。

为什么是无脑执行?这里不是真的说在执行的时候,我们只需要找到一堆idiot来按部就班执行就行了。这里的意思是,当我们有了协作的规则和方法的时候,根本不需要占用大脑的带宽,不需要让团队在执行过程中耗费宝贵的计算资源,把有限的精力投入到最需要全神贯注的工作事项中去。

无脑执行的另外一个意思是,事情必须非常流畅,减少在执行过程中的摩擦,减少无谓的人力物力投入。

“以神御刀,不以目视刀。”
《庄子》

为了让协作更加顺畅,我建议大家可以参考这个“协作金字塔”。也就是教练,或者团队管理者,或者有志于改善团队协作的任何一个人,需要关注的一些要点。

 

屏幕快照 2019-06-11 上午9.49.49.png
 

我们需要定义一些规则和方法。

 

屏幕快照 2019-06-11 上午9.51.00.png
 

我们需要不断提高信息饱和度(提高团队的公开象限)。

 

屏幕快照 2019-06-11 上午9.51.39.png
 

让信息流可视化(提高公开象限;无脑执行)

 

屏幕快照 2019-06-11 上午9.52.14.png
 

及时反馈,及时校准。

 

屏幕快照 2019-06-11 上午9.52.41.png
 

2-敏捷教练是什么

这是一个教练在分享会提到的,他说敏捷就是快速迭代,他分享的主题是《敏捷是骗人的》。

 

屏幕快照 2019-06-11 上午9.53.45.png
 

这个事情告诉我们什么?有一些说法认为敏捷是万能的,或者说敏捷可以做很多事情,但真的是这样吗?不一定。

 

屏幕快照 2019-06-11 上午9.54.11.png
 

上面我也提到了一些教练需要做的事情,比如需要不断扩大沟通视窗,制定规则,减少执行摩擦等,我再提出几个观点。

敏捷教练应该是好销售。我们卖什么?卖“概念”。如果你在团队推敏捷方法和敏捷流程,你可以参考以下的销售思路,会让你的整个过程更容易,大家不妨试试。

 

屏幕快照 2019-06-11 上午9.56.30.png
 

敏捷教练应该是防火队员,更侧重于做防火的事情,而不是做救火队员(在问题发生前,提前感知到,提前准备预案,最好提前解决掉。)

 

屏幕快照 2019-06-11 上午9.57.17.png
 

教练应该是算法工程师,为什么?概念只是概念,最终落地的效果好不好,是需要在真实环境下,根据实际情况来做“调参”,通过不同管理算法的引入,通过不同的实践和结果反馈,不断迭代优化的过程。

 

屏幕快照 2019-06-11 上午9.57.46.png
 

 

屏幕快照 2019-06-11 上午9.58.20.png
 

3-管理的算法

敏捷教练是算法工程师,那么,他应该负责什么样的算法?

 

屏幕快照 2019-06-11 上午9.59.51.png
 

比如我们应该要确保团队持续不断的做正确的事情,如何做?

我们可以把敏捷和精益创业、设计思维做链接,形成一套从问题发现,到问题的分解和试验,到敏捷交付用户价值的闭环。

比如我们有各种各样的模式。

包括瀑布流程,PMBOK流程。

 

屏幕快照 2019-06-11 上午10.02.44.png
 

敏捷流程,看板流程。

 

屏幕快照 2019-06-11 上午10.03.15.png
 

敏捷界的网红Scrum流程和精益流程。

 

屏幕快照 2019-06-11 上午10.03.38.png
 

这些都是管理的算法, 都是敏捷教练这个“算法工程师”的“算法库”,或者说“兵器谱”。必须非常熟悉,并且知道在什么样的场景下,该如何使用。

4-极简之道

 

屏幕快照 2019-06-11 上午10.06.54.png
 

我们听过很多道理,依然过不好这一生。

在这么多方法论的基础上,我们如何用于团队?我们如何帮到团队提升效能?

我们要让团队更加高效,而不是让团队搞笑。从搞笑到高效方法很多,比如在个人级别的GTD时间管理,清单方法,个人和团队级别的“番茄工作法”等,都是在你尝试敏捷方法前的有益尝试。在切入敏捷实践后,可以先从kanban方法开始,慢慢转移到scrum方法(如果适用的话),再根据实际情况,转换到SoS(Scrum of Scrum),LeSS,SAFe等大规模敏捷实践上。

在选择某一个具体方法实施之前,以下几个问题值得思考。

首先,我们为什么要提高效率?为什么效率重要,如果没有想清楚为什么,怎么做可能都不对。比如我们为什么要两周交付?如果产品本身的属性,支持边开发,边测试,测试通过后可以直接灰度上线,我们就不一定要选择两周的交付周期,比如可以保持在一周的周期来交付。如果团队的基础设施还没有准备好,比如单元测试,自动化测试,持续集成都还做不到,固定两周交付可能会是一个灾难。

其次,我们需要区分什么行为是高效,什么是低效,什么是无效。我们可以通过对整体流程进行分析(比如使用value stream mapping等方法,来统计流程效率),获得基础数据,制定效率提升的目标。

再次,区分清楚后,我们可以采取措施和策略,来放弃无效的事情,减少低效的部分,提高有效工作的占比。

最后这一点是区分于流程之外的,我们需要提升团队的“沟通带宽”,需要不断扩大团队的社交连接。比如一个小组可能互相都不太认识,或者在平常的工作里还没有形成很好的协作模式,在这样的情况下,应该着力于让团队更多的沟通,加深在项目级别,和在非正式形式的沟通和协作(比如团队建设等),让团队加快融合。这是你无论采用哪种方式方法,都应该考虑的基础的部分。

从搞笑到高效,构建敏捷团队的基础原则 – Worktile – 博客园已关闭评论
2019年6月11日 By mikel 分类: C#

来源: C#:使用MD5对用户密码加密与解密 – Healer007 – 博客园

C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式。本文总结了通用的算法并结合了自己的一点小经验,分享给大家。

一.使用16位、32位、64位MD5方法对用户名加密

1)16位的MD5加密

复制代码
/// <summary>
/// 16位MD5加密
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public static string MD5Encrypt16(string password)
{
    var md5 = new MD5CryptoServiceProvider();
    string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8);
    t2 = t2.Replace("-", "");
    return t2;
}
复制代码

2)32位的MD5加密

复制代码
/// <summary>
/// 32位MD5加密
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public static string MD5Encrypt32(string password)
{
    string cl = password;
    string pwd = "";
    MD5 md5 = MD5.Create(); //实例化一个md5对像
    // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
    byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
    // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
    for (int i = 0; i < s.Length; i++)
    {
        // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 
        pwd = pwd + s[i].ToString("X");
    }
    return pwd;
}
复制代码

3)64位的MD5加密

复制代码
public static string MD5Encrypt64(string password)
{
    string cl = password;
    //string pwd = "";
    MD5 md5 = MD5.Create(); //实例化一个md5对像
    // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 
    byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
    return Convert.ToBase64String(s);
}
复制代码

4)使用MD5为用户密码加密

复制代码
/// <summary>
/// 加密用户密码
/// </summary>
/// <param name="password">密码</param>
/// <param name="codeLength">加密位数</param>
/// <returns>加密密码</returns>
public static string md5(string password, int codeLength)
{
    if (!string.IsNullOrEmpty(password))
    {
        // 16位MD5加密(取32位加密的9~25字符)  
        if (codeLength == 16)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToLower().Substring(8, 16);
        }

        // 32位加密
        if (codeLength == 32)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToLower();
        }
    }
    return string.Empty;
}
复制代码

      由于MD5是不可逆的,所以加密之后就无法解密,取用户名和密码时候,需要再加密一边用户输入的数据与数据库中已加密的数据进行比对。如果比对结果一致,则可以判定登陆成功!代码如下所示:

复制代码
/// <summary>
/// 登陆
/// </summary>
public Model.UserInfo UserLogOn(string USERID, string pwd, out string statusCode)
{
    //假设已经通过用户ID获取到UserInfo的Model对象
    Model.UserInfo model = GetModel(USERID);
    if (model != null)
    {
        if (model.PASSWORD == MD5Encrypt64(pwd))
        {
            statusCode = "登陆成功";
        }
        else {
            statusCode = “密码错误”;
        }
    }
    else
    {
        statusCode = "用户不存在!";
        model = null;
    }   
    return model;
}
复制代码

5)通过DESCryptoServiceProvider对象对字符串进行加密解密

复制代码
/// <summary>
/// DES数据加密
/// </summary>
/// <param name="targetValue">目标值</param>
/// <param name="key">密钥</param>
/// <returns>加密值</returns>
public static string Encrypt(string targetValue, string key)
{
    if (string.IsNullOrEmpty(targetValue))
    {
        return string.Empty;
    }

    var returnValue = new StringBuilder();
    var des = new DESCryptoServiceProvider();
    byte[] inputByteArray = Encoding.Default.GetBytes(targetValue);
    // 通过两次哈希密码设置对称算法的初始化向量   
    des.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
                                            (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5").
                                                Substring(0, 8), "sha1").Substring(0, 8));
    // 通过两次哈希密码设置算法的机密密钥   
    des.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
                                            (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5")
                                                .Substring(0, 8), "md5").Substring(0, 8));
    var ms = new MemoryStream();
    var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
    cs.Write(inputByteArray, 0, inputByteArray.Length);
    cs.FlushFinalBlock();
    foreach (byte b in ms.ToArray())
    {
        returnValue.AppendFormat("{0:X2}", b);
    }
    return returnValue.ToString();
}
复制代码

此种算法可以通过加密密钥进行解密,解密方法如下:

复制代码
/// <summary>
/// DES数据解密
/// </summary>
/// <param name="targetValue"></param>
/// <param name="key"></param>
/// <returns></returns>
public static string Decrypt(string targetValue, string key)
{
    if (string.IsNullOrEmpty(targetValue))
    {
        return string.Empty;
    }
    // 定义DES加密对象
    var des = new DESCryptoServiceProvider();
    int len = targetValue.Length / 2;
    var inputByteArray = new byte[len];
    int x, i;
    for (x = 0; x < len; x++)
    {
        i = Convert.ToInt32(targetValue.Substring(x * 2, 2), 16);
        inputByteArray[x] = (byte)i;
    }
    // 通过两次哈希密码设置对称算法的初始化向量   
    des.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
                                            (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5").
                                                Substring(0, 8), "sha1").Substring(0, 8));
    // 通过两次哈希密码设置算法的机密密钥   
    des.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile
                                            (FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5")
                                                .Substring(0, 8), "md5").Substring(0, 8));
    // 定义内存流
    var ms = new MemoryStream();
    // 定义加密流
    var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
    cs.Write(inputByteArray, 0, inputByteArray.Length);
    cs.FlushFinalBlock();
    return Encoding.Default.GetString(ms.ToArray());
}
复制代码

说明:本文章系Healer007原创,署名:小萝卜!部分资料来自互联网,如需转载请注明出处!

C#:使用MD5对用户密码加密与解密 – Healer007 – 博客园已关闭评论
2019年6月11日 By mikel 分类: C#

来源: C#实现MD5加密 – 聖輝 – CSDN博客

方法一

首先,先简单介绍一下MD5

MD5的全称是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest开发出来, 经md2、md3和md4发展而来。

MD5具有很好的安全性(因为它具有不可逆的特征,加过密的密文经过解密后和加密前的东东相同的可能性极小)

引用
using System.Security.Cryptography;
using System.Text;

具体代码如下(写在按钮的Click事件里):
byte[] result = Encoding.Default.GetBytes(this.tbPass.Text.Trim());    //tbPass为输入密码的文本框
MD5 md5 = new MD5CryptoServiceProvider();
byte[] output = md5.ComputeHash(result);
this.tbMd5pass.Text = BitConverter.ToString(output).Replace(“-“,””);  //tbMd5pass为输出加密文本的文本框

方法二

C# md5加密(上)
string a; //加密前数据
string b; //加密后数据
b=System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(a,”MD5″)

using   System;
using   System.Security.Cryptography;

方法2

public   static   string   GetMD5(string   myString)
{
MD5   md5     =   new   MD5CryptoServiceProvider();
byte[]   fromData   =   System.Text.Encoding.Unicode.GetBytes(myString);
byte[]   targetData   =   md5.ComputeHash(fromData);
string   byte2String   =   null;

for   (int   i=0;   i<targetData.Length;   i++)
{
byte2String   +=   targetData[i].ToString(“x”);
}

return   byte2String;
}

using   System.Security.Cryptography;

///   <summary>
///   给一个字符串进行MD5加密
///   </summary>
///   <param   name=”strText”>待加密字符串</param>
///   <returns>加密后的字符串</returns>
public   static   string   MD5Encrypt(string   strText)
{
MD5   md5   =   new   MD5CryptoServiceProvider();
byte[]   result   =   md5.ComputeHash(System.Text.Encoding.Default.GetBytes(strText));
return   System.Text.Encoding.Default.GetString(result);
}

C# MD5加密
using System.Security.Cryptography;

private void btnOK_Click(object sender, System.EventArgs e)
{
string strConn = “server=192.168.0.51;database=chengheng;User id=sa; password=123″;
if(texName.Text.Trim()==””)
{
this.RegisterStartupScript(“sf”,”<script language=’JavaScript’>alert(‘用户名不能为空’);document.all(‘texName’).focus()</script>”);
return;
}
else if(texPassword.Text.Trim()==””)
{
this.RegisterStartupScript(“sfs”,”<script language=’JavaScript’>alert(‘密码不能为空’);document.all(‘texPassword’).focus()</script>”);
return;
}
else
{
//将获取的密码加密与数据库中加了密的密码相比较
byte[] by = md5.ComputeHash(utf.GetBytes(texPassword.Text.Trim()));
string resultPass = System.Text.UTF8Encoding.Unicode.GetString(by);
conn.ConnectionString=strConn;
SQLCommand comm = new SQLCommand();
string name = texName.Text.Trim().ToString();
comm.CommandText=”select Ruser_pwd,Ruser_nm from Ruser where Accountno = @name”;
comm.Parameters.Add(“@name”,SqlDbType.NVarChar,40);
comm.Parameters[“@name”].Value=name;
try
{
conn.Open();
comm.Connection=conn;
SqlDataReader dr=comm.ExecuteReader();
if(dr.Read())
{
//用户存在,对密码进行检查
if(dr.GetValue(0).Equals(resultPass))
{
string user_name=dr.GetValue(1).ToString();
string user_Accountno=texName.Text.Trim();
Session[“logon_name”]=user_name;
Session[“logon_Accountno”]=user_Accountno;
//登录成功,进行页面导向

}
else
{
this.RegisterStartupScript(“wp”,”<script language=’JavaScript’>alert(‘密码错误,请检查。’)</script>”);
}

}
else
{
this.RegisterStartupScript(“nu”,”<script language=javascript>alert(‘用户名不存在,请检查。’)</script>”);
}
}
catch(Exception exec)
{
this.RegisterStartupScript(“wc”,”<script language=javascript>alert(‘网络连接有异,请稍后重试。’)</script>”);
}
finally
{
conn.Close();
}
}
}

方法三
C# MD5加密

C#开发笔记   一、C# MD5-16位加密实例,32位加密实例(两种方法)

环境:vs.net2005/sql server2000/xp测试通过
1.MD5 16位加密实例
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace md5
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(UserMd5(“8”));
Console.WriteLine(GetMd5Str(“8″));
}
/**//// <summary>
/// MD5 16位加密 加密后密码为大写
/// </summary>
/// <param name=”ConvertString”></param>
/// <returns></returns>
public static string GetMd5Str(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace(“-“, “”);
return t2;
}

/**//// <summary>
/// MD5 16位加密 加密后密码为小写
/// </summary>
/// <param name=”ConvertString”></param>
/// <returns></returns>
public static string GetMd5Str(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace(“-“, “”);

t2 = t2.ToLower();

return t2;
}

/**//// <summary>
/// MD5 32位加密
/// </summary>
/// <param name=”str”></param>
/// <returns></returns>
static  string UserMd5(string str)
{
string cl = str;
string pwd = “”;
MD5 md5 = MD5.Create();//实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符

pwd = pwd + s[i].ToString(“X”);

}
return pwd;
}
}
}

using System.Security.Cryptography;
using System.Text;

public static string StringToMD5Hash(string inputString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] encryptedBytes = md5.ComputeHash(Encoding.ASCII.GetBytes(inputString));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < encryptedBytes.Length; i++)
{
sb.AppendFormat(“{0:x2}”, encryptedBytes[i]);
}
return sb.ToString();
}

 

 

 

二、首先在界面中引入:using System.Web.Security;

假设密码对话框名字password,对输入的密码加密后存入变量pwd中,语句如下:

string pwd = FormsAuthentication.HashPasswordForStoringInConfigFile(password.Text, “MD5″);

如果要录入则录入pwd,这样数据库实际的密码为202*****等乱码了。

如果登录查询则要:

select username,password from users where username='”+ UserName.Text +”‘ and password='”+ pwd +”‘

因为MD5不能解密,只能把原始密码加密后与数据库中加密的密码比较

 

三、C# MD5 加密方法 16位或32位

public string md5(string str,int code)
{
if(code==16) //16位MD5加密(取32位加密的9~25字符)
{
return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str,”MD5″).ToLower().Substring(8,16) ;
}
else//32位加密
{
return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str,”MD5”).ToLower();
}
}

 

 

四、做一个网站时,必然涉及用户登录,用户登录必然涉及密码,密码必然涉及安全,安全必然涉及加密。
加密现时最流行也是据说最安全的算法是MD5算法,MD5是一种不可逆的算法,也就是 明文经过加密后,根据加密过的密文无法还原出明文来。
目前有好多网站专搞MD5破密,百度上搜一下MD5就搜出一大堆了,今天早上无聊试了几个破密网站,6位以内纯数字密码的MD5密文可以还原出明文,长点的或带字符的就不行了。他们是采用穷举对比的,就是说把收录到的明文和密文放到数据库里,通过密文的对比来确定明文,毕竟收录的数据有限,所以破解的密码很有限。
扯远了,搞破密MD5需要大量的MONEY,因为要一个运算得超快的计算机和一个查找性能超好的数据库和超大的数据库收录。但搞加密就比较简单。以下是我用C#写的一个MD5加密的方法,用到.NET中的方法, 通过MD5_APP.StringToMD5(string str, int i)可以直接调用:

public class MD5_APP
{
public MD5_APP()
{

}

public static string StringToMD5(string str, int i)
{
//获取要加密的字段,并转化为Byte[]数组
byte[] data = System.Text.Encoding.Unicode.GetBytes(str.ToCharArray());
//建立加密服务
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
//加密Byte[]数组
byte[] result = md5.ComputeHash(data);
//将加密后的数组转化为字段
if (i == 16 && str != string.Empty)
{
return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, “MD5”).ToLower().Substring(8, 16);
}
else if (i == 32 && str != string.Empty)
{
return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, “MD5”).ToLower();
}
else
{
switch (i)
{
case 16: return “000000000000000”;
case 32: return “000000000000000000000000000000”;
default: return “请确保调用函数时第二个参数为16或32”;
}

}
}
———————
作者:shenghui188
来源:CSDN
原文:https://blog.csdn.net/shenghui188/article/details/5423959
版权声明:本文为博主原创文章,转载请附上博文链接!

C#实现MD5加密 – 聖輝 – CSDN博客已关闭评论
2019年6月11日 By mikel 分类: C#

来源: 类型初始值设定项引发异常 – 雪庭 – 博客园

类型初始值设定项引发异常

1 引子

今天早上,准备修改已前写的csharp程序,出现TypeInitializationException(类型初 始值设定项引发异常),这个以前没发现,挺奇怪,在网上找到了问题原因。

1.1 问题定位

问题出现在SQLite数据库操作,当打开数据库时,出现:

未处理的“System.TypeInitializationException”类型的异常出现在 TemperApplication.exe 中。
其他信息: “TemperApplication.DataWareHouse.SetupSqlite”的类型初始值设定项引发异常。

原来类的SQLite类静态成员在初始化时如果出现异常,访问类的其它静态成员或对该类进行 初始化都会抛出这个异常。SQLite代码:

  /// <summary>
  /// 访问sqlite数据库底层类
  /// </summary>
  public class SetupSqlite
  {
    /// <summary>
    /// 屏蔽默认构造函数
    /// </summary>
    private SetupSqlite()
    {
    }
...
    private static SQLiteConnection _sql_con = null;
    private static SQLiteCommand _sql_cmd = null;
    private static SQLiteDataReader _dr = null;
    private static SQLiteTransaction _trans = null; 
  }

那么一定是_sql_con,_sql_cmd,_dr,_trans,这四个静态变量初始化出现异常,我将这 四个静态变量的初始化去掉,如下:

  /// <summary>
  /// 访问sqlite数据库底层类
  /// </summary>
  public class SetupSqlite
  {
    /// <summary>
    /// 屏蔽默认构造函数
    /// </summary>
    private SetupSqlite()
    {
    }
...
    /*
    private static SQLiteConnection _sql_con = null;
    private static SQLiteCommand _sql_cmd = null;
    private static SQLiteDataReader _dr = null;
    private static SQLiteTransaction _trans = null; 
    */
    private static SQLiteConnection _sql_con;
    private static SQLiteCommand _sql_cmd;
    private static SQLiteDataReader _dr;
    private static SQLiteTransaction _trans; 
  }

重新运行,TypeInitializationException异常不出现了,但出现新异常:

未处理的“System.BadImageFormatException”类型的异常出现在 TemperApplication.exe 中。
其他信息: 未能加载文件或程序集“System.Data.SQLite, Version=1.0.66.0,
Culture=neutral, PublicKeyToken=db937bc2d44ff139”或它的某一个依赖项。试图加载格式
不正确的程序。

1.2 真正的原因

这说明,的确是四个静态变量的初始化有问题,问题原因出在sqlite.dll加载上,这个dll 以前加载都没有问题,问题一定出在别的地方,网上找到原因,是sqlite.dll分32位和 64位,以前用在32位下,现在开发换到win 7/x64下。

知道原因,修改就容易了,在项目属性中,修改目平台,从Any CPU改为x86,重新运行正 常,再将四个静态变量初始化恢复,运行也正常;明确问题,sqlite.dll是32位的,但目标 平台是x64的,有关sqlite的静态变量初始化异常,引起sqlite类初始化错误,引发 TypeInitializationException异常。

类型初始值设定项引发异常 – 雪庭 – 博客园已关闭评论
2019年6月11日 By mikel 分类: 数据库

来源: tempdb对SQL Server性能的影响 – changbluesky – 博客园

1.SQL Server系统数据库介绍

SQL Server有四个重要的系统级数据库:master,model,msdb,tempdb.

master:记录SQL Server系统的所有系统级信息,包括实例范围的元数据,端点,链接服务器和系统配置设置,还记录其他数据库是否存在以及这些数据问文件的位置等等.如果master不可用,数据库将不能启动.

model:用在SQL Server 实例上创建的所有数据库的模板。因为每次启动 SQL Server 时都会创建 tempdb,所以 model 数据库必须始终存在于 SQL Server 系统中。

msdb:由SQL Server 代理用来计划警报和作业。

tempdb:是连接到 SQL Server 实例的所有用户都可用的全局资源,它保存所有临时表,临时工作表,临时存储过程,临时存储大的类型,中间结果集,表变量和游标等。另外,它还用来满足所有其他临时存储要求.

 

2.tempdb内在运行原理

与其他SQL Server数据库不同的是,tempdb在SQL Server停掉,重启时会自动的drop,re-create. 根据model数据库会默认建立一个新的8MB(mdf file:8MB;ldf file:1MB, autogtouth设置为10%)大小recovery model为simple的tempdb数据库.

 

tempdb数据库建立之后,DBA可以在其他的数据库中建立数据对象,临时表,临时存储过程,表变量等会加到tempdb中.在tempdb活动很频繁时,能够自动的增长,因为是simple的recovery model,会最小化日志记录,日志也会不断的截断.

 

3.如何合理的优化tempdb以提高SQL Server的性能

如果SQL Server对tempdb访问不频繁,tempdb对数据库不会产生影响;相反如果访问很频繁,loading就会加重,tempdb的性能就会对整个DB产生重要的影响.优化tempdb的性能变的很重要的,尤其对于大型数据库.

注:在优化tempdb之前,请先考虑tempdb对SQL Server性能产生多大的影响,评估遇到的问题以及可行性.

3.1最小化的使用tempdb

SQL Server中很多的活动都活发生在tempdb中,所以在某种情况可以减少多对tempdb的过度使用,以提高SQL Server的整体性能.

如下有几处用到tempdb的地方:

(1)用户建立的临时表.如果能够避免不用,就尽量避免. 如果使用临时表储存大量的数据且频繁访问,考虑添加index以增加查询效率.

(2)Schedule jobs.如DBCC CHECKDB会占用系统较多的资源,较多的使用tempdb.最好在SQL Server loading比较轻的时候做.

(3)Cursors.游标会严重影响性能应当尽量避免使用.

(4)CTE(Common Table Expression).也会在tempdb中执行.

(5)SORT_INT_TEMPDB.建立index时会有此选项.

(6)Index online rebuild.

(7)临时工作表及中间结果集.如JOIN时产生的.

(8)排序的结果.

(9)AFTER and INSTEAD OF triggers.

不可能避免使用tempdb,如果有tempdb的瓶颈或issue,就该返回来考虑这些问题了.

3.2重新分配tempdb的空间大小

在SQL Server重启时会自动建立8MB大小的tempdb,自动增长默认为10%. 对于小型的数据库来说,8MB大小已经足够了.但是对于较大型的数据库来说,8MB远远不能满足SQL Server频繁活动的需要,因此会按照10%的比例增加,比如说需要1GB,则会需要较长的时间,此段时间会严重影响SQL Server的性能. 建议在SQL Server启动时设置tempdb的初始化的大小(如下图片设置为MDF:300MB,LDF:50MB),也可以通过ALTER DATABASE来实现. 这样在SQL Server在重启时tempdb就会有足够多的空间可利用,从而提高效率.

难点在于找到合理的初始化大小,在SQL Server活动频繁且tempdb不在增长时会是一个合适的值,可以设置此时的值为Initial Size;当然还会有更多的考量,此为一例.

3.3不要收缩tempdb(如没有必要)

有时候我们会注意到tempdb占用很大的空间,但是可用的空间会比较低时,会想到shrink数据库来释放磁盘空间, 此时要小心了,可能会影响到性能.

如上图所示:tempdb分配的空间为879.44MB,有45%的空间是空闲的,如果shrink掉,可以释放掉一部分磁盘空闲,但是之后SQL Server如有大量的操作时,tempdb空间不够用,又会按照10%的比例自动增长. 这样子的话,所做的shrink操作是无效的,还会增加系统的loading.

3.4 分派tempdb的文件和其他数据文件到不用的IO上

tempdb对IO的要求比较高,最好分配到高IO的磁盘上且与其他的数据文件分到不用的磁盘上,以提高读写效率.

tempdb也分成多个文件,一般会根据CPU来分,几个CPU就分几个tempdb的数据文件. 多个tempdb文件可以提高读写效率并且减少IO活动的冲突.

 

tempdb是SQL Server重要的一部分,以上只是对tempdb的一些了解总结,还需要进一步学习…

tempdb对SQL Server性能的影响 – changbluesky – 博客园已关闭评论
备案信息冀ICP 0007948