对于数据库来说,允许应用程序始终通过SP执行CRUD操作是最佳做法吗?

时间:2009-02-12 21:10:08

标签: database linq-to-sql database-design

我听说过背后的推理,如果其他人认为这是最好的做法/好主意,我很好奇。

一个原因是,限制直接访问数据库表并强制应用程序/用户使用SP(存储过程)执行CRUD操作将允许DBA

  1. 精细控制以在批准SP之前审核/审核SP
  2. 避免开发人员编写的可能导致服务器负载/其他服务器问题的随机查询
  3. 这意味着开发人员无法在表上编写Linq查询(尽管可能涉及SP的Linq查询) 这也意味着开发人员必须忘记编译时检查以及完全控制数据,而主要使用另一种语言(SQL)来处理数据。

    我并不反对这一点,也不认为这是一个好主意。我很想知道其他人的想法。这种方法的任何其他优点和缺点是什么。

    更新:正如Thomas in his answer所提到的,我倾向于认为SP是逻辑并且使用“SQL中的数据库编程”来做逻辑是可以的,只要它不是'业务逻辑”。业务逻辑需要分离,编译时检查和集成检查点以及什么不是。

12 个答案:

答案 0 :(得分:7)

就个人而言,我从来没有发现过程对于CRUD中的'R'足够灵活。我经常使用观点。但是通过视图和&amp ;;访问数据库procs还允许你抽象出数据库表,为将来的数据模型提供更大的灵活性 ......几乎就像在界面上工作一样。

答案 1 :(得分:4)

完全取决于您的环境。这个问题的答案实际上不是编码问题,而是商业决策。

如果您的数据库仅支持一个应用程序,并且与其紧密集成,那么出于灵活性的原因,最好将逻辑放在应用程序中。在这些情况下,将数据库简单地作为使用通用功能的普通数据存储库处理将使您失去灵活性 - 获得供应商,实施,部署等等。

另一方面,如果您正在处理公司数据库,那么最好尽可能地降低安全性。至少应启用所有适当的约束,并且如果可能,仅应通过视图和过程访问数据。在这些情况下,应该忽略呜呜的程序员......

  1. 使用公司数据库,资产很有价值,无效数据或操作可能会对业务造成威胁。在这些情况下,您最关心的是业务,而不是您的编码员访问的方便程度。
  2. 根据定义,此类数据库可由多个应用程序访问。您需要使用存储过程提供的抽象,以便在升级应用程序A并且您没有资源升级应用程序B时可以更改数据库。
  3. 类似地,在SP中而不是在应用程序代码中封装业务逻辑允许比在应用程序代码中嵌入此类逻辑更容易和可靠地在整个业务中实现对这种逻辑的更改。例如,如果计算必须在一个SP中更改而不是多个应用程序,那么如果税收计算更改,则工作更少,更稳健。这里的经验法则是业务规则应该在最接近数据的位置实现 - 因此,如果您有专家应用程序,那么该应用程序的逻辑可以在该应用程序中实现,但逻辑更广泛适用应该在SP中实施业务。

答案 2 :(得分:3)

我在一个采用这种方法的团队工作。

还有其他好处,例如

  1. 安全性 - 如果您无法直接访问基表,它可以成为深度防御方法的一部分。
  2. PDM的灵活性 - 出于性能原因,您可以对PDM进行大规模更改,只要保留“合同”(SP,视图),应用程序层就不会发现。
  3. Futureproofing - 您可以使用其他语言编写另一个应用程序来访问您的数据库。
  4. 当您拥有专门的数据库人员或团队时,它最有效。

    我正在兴趣地关注这个领域,因为它似乎与使用ORM时所需的技术背道而驰。

答案 3 :(得分:3)

使用存储过程(以及不使用动态SQL的过程)允许数据库人员进行性能调优,更重要的是它限制了对数据库表和视图的访问,这样除了dba之外没有人可以更改它们。如果您有财务申请并希望防范内部欺诈,这非常重要。

答案 4 :(得分:3)

这篇博客文章提出了一个非常好的对立点,“存储过程总是更好”的人群。

http://statestreetgang.net/post/2008/04/My-Statement-on-Stored-Procedures.aspx

就我个人而言,我处于困境并倾向于使用它们。

答案 5 :(得分:1)

这在很大程度上取决于您的数据和环境。

如果您正在向不同的读者和作者广泛使用您的数据库,请使用SPROC:这样您就可以保持绝对控制。

如果您更喜欢信任开发人员的封闭式商店,请使用LINQ。它允许更大的访问数据的灵活性,并使未来对数据库的更改变得轻而易举。 (例如,如果向表中添加字段,则必须重新生成LINQ数据访问部分类,并且已完成;否则您将不得不重写一堆SPROC,以及在应用程序中更改数据访问层。)

