我应该把我的数据库项目放在TFS的哪个位置?

13

浏览了其他问题,没有看到明确的答案。

我们是一个小的开发团队,正在开发可以描述为3个独立前台“应用程序”的项目(通过asp web的OnlineOrders、TradeManagement winforms app和ASP.NET ReportingSuite)。但是,好或坏,这些应用程序共享一个中央SQL2005数据库,让我们称其为MainDB。它们都使用相同的订单表结构、用户、账户等,几乎80%的对象都以某种方式被每个应用程序使用。

在TFS中,我认为这三个应用程序都是单独的项目,具有工作项跟踪、报告等功能。创建我们的“基于代码”的解决方案似乎很好用。

现在我正在尝试了解如何将MainDB数据库添加到TFS源代码控制中。我找不到明显的方法来做到这一点。

问题是: 我应该为MainDB创建一个数据库项目,将模式导出到项目中的脚本中,并将该数据库项目添加到每个解决方案中,放在每个TFS项目中吗?

还是应该为我的数据库项目单独建立一个TFS项目?开发人员需要打开MainDB数据库TFS项目和(例如)TradeManagement TFS项目进行新功能开发(因为大多数新功能也将涉及一些数据库更改)吗?这似乎很麻烦。

还是通常只有一个名为“Everything”的大型TFS项目,其中包含代码项目的功能分支、数据库的数据库分支以及可能使用MainDB数据库的任何其他项目? (在img中,假设MainDB脚本位于“Database”文件夹中)

alt text

等等。我很困惑。Codeplex似乎指出通过将所有解决方案放在一个大单一解决方案中保持简单。这可持续吗?


感谢回复,非常好。

将数据库视为API的想法很有趣,确实是这样。数据库从许多来源填充,有些是内部的,有些是外部的,一些应用程序获取通过另一个应用程序输入的数据。将其作为每个应用程序都可以轻松使用的API进行控制,这是一个非常有帮助的比喻,谢谢。

没有支持依赖关系的代价是一个问题,但我认为我们可以有纪律地按照顺序进行分支。应用程序代码库的分支可能会比数据库更加复杂 - 我们真正想要的只是以某种方式将数据库纳入源代码控制,以满足Sarbannes-Oxley审计要求。

我还需要再思考一下。

对数据库进行水平分区并不是我考虑过的事情。感觉共享太多的数据库对象,无法将其划分为水平块 - 我们可能会在几个块中拥有相同的对象(表/存储过程等),我认为这会让我们更加困惑。


你的所有应用程序是否一起部署,运行在同一个数据库实例上?还是它们各自使用自己的实例? - Dave Roberts
它们都在同一个实例上运行。 - Graeme
3个回答

17

关于将数据库视为API的评论是正确的。虽然实现方式非常不同——从源代码构建和部署数据库需要特殊工具,而不仅仅是编译器+xcopy——但就概念上而言,您的情况与共享公共实用程序库的团队并没有什么不同。

幸运的是,这是一个经过充分研究的话题。此外,没有任何与TFS有关的特别之处;您可以阅读任何具有强大分支和合并功能的源代码控制系统的文档,目前大多数系统都具备这些功能。例如《实用Perforce》、《Red Bean》书籍(SVN)、Eric Sink的博客(Vault)等都具有良好的见解。我特别喜欢Laura Wingerd关于代码行的演示文稿。当然,您也应该阅读最新的TFS指南

在StackOverflow上,将这些概念付诸实践的问题也已经出现了多次。对于TFS用户来说,这个Team Foundation Server Source Control Structure是最好的总结。它包含了最重要的行业原则...

  1. 所有分支都是自包含的。分支之间或分支与固定(非分支)位置之间不允许有依赖关系。
  2. 分支内的相对路径不变
  3. 晋升模型被明确定义,并适用于所有工程艺术品:开发->集成->生产(使用它们的术语来表示主要代码行;许多其他常用的,通常归结为相同的核心思想)
  4. 1个集成分支(也称为“树干”或“主干”),连接树的稳定和不稳定侧。不允许点对点合并。
  5. 根据需要隔离团队/功能/重构的程度,可以有可变数量的Dev分支
  6. 可变数量的Release分支,取决于热修复的频率、任何版本的重叠以及审核要求的严格程度
  7. 如果您选择签入次要资源(如文档、第三方二进制文件、编译器等),它们应该位于分支结构内。请参阅规则#1。

...连同一些TFS特定的怪癖...

  • 不要使用工作区映射来规避共享文件的问题。(我不知道谁最初写了这个“建议”——幸运的是,在最新的P&P修订版中它已经不再出现)
  • 不要将分支/合并到现有分支层次结构的子目录中。 (同样,自TFS推出以来一直遵循的一些“建议”,即使我还没有遇到过一个人是因为他们遵循了这个建议而感到高兴)
  • 不要使用默认的TeamBuildTypes文件夹;像所有代码一样,您的构建脚本应该遵循上述的1-3要点。

