开发者社区> 杰克.陈> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

MSSQL连接字符串,你真的清楚吗?

简介: 原文:MSSQL连接字符串,你真的清楚吗?     几年前当我第一次面试时,考官发现我是个新手于是他让我写个连接字符串,虽然当时就知道X种连接字符串的写法,但是当时却没能写对一个,工作多年后我仍然不能写一个正确的连接字符串,但我知道打发新人时,让他写连接字符串是个不错的方法.
+关注继续查看
原文:MSSQL连接字符串,你真的清楚吗?


    几年前当我第一次面试时,考官发现我是个新手于是他让我写个连接字符串,虽然当时就知道X种连接字符串的写法,但是当时却没能写对一个,工作多年后我仍然不能写一个正确的连接字符串,但我知道打发新人时,让他写连接字符串是个不错的方法.

   以下是一个常用的ADO.NET 连接MSSQL的字符串
  "Data Source=.;Initial Catalog=MyDBA;Integrated Security=SSPI"
  在IIS 环境下 我们也许会这么写
  "Data Source=.;Initial Catalog=MyDBA;User Id=用户名;pwd=一般人我不告诉他;"
  
使用高效的协议(虽然我们一直这么做,但一直没注意)
  首先要搞清楚我们是使用什么方式与MSSQL数据库服务沟通的,当然微软产品的好处是即使你不知道,他也会帮你选择一个最合适的方式,在IIS跟MSSQL同台服务器的情况下,默认使用共享内存.
图1)
img_eac747731ed45d123f7017a4acdabe75.jpg
要确认ADO.Net建立的是什么方式的连接可以通过,企业管理器中->管理->进程信息
img_63efcda5417b81f5e07c711d5a68fc30.jpg
可以看到ADO.NET提供程序,.Net SqlClient data Provider
img_c121d0356a21cb436a5ae9f7dea2296f.jpg
使用LPC(本地调用,即共享内存)
img_6d2727d4d92fc655ad74c2aa0970a017.jpg
 如果你把上面的连接字符串改成"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI"
注意我的电脑上安装了多个SQL2000实例,其中一个为SQL2K ,使用上面的连接字符串打开一个连接后,再查看进程信息,发现LPC 现在变成了Tcp/IP(注意是.Net SqlClient Data provider对应的行)这个表明现在你启用了TCP/IP来连接数据库,
当然在IIS跟SQL同服务器的情况下建议你使用LPC,这样速度跟性能都比较优越.

在连接字符串中使用端口
一般异地连接时我们多使用tcp/ip协议,默认端口是1433,有时候你可能想改变这个端口,为此你需要使用"服务器网络实用工具"(在开始->Microsoft SQL Server下面),在里面配置Tcp/ip 协议并指定一个新的端口.
img_f70d3db601f398dfc25a38926252e58f.jpg
    这里指定了8888 为实例SQL2K的新端口,注意请不要将"隐藏服务器(H)"选择中,保存更改后就可以下面的连接字符串进行连接了"Data Source=127.0.0.1,8888;Initial Catalog=MyDBA;User ID=sa ",同样在进程信息里你能看到ADO.NET的一条用户名为sa的TCP/IP连接.但是当我们试图从远程连接这台SQL服务器时通常会出现问题,一般服务器上都有防火墙,而且只开放web,ftp,远程桌面等几个有限的端口,而你上面指定8888未在其列,因此当你在异地来连接数据库时会报错,(另外连接字符串如"Data Source=60.188.86.49,8888;Initial Catalog=MyDBA;User ID=sa;pwd=" ,中需要注意的是端口号跟IP或域名之间用逗号","隔开)为解决此问题你需要在防火墙中开放8888端口.
   完成后,你可以使用上面IP+端口的形式访问数据库了,不过你在使用以上连接字符串前,是否尝试过类似
"Data Source=www.wow52.cn\SQL2K;Initial Catalog=MyDBA;User ID=sa;pwd=;" 形式的连接字符串呢,这里采用域名加实例名的样子,可能你尝试了下发现行不通,反正我当时是这样做过但发现不行,虽然感觉这个形式很直观,但是怎么就不行呢?
   当然如果你细心的话,回过头去看上文有个"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI"
形式的连接字符串,这个是IP+实例的形式,本质上已经是域名+实例的形式了,那么为什么不行呢?问题同样是出在防火墙上面,不过这次你需要开放的是一个UDP端口1434以给运行SQL Server 解析协议 (SSRP)的服务使用,当你使用域名+实例名访问时,解析服务会解析成 IP+端口的形式进行数据库连接. 现在你通过企业管理器中的进程信息查看时,可以看到一个TCP/IP连接了,
SQL Server 解析协议 在SQL2005中被SQL Server Browser 取代,在需要进行远程连接,并且采用域名或IP+实例名的形式时,你需要启动这个服务,并且在防火墙中开放相应端口. 最后关于端口部分,还有一点是SQL2000,跟SQL2005多支持动态端口,也就是把端口设置为0(SQL2005 具体参考配置工具),这个时候为使数据库能在异地正确访问,你需要在防火墙中以添加程序的形式把sqlserver.exe添加进去,如实例SQL2k的程序位置是
D:\Program Files\Microsoft SQL Server\MSSQL$SQL2K\Binn\sqlservr.exe,具体取决于你的安装位置,SQL2005可以在服务器网络配置工具里查看. 除了需要添加sqlserver.exe程序外,你还需要开放1434 UDP端口,或者在使用SQL2005时把C:\Program Files\Microsoft SQL Server\90\Shared\sqlbrowser.exe 添加到防火墙里, sqlbrowser.exe 使用的也是1434 UDP端口.