答案 6 :(得分:1)

使用您的清单:

这意味着开发人员不需要在表上编写Linq查询。这也意味着开发人员可以忘记对数据库访问代码的编译时检查,并让知道数据库的人完全控制数据。开发人员不需要使用其他语言(SQL或Linq)来处理数据。

换句话说,这取决于你的工作环境。

答案 7 :(得分:1)

是的,特别是在Oracle中。

在Oracle中,触发器和外键需要许多SQL/PLSQL上下文切换。

我个人以下列方式开发需要大型 CRUD操作的数据库:

  1. 我既不使用触发器也不使用外键。
    • 没有为用户提供对表的修改权限。
    • 数据库中的所有DML都以这种方式执行:
      1. 要插入/更新/删除的数据将加载到TEMP
    • 调用存储过程,其中:
      1. 检查数据的一致性,如BEFORE I/U/D触发器和外键
        • 数据MERGE进入表格
        • 检查数据的一致性,如AFTER I/U/D触发器和外键
  2. 在数据库中,我有一个服务表,它包含这些foreign key - 就像字段之间的关系一样。

    程序的存根是从该表自动生成的,每次表更改时都需要重新创建。

    所有检查都由处理数千行的单个查询执行,而不是在循环中调用触发器数千次。

    这是巨大的增加修改性能。

    如果您需要在UPDATE行表中50,000,例如10,000,000行,则可能需要10秒,而不是200秒甚至更多。


    当然,只有当您需要真正快速响应真正的大型操作时,它才能收回成本。

    以这种方式设计数据库非常困难,如果你不习惯它就容易出错。

答案 8 :(得分:1)

正如其他人所说,这在很大程度上取决于您的环境。

但是,即使在企业情况下,您希望保护关键任务数据,也不一定要使用CRUD存储过程。如上所述,使用存储过程实现数据库插入假定存储过程比应用程序编程人员更聪明。存储过程是逻辑,因此编写它们的技巧是程序员的技能。所以,如果你碰巧有一个DBA,他也是一个比你的程序员更好的程序员,那么,通过各种方式让他们编写存储过程来保持你的程序员诚实。某些地方可能就是这种情况。值得记住的是Thomas Hansen的观点,即使用存储过程可能导致整个组织被锁定在给定存储过程的逻辑中。同样,某些组织可能想要或需要这个。

另一种方法是使用一些存储过程来保证一致性,但仍然允许ad-hoc插入。根据数据库的不同,这可以实现更清晰的界面和更高的一致性。

存储过程可能会快一点,但这不太可能是大型组织主数据库的主要考虑因素(小型组织可能不会想要那么多层)。

如果要添加大量数据,批处理文件和关闭事务等操作非常有用。但在我看来,CRUD并不意味着创建了大量数据,而是像大多数用户级应用程序那样创建,读取,编辑和删除数据的小实例。

答案 9 :(得分:0)

看起来你不相信开发人员编写行为良好的查询。

这可能来自经验。

我建议如果糟糕的开发人员正在编写垃圾sql代码,他们也会编写错误的应用程序代码,这意味着管理层做得很差。

问题不在于动态SQL(即使参数化)与存储过程相比:它管理不善。

通过存储过程强制进行数据库访问不会解决这个问题。

无论如何,即使只通过存储过程提供对数据库的访问,坏程序员仍然可以对数据库施加压力。

现实情况是,如果您在数据库中难以访问数据,开发人员将使用其他技术不将数据放入数据库或转换数据库。例如,假设您有一个用于存储pdf或其他内容的博客字段,是什么阻止它们序列化对象并将它们存储在blob中,以便在代码中检索和反序列化?

我会小心的。

确保存储过程最终在源代码管理中,并且构建工具可以自动执行存储过程到相应数据库环境的部署(连续或每天)...

答案 10 :(得分:0)

另一个明显的好处是性能,一旦SP被编译,它们将比代码中的SQL执行得更快。对于注重安全性和控制力的大型组织,您已经说明了SP的主要优势。它使DBA能够更容易地关注在性能问题时针对数据库运行的SQL,以及数据库中的所有内容。

一个缺点是可移植性,如果您正在编写商业应用程序并且客户坚持要求您适应其现有的数据库,那么您将需要更多的工作来处理SP而不是内联SQL。

答案 11 :(得分:0)

数据库是一个存储桶,一旦你开始将其视为业务逻辑的一部分,你将最终处于一个非常紧张和不舒服的地方并创建MUD而不是SW ......

分离逻辑和数据。 SP是逻辑 ......!

Evil tongues(我就是这样)声称SP是数据库供应商创建锁定技术的技术,这将使创建抽象变得更加困难,从而可以轻松地更改数据库供应商......

SP使用了99.9%的ANTI设计模式......!