简体   繁体   English

动态sql vs存储过程 - 优点和缺点?

[英]Dynamic sql vs stored procedures - pros and cons?

I have read many strong views (both for and against) SPs or DS. 我已经阅读了许多强烈的观点(赞成和反对)SP或DS。

I am writing a query engine in C++ (mySQL backend for now, though I may decide to go with a C++ ORM). 我正在用C ++编写一个查询引擎(mySQL后端现在,虽然我可能决定使用C ++ ORM)。 I cant decide whether to write a SP, or to dynamically creat the SQL and send the query to the db engine.# 我无法决定是编写SP,还是动态创建SQL并将查询发送到数据库引擎。#

Any tips on how to decide? 关于如何决定的任何提示?

Here's the simple answer: 这是一个简单的答案:

If your programmers do both database and coding work, keep the SQL with the app. 如果您的程序员同时执行数据库和编码工作,请将SQL与应用程序保持一致。 It's easier to maintain that way. 保持这种方式更容易。 Otherwise, let the DB guys handle it in SPs. 否则,让DB人员在SP中处理它。

You have more control over the mechanisms outside the database. 您可以更好地控制数据库外部的机制。 The biggest win for taking care of this outside the database is simply maintenance (in my mind). 在数据库之外处理这个问题的最大胜利就是维护(在我看来)。 It'd be slightly hard to version control the SP vs the code you generate outside the database. 对SP进行版本控制与在数据库外部生成的代码相比有点难度。 One more thing to keep track of. 还有一件事要跟踪。

While we're on the topic, it's similar to handling data/schema migrations. 虽然我们讨论的是主题,但它与处理数据/架构迁移类似。 It's annoyingly complex to version/handle schema migrations, if you don't already have a mechanism for this, you will have yet another thing you'll need to manage. 版本/处理模式迁移非常复杂,如果您还没有这种机制,那么您将需要管理另一件事。 It comes down to simply being easier to manage/version these things outside the database. 它归结为简单地在数据库之外管理/版本化这些东西。

Consider the scenario where you have a bug in your SP. 考虑您的SP中存在错误的情况。 Now it needs to be changed, but then you hop over to another developers database/sandbox. 现在它需要更改,但随后您跳转到另一个开发人员数据库/沙箱。 What version is the sandbox and the SP? 什么版本的沙箱和SP? Now you have to track multiple versions. 现在您必须跟踪多个版本。

One of the main differentiators is whether you are writing the "one true front end" or whether the database is the central piece of your application. 其中一个主要区别在于您是在编写“真正的前端”还是数据库是您应用程序的核心部分。

If you are going to have multiple front ends stored procedures make a lot of sense because you reduce your maintenance overhead. 如果你要有多个前端存储过程很有意义,因为你减少了维护开销。 If you are writing only one interface, stored procedures are a pain, because you lose a lot of flexibility in changing your data set as your front end needs change, plus you now have to do code maintenance, version control, etc. in two places. 如果您只编写一个接口,那么存储过程很麻烦,因为在前端需要更改时,您在更改数据集时会失去很大的灵活性,而且您现在必须在两个地方执行代码维护,版本控制等操作。 。 Databases are a real pain to keep in sync with code repositories. 数据库与代码存储库保持同步真的很痛苦。

Finally, if you are coding for multiple databases (Oracle and SQL compatible code, for example), I'd avoid stored procedures completely. 最后,如果您要编写多个数据库(例如,Oracle和SQL兼容代码),我将完全避免存储过程。

You may in certain rare circumstances, after profiling, determine that some limited stored procedures are useful to you. 在某些罕见的情况下,您可能会在分析后确定某些有限的存储过程对您有用。 This situation comes up way less than people think it does. 这种情况比人们想象的要少。

The main scenarios when you MUST have the SP is: 必须拥有SP的主要场景是:

1) When you have very complex set of queries with heavy compile overhead and data drift low enough that recompiling is not needed on a regular basis. 1)如果您有非常复杂的查询集,编译开销很大,数据漂移足够低,则不需要定期重新编译。

2) When the "Only True" logic for accessing the specific data set is VERY complicated, needs to be accessed from several different codebases on different platforms (so writing multiple APIs in code is much more expensive). 2)当访问特定数据集的“Only True”逻辑非常复杂时,需要从不同平台上的几个不同代码库访问(因此在代码中编写多个API要贵得多)。

Any other scenario, it's debatable, and can be decided one way or another. 任何其他情况,它都是有争议的,可以通过某种方式决定。