(坦白说,虽然那里的回答已经变得有点太详细了。即使你有数十个或数百个分支,也没有必要将它们嵌套得像修改后的问题那样深入源码树中。对于那些初次接触大规模源管理和/或路径空间分支管理的读者来说,有些分支尤其令人困惑,会掩盖主要的收获。如果你希望让你组织的每个人都遵守“路规”,如Wingerd所说,简单就是金色的。)

无论如何,我知道你并不是特别询问分支和合并,但是你设置源码树的方式直接影响您的整个软件流程。坦白地说,如果您在添加数据库项目时不遵循#1这样的规则,您的前端应用程序团队将永远无法独立运作。因此,您的第一个提议(在$/FrontOfficeDevelopment下显示的结构)比第二个更接近实际情况。但是您需要更进一步。将3个应用程序+数据库的文件夹向树深度移动一级。也就是说,给它们一个共同的父级——让我们称之为“Integration”,以匹配其他StackOverflow示例。如果您需要分支,现在可以通过分支此容器来进行一个自包含的操作;如果每个应用程序都是Team Project中的顶层文件夹,则会更加困难。不久之后,您的源代码树将看起来像“TFS Guidance II”图表中的理想状态...这并不是巧合:)

$/Everything
   |- Integration
       |- 3rdPartyAssemblies
       |- Database
       |- OnlineOrders
            |- Code
            |- Tests*
       |- ReportingSuite
            |- Code
            |- Tests
       |- TeamBuildTypes
            |- TfsBuild.proj
            |- QuickBuild.targets
            |- FullBuild.targets
            |- FullBuildAndTest.targets
       |- TradeManagement
            |- Code
            |- Tests
   |- Development #1
       |- 3rdPartyAssemblies
       |- Database
       |- etc
   |- Release #1
       |- 3rdPartyAssemblies
       |- Database
       |- etc                   

将测试按应用程序分开,如上所示,使得各个团队更容易在他们负责的部分上工作。例如,OnlineOrders 团队只需要下载 OnlineOrders 以及共享的部分,如第三方库和数据库。如果您的应用程序非常大或者有数十个/数百个应用程序,这是非常方便的。但是,将所有测试放在分支内的一个顶级 Tests 文件夹中也同样有效,如下所示:

   |- Integration
       |- Database
       |- OnlineOrders
       |- ...
       |- Tests
            |- Database
            |- OnlineOrders
            |- ...

这样做使得一次运行整套测试更加方便,并减少了树的深度/复杂度。缺点是在日常工作中你需要更频繁地在树中导航。或许更令人困扰的是,这需要你手动维护一个平行的结构。随着时间的推移,添加/删除项目、代码重构、部门重组、外包等等很多事情都可能会改变主代码文件夹的布局。如果不更新 Tests 以匹配这些变化,至少会让 QA 的人感到困惑,还有很大的机会出现测试自动化失效。


你还提出了将公司的工作划分为团队项目的问题。好消息是,这个决定完全与你选择的分支/合并流程无关。与构建、报告、SharePoint 神器和(在某种程度上)工作项紧密耦合的团队项目概念不同,TFS 源代码控制系统只是一个跨越它们所有的大树。我在图表中使用了“Everything”项目,因为这样比较容易绘制——而且我自己也确实偏爱这种策略——但实际上这并不重要。

然而,将我们到目前为止了解到的内容与 TFS 的“团队项目”概念结合起来需要额外的思考。我承认,从产品的粗略外观上很难看出“团队项目”到底是干什么的。可以说它们被设计成是非常大的容器。让我们举一些熟悉的例子。Windows 和 Office 绝对应该是单独的团队项目——它们按独立的发布时间表开发,使用非常不同的工程实践,运行定制的错误报告和报告工作流,完全不兼容的构建系统等等。然而,即使 NTFS 团队和 MSPaint 团队的实际工作从未重叠过,也没有理由将它们分开成单独的团队项目;除非下一个发布里程碑也带来了重大的流程变化,否则 Windows 7 SP1 和 Windows 8 的开发也不应该被分开。

与分支一样,我认为简单就是金色的。一旦有了多个团队项目,许多曾经平凡无奇的任务突然变得棘手起来。假设你在一个主要由另一个团队开发的数据库存储过程中发现了一个 bug。你会在你的团队项目中打开这个 bug(以确保它被解决并返回给你进行 QA 签名)、在另一个团队的团队项目中打开它(因为他们将编写修复程序),还是在一个专门的 DB-only 团队项目中?平均开发人员需要搜索多少个活动工作项呢?这只是我想到的第一个场景;还有很多功能在不同团队项目之间无法转换。不幸的是,也有一些功能要求你分开做。如果团队 #1 想使用即时合并,但团队 #2 的开发流程依赖于独占锁定,那在单个团队项目中就不支持。