以上所讲述在我的MSSQL2000里都不行!
  

   如果你不幸遇到这样的情况,最重要的一点是查看你sql的版本,请在查询分析器里运行 Select @@Version,或者看帮助菜单中的"关于..." 如果版本不是8.00.2039(现在说的是SQL2000),那么赶紧升级把,下个SQLSP4来打上.
如果打上补丁还无济于事,那么请确定你在SQL Server网络实用工具中启用了TPC/IP协议,并在防火墙中开放了相关端口.

连接字符串中的一些属性
 
  Connection lifetime 连接生存时间,默认为0,表示无限长,单位为秒.在SQL集群环境中我们才设置为具体的数值.

  Connection timeout 连接生成时间,默认为15秒,通俗的讲当你conn.Open等15秒后还没连接成功,那么就会抛出一个连接超时的错误,这也是为什么其他错误来的那么突然,而数据库连接超时错误,非要你等15秒的原因了.

  Pooling 是否使用连接池, 默认是起用的,使用Pooling=false来禁止.

  Min Pool Size,Max Pool Size 默认情况下最小是0,最大是100.

  关于pooling属性在上面所有的连接字符串中多是默认开启的,连接池能有效的提高数据库访问性能,因为创建一个连接需要消耗很多资源,尤其是进行异地访问时(一般指局域网,最好不要进行跨internet的数据库访问)更加如此,因此你在多数情况下不需要显式的禁止(也许你没在意微软一直帮你开通着), 事实上在你使用 conn.open() ,conn.close() 多少数情况下不是真的打开一个连接,而是向连接池中取一条可用连接,跟归还一条连接,conn.open操作只有在池中没有可用连接时才会创建一条连接,当然如果池中可用接数目达到Max Pool Size时,他将不再创建新的连接,而是等待一条可用连接的到来,这个时间是Connection timeout. 当然你的conn.Open操作涉及的连接池,取决于你的连接字符串,比如:
"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI"


"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI
;" ,注意后面多了";"
会开启两个独立的连接池,ADO.NET 判断字符串是否相同的依据是对字符串进行2进制的比较,所以任何变动(空格,大小写)都会被判断为不同的连接字符串.
有如下代码
-----------------------------------
string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI
;";
for(int i=0;i<10;i++){
  SqlConnection conn=new SqlConnection(strConn);
  conn.Open();
  conn.Close()
}

string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI
;";
for(int i=0;i<10;i++){
  strConn +=" "; //空格
  SqlConnection conn=new SqlConnection(strConn);
  conn.Open();
  conn.Close()
}
两段代码分别运行,看企业管理器->管理->进程信息(请刷新先) ,可以看到前面的只启用了一个进程,而后面的则启用了10个进程,每个进程对应一条连接.前一段代码10个open +close()操作使用的是同一个连接池中的同一个连接,而后一个则开启了10个连接池,每个连接池中有一个连接.

再看下面的代码
            for (int i = 0; i <= 10; i++)
            {
                Thread t = new Thread(new ThreadStart(Command));
                t.Start();
            }
---------------------
//Command定义
private void Command(){
string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI
;";
  Sqlconnection conn=new SqlConnection(strConn);
 SqlCommand cmd=new SqlCommand("一个运行比较长的查询",conn);
  conn.Open();
  cmd.ExecuteNonQuery();
  
  conn.Close()
}
  运行后可以看,企业管理器->管理->进程信息里会开启10个到MyDBA数据库的连接进程,但是需要注意的是,这10个进程是属于同个连接池的,为了证明这一点你可以将上面的连接字符串改为
 private void command(){
string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI
;Max pool Size=5;"; //加了Max Pool Size=5;
  SqlConnection conn=new SqlConnection(strConn);
 SqlCommand cmd=new SqlCommand("一个运行比较长的查询",conn);
  conn.Open();
  cmd.ExecuteNonQuery();
  
  conn.Close()
}
结果可以看到他只开启了5个到MyDBA数据库的连接,这证明他们是同个连接池的.当然这里能成功演示的前提是,cmd执行的任务时间要在15秒内,不然会出现后5个线程连接超时,另外使用SQL2000 的跟踪工具(SQL2005中是,SQL Server Profiler)是你观察以上实验的一个绝好的工具!

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
数据库连接字符串
SQLServer 连接字符串 MySql 连接字符串 Data Source=127.0.0.1;Database=DBName;User Id=root;Password=root;
1132 0
MySQL数据库远程连接创建用户权限等
MySQL数据库远程连接创建用户权限等 一. 创建用户 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明: username:你将创建的用户名 host:指定该用户在哪个主机上可以登陆,如果是本地用户可用localh.
2493 0
mysql之字符编码问题
问题描述:新建数据库并新建表插入数据,中文乱码问题,即便将字符集通过命令行或者mysql客户端改为utf-8还是乱码。 问题原因:此问题目前主要出现在Linux为centos7安装mysql上,主要是通过源码编译安装mysql。
861 0
第39天:字符串连接、截取操作
一、网址编码encodeURIComponent() 函数可把字符串作为 URI 组件进行编码decodeURIComponent() 函数可把字符串作为 URI 组件进行解码var url = "http://www.
719 0
保护连接字符串
保护连接字符串 摘自MSDN保护对数据源的访问是安全应用程序最重要的目标之一。为了帮助限制对数据源的访问,必须保护连接信息(例如用户标识、密码和数据源名称)的连接信息。以纯文本形式存储用户标识和密码(例如在源代码中)会造成严重的安全问题。
791 0
+关注
杰克.陈
一个安静的程序猿~
文章
问答
文章排行榜
最热
最新
相关电子书
更多
SQL Server 2017
立即下载
PostgresChina2018_董红禹_SQL_Server迁移PG经验分享
立即下载
SQL Server在电子商务中的应用与实践
立即下载