I must also say that the other posters' arguments about versioning are not really such a big deal in my experience - having your SPs in version control is as easy as creating a "sql/db_name" directory structure and having easy basic "database release" script which releases the SP code from the version control location to the database. 我还必须说其他海报关于版本控制的论点在我的经验中并不是那么重要 - 让版本控制中的SP像创建“sql / db_name”目录结构一样容易,并且具有简单的基本“数据库发布”将SP代码从版本控制位置释放到数据库的脚本。 Every company I worked for had some kind of setup like this, central one run by DBAs or departmental one run by developers. 我工作的每家公司都有这样的设置,一个由DBA运行,另一个由开发人员运行。

The one thing you want to avoid is to have your business logic spread across multiple tiers of your application. 您要避免的一件事是让您的业务逻辑分布在应用程序的多个层中。 Database DDL and DML are difficult enough to keep in sync with an application code base as it is. 数据库DDL和DML很难与应用程序代码库保持同步。

My recommendation is to create a good relational schema, but all your constraints and triggers so that the data retains integrity even if somebody goes to the database and tries to do something through some command line SQL. 我的建议是创建一个良好的关系模式,但所有的约束和触发器,以便即使有人进入数据库并尝试通过某些命令行SQL执行某些操作,数据仍保持完整性。

Put all your business logic in an application or service that calls (static/dynamic) SQL then wraps the business functionality you are are trying to expose. 将所有业务逻辑放在调用(静态/动态)SQL的应用程序或服务中,然后包装您尝试公开的业务功能。

Stored-procedures have two purposes that I can think of. 存储过程有两个我能想到的目的。

  1. An aid to simplifying data access. 有助于简化数据访问。 The Stored Procedure does not have any business logic in it, it just knows about the structure of the data and exposes an interface to isolate accessing three tables and a view just to get a single piece of information. 存储过程中没有任何业务逻辑,它只知道数据的结构,并公开一个接口来隔离访问三个表和一个视图,只是为了得到一条信息。
  2. Mapping the Domain Model to the Data Model, Stored Procedures can assist in making the Data Model look like a given Domain Model. 将域模型映射到数据模型,存储过程可以帮助使数据模型看起来像给定的域模型。

After the program has been completed and has been profiled there are often performance issues with the pre 1.0 release. 程序完成并且已经过分析后,1.0版本经常出现性能问题。 Stored procedures do offer batching of SQL without traffic needing to go back and forth between the DBMS and the Application. 存储过程确实提供了SQL的批处理,而无需在DBMS和应用程序之间来回传输流量。 That being said in rare and extreme cases due to performance a few business rules might need to be migrated to the Stored-Procedure side. 在罕见和极端情况下,由于性能的原因,可能需要将一些业务规则迁移到存储过程方面。 Make sure to document any exceptions to the architectural philosophy in multiple prominent places. 确保在多个显着位置记录架构理念的任何例外情况。

Stored Procedures are ideal for: 存储过程非常适合:

  • Creating reusable abstractions over complex queries; 在复杂查询上创建可重用的抽象;
  • Enforcing specific types of insertions/updates to tables (if you also deny permissions to the table); 对表执行特定类型的插入/更新(如果您还拒绝对表的权限);
  • Performing privileged operations that the logged-in user wouldn't normally be allowed to do; 执行通常不允许登录用户执行的特权操作;
  • Guaranteeing a consistent execution plan; 保证一致的执行计划;
  • Extending the capabilities of an ORM (batch updates, hierarchy queries, etc.) 扩展ORM的功能(批量更新,层次结构查询等)

Dynamic SQL is ideal for: 动态SQL非常适合:

  • Variable search arguments or output columns: 变量搜索参数或输出列:
    • Optional search conditions 可选的搜索条件
    • Pivot tables 数据透视表
    • IN clauses with user-specified values 带有用户指定值的IN子句
  • ORM implementations (most can use SPs, but can't be built entirely on them); ORM实现(大多数可以使用SP,但不能完全构建它们);
  • DDL and administrative scripts. DDL和管理脚本。

They solve different problems, really. 他们真的解决了不同的问题。 Use whichever one is more appropriate to the task at hand, and don't restrict yourself to just one or the other. 使用更适合手头任务的任何一个,并且不要仅限于其中一个。 After you work on database code for a while you'll start to get a more intuitive feel for these things; 在您处理数据库代码一段时间之后,您将开始对这些事情有一种更直观的感觉; you'll find yourself banging together some rat's nest of strings for a query and think, "this should really go in a stored procedure." 你会发现自己正在敲打一些老鼠的字符串嵌套以供查询,并认为“这应该存储在一个存储过程中。”

Final note: Because this question implies a certain level of inexperience with SQL, I feel obliged to say, don't forget that you still need to parameterize your queries when you write dynamic SQL . 最后说明:因为这个问题暗示了SQL的某种程度的缺乏经验,我不得不说, 不要忘记在编写动态SQL时仍然需要参数化查询 Parameters aren't just for stored procedures. 参数不仅适用于存储过程。

DS is more flexible. DS更灵活。 SP approach makes your system more manageable. SP方法使您的系统更易于管理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM