手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:优化

mssql和mysql区别

偶尔看到这篇文章,觉得转下来也挺不错。毕竟现在mssql用的人也挺多,不是吗?
数据库迁移问题也可以多注意一下。。

原文地址:
内容如下:http://www.cnblogs.com/perfectdesign/archive/2009/05/22/mssql2mysql.html

最近在做mssql转换成mysql的工作,总结了点经验,跟大家分享一下。

同时这些也会在不断更新。也希望大家补充。

 

1 mysql支持enum,set类型,sql server不支持

2 mysql不支持nchar,nvarchar,ntext类型

3 mysql的递增语句是AUTO_INCREMENT,而mssqlidentity(1,1)

4 msms默认到处表创建语句的默认值表示是((0)),而在mysql里面是不允许带两括号的

5 mysql需要为表指定存储类型

6 mssql识别符是[],[type]表示他区别于关键字,但是mysql却是 `,也就是按键1左边的那个符号

7 mssql支持getdate()方法获取当前时间日期,但是mysql里面可以分日期类型和时间类型,获取当前日期是cur_date(),当前完整时间是 now()函数

8 mssql不支持replace into 语句,但是在最新的sql20008里面,也支持merge语法

9 mysql支持insert into table1 set t1 = ‘’, t2 = ‘’ ,但是mssql不支持这样写

10 mysql支持insert into tabl1 values (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,1)

11 mssql不支持limit语句,是非常遗憾的,只能用top 取代limt 0,Nrow_number() over()函数取代limit N,M

12 mysql在创建表时要为每个表指定一个存储引擎类型,而mssql只支持一种存储引擎

13 mysql不支持默认值为当前时间的datetime类型(mssql很容易做到),在mysql里面是用timestamp类型

14 mssql里面检查是否有这个表再删除,需要这样:

if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'uc_newpm')   and   OBJECTPROPERTY(id,   N'IsUserTable')   =   1) 

但是在mysql里面只需要 DROP TABLE IF EXISTS cdb_forums;

15 mysql支持无符号型的整数,那么比不支持无符号型的mssql就能多出一倍的最大数存储

16 mysql不支持在mssql里面使用非常方便的varchar(max)类型,这个类型在mssql里面既可做一般数据存储,也可以做blob数据存储

17 mysql创建非聚集索引只需要在创建表的时候指定为key就行,比如:KEY displayorder (fid,displayorder) mssql里面必须要:create unique nonclustered index index_uc_protectedmembers_username_appid on dbo.uc_protectedmembers

(username asc,appid asc)


18 mysql text字段类型不允许有默认值

19mysql的一个表的总共字段长度不超过65XXX

20一个很表面的区别就是mysql的安装特别简单,而且文件大小才110M(非安装版),相比微软这个庞然大物,安装进度来说简直就是.....

21mysql的管理工具有几个比较好的,mysql_front,和官方那个套件,不过都没有SSMS的使用方便,这是mysql很大的一个缺点。

22mysql的存储过程只是出现在最新的版本中,稳定性和性能可能不如mssql。

23 同样的负载压力,mysql要消耗更少的CPU和内存,mssql的确是很耗资源。

24php连接mysql和mssql的方式都差不多,只需要将函数的mysql替换成mssql即可。

25mysql支持date,time,year类型,mssql到2008才支持date和time。

Tags: mssql, mysql

Anders将重返Delphi舞台?

新闻来源:Microsoft Member
作为Delphi和C#架构的先驱,Anders Hejlsberg已在这两种语言上活跃了很久,而Anders应邀加入微软后,似乎Delphi多年来一直没有什么起色,处于相当被动的地位。现在,是Anders回归Delphi怀抱的时候了吗?据微软内部员工的透露,Delphi和C#的架构者Anders Hejlsberg将于下个月重拾Delphi,继续为Delphi的发展起到领头羊的作用。

而许多人所关心的,Anders回去做什么,至今还没有一个可靠的答复。

据称,当初Anders离开Borland,是因为与高层的思想不合拍,引起了冲突后,Anders一怒而去。而现在,是不是他又与微软的高层擦出了火。 在Delphi被Embarcadero(中文名称英巴卡迪诺公司)收购后,一年来有了比较大的起色,Anders或许是想借这个契机重回Delphi的 战线。

希望Anders能为Delphi,为Embarcadero旗下的CodeGear带来一个新的生命,这也是为无数的Delphi/Pascal爱好者带来第二次生命。

Tags: delphi

jQuery简单开发

jQuery这种轻量级的框架大家使用的都比较多,1.3后效率据说又上升了不少,因此,开发基于jQuery的插件也就显得那么理所当然了。
一般来说,jQuery有两种插件模式,一种是:$.extends({}) ,另一种是:$.fn.extends({})
个人理解:前一种是属于全局性的调用,后一种是针对某个元件的绑定调用。这当然是简单的理解。但事实上,也基本上就是这么做的。

官方的例子也比较简单:

JavaScript代码
  1. $.extend({  
  2.     max: function(a, b) {  
  3.         return a > b ? a : b;  
  4.     },  
  5.     min: function(a, b) {  
  6.         return a > b ? b : a;  
  7.     },  
  8.     avg: function(a, b) {  
  9.         return a / b;  
  10.     }  
  11. });  

看上去是不是容易?然后就可以直接调用了。 $.min(2,3) 返回2
一般情况下,为了在扩展中使用$,却又担心的页面使用了jQuery.noConflict()而取消了$指向jQuery的引用,则需要这样写

JavaScript代码
  1. function($){  
  2.     $.fn.extend({  
  3.         //....code in here  
  4.     });  
  5. })(jQuery);  

这样写不仅能够将$显式指向jQuery,而且将产生的变量封在function的作用范围内,不会污染window全局。
而基于$.fn.extends({})的扩展又如何开发呢?

在这里我引用Roby的译文:http://www.robysky.com/archives/171
英文原文:http://www.learningjquery.com/2007/10/a-plugin-development-pattern

我认为以下插件开发模式是必须应该掌握的:
1.在JQuery命名空间内声明一个特定的命名;
2.接收参数来控制插件的行为;
3.提供公有方法访问插件的配置项值;
4.提供公有方法来访问插件中其他的方法(如果可能的话);
5.保证私有方法是私有的;
6.支持元数据插件;

下面,我将逐一讲述上面的内容,并在同时给出相关的简单插件开发代码。
1.在JQuery命名空间内声明一个特定的命名

这意味着开发的是一个单一命名的插件脚本,如果你的脚本包含多个插件或者有补充性质的插件,比如$.fn.doSomething() 和$.fn.undoSomething(),那你得声明多个命名了。但是总体来说,当开发一个插件时,我们应该努力做到用一个单一的命名来搞定整个插件。

在例子中,我们将声明一个名为“hilight”的插件。

JavaScript代码
  1. $.fn.hilight = function() {  
  2.     // Our plugin implementation code goes here.  
  3. };   

我们可以这样调用:
$(’#myDiv’).hilight();
但是假如我们需要打破这种单一的命名和调用方式呢?有很多理由支持我们这么做:设计上的需要;更加简单和可读的配置;而且那样将更加符合OO的要求。

在没有给命名空间来到麻烦的前提下,将插件的部署打破成为多个函数的形式将是十分繁琐的。我们通过认识并利用JavaScript中 functions是最高层的对象,和其他对象一样,functions可以被赋予属性,前面我们已经将hilight命名声明在了JQuery的原型对象上,那么,其实,其他的我们想扩展的属性或对象都能够在hilight上进行声明。稍后将详细讲述此点。
2.接收参数来控制插件的行为;

来为我们的hilight插件添加指定前景和背景色的功能,我们需要在函数中允许一个object类型的选项设置。如下所展示的那样:

JavaScript代码
  1. $.fn.hilight = function(options) {  
  2.  var defaults = {  
  3.     foreground: 'red',  
  4.     background: 'yellow'  
  5.   };  
  6.   // Extend our default options with those provided.  
  7.   var opts = $.extend(defaults, options);  
  8.   // Our plugin implementation code goes here.  
  9. };  

现在,我们的插件可以这样来调用:

$(’#myDiv’).hilight({
  foreground: ‘blue’
});
3.提供公有方法访问插件的配置项值;

上面的代码我们可以做一下改进,使得插件的默认值可以在插件之外被设置。这无疑是十分重要的,因为它使得插件用户可以使用最少的代码来修改插件配置,这其实是我们利用函数对象的开始。

JavaScript代码
  1. // plugin definition  
  2. $.fn.hilight = function(options) {  
  3.   // Extend our default options with those provided.  
  4.   // Note that the first arg to extend is an empty object -  
  5.   // this is to keep from overriding our "defaults" object.  
  6.   var opts = $.extend({}, $.fn.hilight.defaults, options);  
  7.   // Our plugin implementation code goes here.  
  8. };  
  9.    
  10. // plugin defaults - added as a property on our plugin function  
  11. $.fn.hilight.defaults = {  
  12.   foreground: 'red',  
  13.   background: 'yellow'  
  14. };  

 4.提供公有方法来访问插件中其他的方法(如果可能的话)

这里要讲的方法和前面的讲解一脉相承,用此方法来扩展你的插件(而且能够让其他人进行扩展)是件很有意思的事情。例如,在扩展hilight插件时,我们可以定义一个format方法用来格式化高亮显示的文本,原来的hilight插件和扩展了format方法的插件代码如下:

JavaScript代码
  1. $.fn.hilight = function(options) {  
  2. // iterate and reformat each matched element  
  3. return this.each(function() {  
  4. var $this = $(this);  
  5. ...  
  6. var markup = $this.html();  
  7. // call our format function  
  8. markup = $.fn.hilight.format(markup);  
  9. $this.html(markup);  
  10. });  
  11. };  
  12.    
  13. // define our format function  
  14. $.fn.hilight.format = function(txt) {' 
  15. return '<strong>' + txt + '</strong>';  
  16. };  

如前面所述,我们已经很容易的通过设置options对象的属性来允许一个回调函数来覆写默认的格式设置。在这里有另外一个非常棒的方法来个性化你的插件,上面展示的方法实际上就是通过暴露format方法,使其可以被重新定义。这种做法使得其他人可以采用他们自己的习惯和方式来重写你的插件,这意味着他们可以为你的插件写额外的扩展插件。
仔细考量一下前面我们用到的插件例子程序,你可能会想“我们究竟应该在什么时候使用这种插件方式来实现需求”的问题。一个来自现实应用中的插件便是“ Cycle Plugin”,它是一个支持多种滑动显示特效的插件,特效包括滚动、滑动和渐变等等。但是,实际上,并没有办法来定义每一个可能会用在滑动变幻上的特效。这就是这种扩展方式的有用之处。“ Cycle Plugin”插件暴露了”transitions”对象,这使得用户只需要按照如下方式便可以添加自己的变幻定义:
$.fn.cycle.transitions = {

};
这种技巧使得用户可以定义或者采用自己习惯的方式来扩展“ Cycle Plugin”。
5.保证私有方法是私有的;

上面提到的暴露插件中的公有方法的技巧使得插件能够被覆写,这将使插件变得十分灵活而强大,但至于哪一部分,那些属性和方法应该被暴露出来,你得小心了。一旦使其能够被外界访问到,你就得注意到任何调用参数和语义化的变动都可能使其丧失向前的兼容性。作为一般准则,如果不确定是否应该暴露某个属性或对象的话,那就最好别那样做。
那么我们应该怎样来定义多个方法而不至于使命名空间混乱并且保证不被暴露再外呢?这就是闭包的工作,为了便于演示,我们给插件加入了一个叫做 “debug”的功能,它用来记录firebug控制台所选择的网页元素数目。为了创建一个闭包,我们将整个功能的定义放入在一个function中了(有关这方面的知识,可参见JQuery手册)。

JavaScript代码
  1. // create closure  
  2. (function($) {  
  3.     // plugin definition  
  4.     $.fn.hilight = function(options) {  
  5.         debug(this);  
  6.         ...  
  7.     };  
  8.     // private function for debugging  
  9.     function debug($obj) {  
  10.         if (window.console && window.console.log)  
  11.         window.console.log('hilight selection count: ' + $obj.size());  
  12.     };  
  13.     ...  
  14.     // end of closure  
  15. })(jQuery);  

debug方法在这里是无法被在插件以外访问到的,因此,我们称之为它是插件私有的。
6.支持元数据插件;

根据你所写的插件的类型,为你的插件加入元数据插件的支持将使其变得更强大。就我个人来说,喜欢采用元数据插件的重要原因便是它可以让你使用定义之外的标签来覆写你的插件属性设置(这在创建demo和例子时十分有用),而且支持它十分的简单。
更新:这部分内容可以在本文的评论中展开讨论(既然有争议的话)

JavaScript代码
  1. // plugin definition  
  2. $.fn.hilight = function(options) {  
  3.  ...  
  4.  // build main options before element iteration  
  5.  var opts = $.extend({}, $.fn.hilight.defaults, options);  
  6.  return this.each(function() {  
  7.  var $this = $(this);  
  8.  // build element specific options  
  9.  var o = $.meta ? $.extend({}, opts, $this.data()) : opts;  
  10. ...  

改动部分的代码会做如下的事情:
*测试metadata插件是否可用
*如果可以,将用metadata扩展options对象
这被加入到jQuery.extend,作为其最后一个参数,所以它可以覆写任何其他参数设置。现在我们可以通过下面的方式控制其行为:

XML/HTML代码
  1. <!--  markup  -->  
  2. <div class="hilight { background: 'red', foreground: 'white' }">Have a nice day!</div>  
  3. <div class="hilight { foreground: 'orange' }">Have a nice day!</div>  
  4. <div class="hilight { background: 'green' }">Have a nice day!</div>  

而在调用方面,我们通过一行简单的代码就可以实现预期的效果:
$(’.hilight’).hilight();

将上面所述内容涉及到的代码放在一起,完整的例子程序代码如下:

JavaScript代码
  1. //  
  2. // create closure  
  3. //  
  4. (function($) {  
  5.     //  
  6.     // plugin definition  
  7.     //  
  8.     $.fn.hilight = function(options) {  
  9.         debug(this);  
  10.         // build main options before element iteration  
  11.         var opts = $.extend({}, $.fn.hilight.defaults, options);  
  12.         // iterate and reformat each matched element  
  13.         return this.each(function() {  
  14.             $this = $(this);  
  15.             // build element specific options  
  16.             var o = $.meta ? $.extend({}, opts, $this.data()) : opts;  
  17.             // update element styles  
  18.             $this.css({  
  19.                 backgroundColor: o.background,  
  20.                 color: o.foreground  
  21.             });  
  22.             var markup = $this.html();  
  23.             // call our format function  
  24.             markup = $.fn.hilight.format(markup);  
  25.             $this.html(markup);  
  26.         });  
  27.     };  
  28.     //  
  29.     // private function for debugging  
  30.     //  
  31.     function debug($obj) {  
  32.         if (window.console && window.console.log)  
  33.         window.console.log('hilight selection count: ' + $obj.size());  
  34.     };  
  35.     //  
  36.     // define and expose our format function  
  37.     //  
  38.     $.fn.hilight.format = function(txt) {  
  39.         return '<strong>' + txt + '</strong>';  
  40.     };  
  41.     //  
  42.     // plugin defaults  
  43.     //  
  44.     $.fn.hilight.defaults = {  
  45.         foreground: 'red',  
  46.         background: 'yellow'  
  47.     };  
  48.     //  
  49.     // end of closure  
  50.     //  
  51. })(jQuery);  

看完以上的内容,你是不是对jQuery的插件开发加深了一定的了解了呢?
顺便提一下,yhustc在自己的博客上写了一个基于jQuery的软键盘插件,你是不是又可以根据上面的教程来写一个基于$.fn.extends的扩展呢?让yhustc的插件可以绑定在某个元件上?

Tags: jquery, 开发, 插件, yhustc

老王:单例模式是邪恶的么

老王的看法,不过,事实上就是这样,现在很多开发人员还是很少在运行时候把对象作为参数传给某个方法或者class

原文:http://hi.baidu.com/thinkinginlamp/blog/item/ea586b63472627680c33fa38.html

正文:

写在前面的话:PHP每次运行重建环境,这样的运行方式本身就决定了PHP没有传统意义上的单例。

单例模式(singleton)也被叫做单件模式。使用它的目的是为了确保某个类只有一个实例。因为它的实现方式很简单,所以多数模式书籍都把单例模式作 为入门模式来介绍,可以说对很多模式爱好者来说,单例模式是他们最熟悉的设计模式。可惜这间接造成了单例模式使用的泛滥,以至于到了无所不在的地步,比如 说,ZendFramework里连前端控制器都是单例的。那么,单例模式是邪恶的么?

下面看一个实际编程时很多人愿意采用的单例模式例子:

注意:正常的单例模式应该设置一个私有化的__construct,但是出于下文的需要,我省略的它,至于限制__clone的行为,因为我嫌它占地方, 所以也没写,这两点你自己注意一下就好了,和文本讨论的问题关系不大。完整的例子可以参考:http://www.php.net/manual/en /language.oop5.patterns.php。

class Database
{
    private static $instance;

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            $class = __CLASS__;
            self::$instance = new $class;
        }

        return self::$instance;
    }
}


如此的单例模式通常是这样调用的:

class Article
{
    private $dasebase;

    public function __construct()
    {
        $this->database = Database::getInstance();
    }
}

$article = new Article();


下面我们就来讨论一下这样使用单例模式好还是不好。

文章在构造函数内通过单例模式的方式得到数据库实例,这看起来很正常,但是对于文章这样的领域概念来说,数据库实例属于纯粹的技术实现手段,明显属于外来 物,应该尽可能隔离才对,这样才符合单一原则,在测试驱动开发的领域,这被称作MOCK,但是在上例中,由于我们是在构造函数里通过单例模式静态方法调用 得到的数据库对象,这就造成了没有办法从外部替换掉这个数据库对象。

为了克服这样的问题,按照如下的方式获取数据实例更好一些:

class Article
{
    private $dasebase;

    public function __construct($database)
    {
        $this->database = $database;
    }
}

$database = Database::getInstance();
$article = new Article($database);


一旦我们把数据库实例化的过程放到了外面,便可以随意替换掉其具体的实现方式,这很棒,特别是在测试的时候很有用,因为数据库环境是一个很大的不安定因 素,替换掉它有助于让测试用例更高效的运行。你甚至可以把程序搞得再智能化一点,一切外部对象依赖都通过容器注入的方式挂接。

此时再看看上面代码里的$database = Database::getInstance($database);突然又感觉有点莫名其妙,因为实在看不到在这里使用单例模式有什么额外的好处,直接按照最平常的实例化方式并没有什么不妥:

$database = new Database();
$article = new Article($database);

外部数据库对象通过构造函数的方式注入到文章里,保存在$this->database属性中,至于文章级联的评论 ($article->comments)也需要数据库实例这样的情况,可以在实例化评论的时候把文章的$this->database属性 通过评论构造函数注入的方式传递过去,当然,还有其它的方法,总而言之,你不再需要一个单例模式的数据库实例。

再回到单例模式的本意上:为了确保某个类只有一个实例。比如说公司只有一个CEO(如果有一个公司有多个CEO,那么这个公司必然会犯很多逻辑错误)。但 是反思现在很多人对单例模式的使用,往往并没有按照单例模式的本意来使用,拿上面的数据库例子来说,如果文章有一个数据库实例,评论有另一个数据库实例。 这有什么逻辑问题么?答案是没有。既然不必确保数据库只有一个实例,那么在这里使用单例模式的动机本身就值得推敲。当然,有人会说文章和评论使用不同的数 据库实例本身就低效。但如果仅仅是出于效率的考虑来使用单例模式,那么本质上不符合单例模式的定义,更何况即便不使用单例模式,我们也可以像文中的例子一 样通过注入的方式来解决所谓的低效问题。

写在后面的话:单例模式本身并不邪恶,邪恶的是在错误的环境下使用单例模式。不要为了单例而单例。

Tags: 单例, 模式

step by step 安装svn for ubuntu

我在安装SVN for ubuntu的时候直接参考了本文,因此摘录下来,与各位分享。
原文:http://www.svn8.com/svnpz/20080308/253.html

1. 简介

如果您对 Subversion 还比较陌生,本节将给您一个关于 Subversion 的简要介绍。

Subversion 是一款开放源代码的版本控制系统。使用 Subversion,您可以重新加载源代码和文档的历史版本。Subversion 管理了源代码在各个时期的版本。一个文件树被集中放置在文件仓库中。这个文件仓库很像是一个传统的文件服务器,只不过它能够记住文件和目录的每一次变化。

2. 假设

首先我们假设您能够在 Ubuntu 中操作 Linux 的命令、编辑文件、启动和停止服务。当然,我们还认为您的 Ubuntu 正在运行中,您可以使用 sudo 操作并且您打算使用 Subversion。

我们假设您可能需要使用所有可能的方法访问 SVN 文件仓库。同时我们也认为您应该已经配置好了您的 /etc/apt/sources.list 文件。

3. 本文涉及的范围

要通过 HTTP 协议访问 SVN 文件仓库,您需要安装并配置好 Web 服务器。Apache 2 被证实可以很好的与 SVN 一起工作。关于 Apache 2 的安装超出了本文的范围,尽管如此,本文还是会涉及如何配置 Apache 2 使用 SVN。

类似的,要通过 HTTPS 协议访问 SVN 文件仓库,您需要在您的 Apache 2 中安装并配置好数字证书,这也不在本文的讨论范围之中。

4. 安装

幸运的,Subversion 已经包含在 main 仓库中。所以,要安装 Subversion,您只需要简单的运行:

$ sudo apt-get install subversion

$ sudo apt-get install libapache2-svn

如果系统报告了依赖关系的错误,请找出相应的软件包并安装它们。如果存在其它问题,也请自行解决。如果您是再不能解决这些问题,可以考虑通过 Ubuntu 的网站、Wiki、论坛或邮件列表寻求支持。

5. 服务器配置

您应该已经安装了上述的软件包。本节将阐述如何创建 SVN 文件仓库以及如何设置项目的访问权限。

5.1. 创建 SVN 仓库

许多位置都可以放置 Subversion 文件仓库,其中两个最常用的是:/usr/local/svn 以及 /home/svn。为了在下面的描述中简单明了,我们假设您的 Subversion 文件仓库放在 /home/svn,并且你的项目名称是简单的“myproject”。

同样的,也有许多常用的方式设置文件仓库的访问权限。然而,这也是安装过程中最经常出现错误 的地方,因此我们会对此进行一个详细说明。典型的情况下,您应该创建一个名为“Subversion”的组来拥有文件仓库所在的目录。下面是一个快速的操 作说明,有关内容请参考相关文档的详细说明:

在 Ubuntu 菜单上选择“系统->系统管理->用户和组”;

切换到“组”标签;

点击“添加组”按钮;

组名为“subversion”;

将您自己和“www-data”(Apache 用户)加入组成员中;

点击“OK”以确认修改,关闭该程序。

您需要注销然后再登录以便您能够成为 subversion 组的一员,然后就可以执行签入文件(Check in,也称提交文件)的操作了。

现在执行下面的命令

$ sudo mkdir /home/svn

$ cd /home/svn

$ sudo mkdir myproject

$ sudo chown -R root:subversion myproject

$ sudo chmod -R g+rws myproject

最后的一条命令赋予组成员对所有新加入文件仓库的文件拥有相应的权限。

下面的命令用于创建 SVN 文件仓库:

$ sudo svnadmin create /home/svn/myproject

6. 访问方式

Subversion 文件仓库可以通过许多不同的方式进行访问(Check Out,签出)——通过本地硬盘,或者通过各种网络协议。无论如何,文件仓库的位置总是使用 URL 来表示。下表显示了不同的 URL 模式对应的访问方法:

模式

访问方法

file:///

直接访问本地硬盘上文件仓库

http://

通过 WebDAV 协议访问支持 Subversion 的 Apache 2 Web 服务器

https://

类似 http://,支持 SSL 加密

svn://

通过自带协议访问 svnserve 服务器

svn+ssh://

类似 svn://,支持通过 SSH 通道

本节中,我们将看到如何配置 SVN 以使之能够通过所有的方法得以访问。当然这里我们之讨论基本的方法。要了解更高级的用途,我们推荐您阅读《使用 Subversion 进行版本控制》在线电子书。

6.1. 直接访问文件仓库(file://)

这是所有访问方式中最简单的。它不需要事先运行任何 SVN 服务。这种访问方式用于访问本地的 SVN 文件仓库。语法是:

$ svn co file:///home/svn/myproject

或者

$ svn co file://localhost/home/svn/myproject

注意:如果您并不确定主机的名称,您必须使用三个斜杠(///),而如果您指定了主机的名称,则您必须使用两个斜杠(//).

对文件仓库的访问权限基于文件系统的权限。如果该用户具有读/写权限,那么他/她就可以签出/提交修改。如果您像前面我们说描述的那样设置了相应的组,您可以简单的将一个用户添加到“subversion”组中以使其具有签出和提交的权限。

6.2. 通过 WebDAV 协议访问(http://)

要通过 WebDAV 协议访问 SVN 文件仓库,您必须配置您的 Apache 2 Web 服务器。您必须加入下面的代码片段到您的 /etc/apach2/apache2.conf 中:

DAV svn

SVNPath /home/svn/myproject

AuthType Basic

AuthName "myproject subversion repository"

AuthUserFile /etc/subversion/passwd

Require valid-user

 

 

当您添加了上面的内容,您必须重新起动 Apache 2 Web 服务器,请输入下面的命令:

sudo /etc/init.d/apache2 restart

接下来,您需要创建 /etc/subversion/passwd 文件,该文件包含了用户授权的详细信息。要添加用户,您可以执行下面的命令:

sudo htpasswd2 /etc/subversion/passwd user_name

它会提示您输入密码,当您输入了密码,该用户就建立了。您可以通过下面的命令来访问文件仓库:

$ svn co http://hostname/svn/myproject myproject --username user_name

它会提示您输入密码。您必须输入您使用 htpasswd2 设置的密码。当通过验证,项目的文件就被签出了。

警告:密码是通过纯文本传输的。如果您担心密码泄漏的问题,我们建议您使用 SSL 加密,有关详情请看下一节。

6.3. 通过具有安全套接字(SSL)的 WebDAV 协议访问(https://)

通过具有 SSL 加密的 WebDAV 协议访问 SVN 文件仓库(https://)非常类似上节所述的内容,除了您必须为您的 Apache 2 Web 服务器设置数字证书之外。

您可以安装由诸如 Verisign 发放的数字签名,或者您可以安装您自己的数字签名。

我们假设您已经为 Apache 2 Web 服务器安装和配置好了相应的数字证书。现在按照上一节所描述的方法访问 SVN 文件仓库,别忘了把 http:// 换成 https://。如何,几乎是一模一样的!

6.4. 通过自带协议访问(svn://)

当您创建了 SVN 文件仓库,您可以修改 /home/svn/myproject/conf/svnserve.conf 来配置其访问控制。

例如,您可以取消下面的注释符号来设置授权机制:

# [general]

# password-db = passwd

现在,您可以在“passwd”文件中维护用户清单。编辑同一目录下“passwd”文件,添加新用户。语法如下:

username = password

要了解详情,请参考该文件。

现在,您可以在本地或者远程通过 svn:// 当文 SVN 了,您可以使用“svnserve”来运行 svnserver,语法如下:

$ svnserve -d --foreground -r /home/svn

# -d -- daemon mode

# --foreground -- run in foreground (useful for debugging)

# -r -- root of directory to serve

要了解更多信息,请输入:

$ svnserve --help

当您执行了该命令,SVN 就开始监听默认的端口(3690)。您可以通过下面的命令来访问文件仓库:

$ svn co svn://hostname/myproject myproject --username user_name

基于服务器的配置,它会要求输入密码。一旦通过验证,就会签出文件仓库中的代码。

要同步文件仓库和本地的副本,您可以执行 update 子命令,语法如下:

$ cd project_dir

$ svn update

要了解更多的 SVN 子命令,您可以参考手册。例如要了解 co (checkout) 命令,请执行:

$ svn co help

6.5. 通过具有安全套接字(SSL)的自带协议访问(svn+ssh://)

配置和服务器进程于上节所述相同。我们假设您已经运行了“svnserve”命令。

我们还假设您运行了 ssh 服务并允许接入。要验证这一点,请尝试使用 ssh 登录计算机。如果您可以登录,那么大功告成,如果不能,请在执行下面的步骤前解决它。

svn+ssh:// 协议使用 SSL 加密来访问 SVN 文件仓库。如您所知,数据传输是加密的。要访问这样的文件仓库,请输入:

$ svn co svn+ssh://hostname/home/svn/myproject myproject --username user_name

注意:在这种方式下,您必须使用完整的路径(/home/svn/myproject)来访问 SVN 文件仓库

基于服务器的配置,它会要求输入密码。您必须输入您用于登录 ssh 的密码,一旦通过验证,就会签出文件仓库中的代码。

您还应该参考 SVN book 以了解关于 svn+ssh:// 协议的详细信息。

7. 参考资料

Setting up Apache on Ubuntu

SVN Home page

SVN Book

Apache 2 Documentation

Mod-SSL

Apache-SSL SvYLinux联盟

Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论

Tags: stepbystep, svn, ubuntu

Records:171234