我已经多次使用了“进程”这个词。这确实是关键所在。一旦你理解了 TFS过程模板 的概念,团队项目就会变得更加清晰易懂。在这里 这篇旧博客中,我深入探讨了这个想法,并提出了一个方便的经验法则:每个进程模板创建一个团队项目。当然也有例外;并非所有TFS功能都可以通过模板来控制。更多详细信息请参见促使我写这篇文章的白皮书——里面包含一张表格,详细说明了单个团队项目内部/之间支持/不支持的内容。我的猜测是像你们这样的小企业不需要做太多妥协就可以适应单个团队项目的模式。


嗨Richard,感谢您的全面回复和链接。我花了一些时间来消化。我的脑海中有一些关于您上面的树状图和https://dev59.com/zuo6XIcBkEYKwwoYTzNK之间的区别的困惑。在您的树状图中,您将每个子项目都包含在仅3个父目录(Integration,Development,Release)中,直接位于“Everything”团队项目下方,而在问题381020中,有一个“Subprojects”级别,每个子项目都有自己的Integration,Development,Release目录。 - Graeme
算作另一个小提示,我认为维基百科使它变得过于复杂了。在我看来,如果你的“项目”有可能共享一行代码,则保持它们属于同一分支结构的好处大于成本。 (即:如果它们的时间表分歧,它们将需要多个发布分支,尽管具有共享祖先,但它们会独立运行。)另一方面,如果它们真正是不同的实体,则为每个创建一个团队项目更清晰且更可定制。总之,“子项目”级别让我觉得这是一个没有任何人受益的妥协。 - Richard Berg

5

如果你还对我们是如何做到这一点感兴趣:我们请来了一位TFS专家帮助!

我们选择了这样的方式:将所有解决方案分解成它们的项目,将所有项目放入相关的桶中,在源目录中放置.sln文件,使它们易于查找。 这是一种逻辑上组织事物的方式,目前已经运作良好。

<Branch>
Source
    Solution files at root
    Server Apps     Previously “services”, helper apps running on server
        App 1
            Project 1
            Project N
            Installer
        App 2
    Services    WCF/Web services providing business operations
        App 1
            Project 1
            Installer
    Client      Rich client applications, e.g. WinForms, WPF
        App 1   
            Project 1
            Installer
    Web     Server side web applications
        App 1
            Project 1
            Installer
    Database    All scripts related to database structures and data
        Databases
            SMOL
            AuditAuthentication
            …
        Servers (Environments?)
            Server1.proj
            Server2.proj
    Common  Reusable classes across applications
        Communications
        Security
        ….
    SharedBin   3rd party binaries
        EnterpriseLibrary
        …
Docs
    Release notes
    Help files
Scripts
    Deployment
    Data Migration
    …
System Tests
    Functional
    Performance
    Security
    …

这是在VS中的效果(为了保护隐私做了一些混淆):alt text

3
在这种情况下,我会将数据库项目放入单独的项目中,并从其他项目中引用它。
我的看法是,如果你的数据库(无论是单个数据库实例还是公共数据库架构)在多个项目之间共享,则需要将数据库架构(或至少其中的大部分)视为向这些项目公开的接口。此接口/ API需要独立于任何单个项目进行变更控制和版本控制。因此,数据库成为所有这些项目的外部依赖项,就像任何共享库或服务器一样。
现在,您正在使用TFS。在TFS中拥有单独的项目会带来成本。TFS的分支模型基于具有项目树的单个命名空间。这需要很多注意和纪律性,否则您将搞乱合并等操作。
此外,完全缺乏项目之间的依赖关系支持。如果要更改控制项目之间的依赖关系,则必须将项目分支为依赖项目的子项目(具有我上面提到的所有分支和合并跟踪问题),或者教会您的构建系统始终从TFS获取正确的版本(我觉得这很可怕)。
请注意,“Everything”项目不会有所帮助,如果其每个部分都需要单独发布/版本控制。您提到了子项目的“功能分支”等。这将比单独的项目更混乱,而单独的项目至少是明确的。如果您公开同意维护共同的数据库项目,则稍后发现需要在其他所有项目团队之间协商对其进行每个更改时,就不会有任何惊喜了。
因此,最终决定取决于您。这些项目是否足够分开以将它们版本化为单独的项目。它们是否会分叉。您是否希望或需要它们分叉?这是否值得额外工作的成本?
并且在完全不同的层面上。你所谈论的只是将你的代码库垂直分区成层 - 这里来了数据库项目(具有数据库架构等),这里是数据访问,这里是业务逻辑等...
您是否考虑过水平分区为域级块,每个块都由其数据库架构完整支持和备份。您的项目不仅依赖于公共数据库架构,还依赖于一个或多个共享模块。它们中的每一个都将带来其自己的数据库脚本部分。
我只是在思考。我不确定那是否更好,甚至在实践中是否可行。任何人都可以分享他或她的意见吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接