6

我们正在为我们的新内部应用程序建立一个新的框架和开展业务的方式。我们当前的设计要求所有安全逻辑都应该由我们的数据库处理,所有信息(我的意思是全部)都将通过存储过程进出数据库。

理论上,数据访问层从存储过程请求信息并将身份验证传递给数据库。数据库确定用户的角色/权限并决定是否执行任务(无论是检索数据还是进行更新)。

我想这意味着更少的数据库事务。一次调用数据库。如果安全性在我们的数据访问层,这将需要 1 次数据库调用来确定用户是否具有适当的权限,然后需要 1 次单独的数据库调用来执行操作。

一方面,我发现 SQL 管理工作室完全缺乏 IDE。我主要担心的是,我们最终将不得不在存储过程中维护一些令人讨厌的业务逻辑,以获得一些非常小的性能提升。

现在,我们将 LINQ 用于我们的 ORM。它看起来轻巧快速,但最重要的是,它真的很容易快速开发。

维护成本是否值得性能提升?我们是否自欺欺人地认为甚至会有明显的性能提升?还是我们只是在为自己做噩梦?

我们的环境:

  • 内部的非关键业务应用程序
  • C#/ASP.NET 3.5
  • 视窗 2003
  • 微软 SQL 服务器 2005
  • 35 个中型 Web 应用程序,大约 500 个用户
4

8 回答 8

8

不要那样做。当“数据库大师”决定去另一家公司时,我们最近有一个非常糟糕的经历。程序中所有逻辑的维护简直太可怕了!!

是的,您将获得一些性能改进,但这不值得。事实上,在内部应用程序中,性能甚至不是一个大问题。在好的服务器上投入更多的钱。它会得到回报的。

于 2008-09-11T05:30:19.957 回答
3

不幸的是,没有“一个真正的答案”。您必须做出的选择取决于多种因素,例如:

  • 团队对给定解决方案的熟悉程度(即,如果他们中的大多数人擅长编写 SQL,则可以在数据库中,但是如果他们中的大多数人更喜欢 C#,则应该在代码中)
  • 各党派的“政权”
  • ETC

在任何方向都没有决定性的优势(正如您所说的性能提升是最小的),要记住的一件事是 DRY(不要重复自己)原则:不要重新实现功能两次(在代码中和DB),因为让它们保持同步将是一场噩梦。选择一种解决方案并坚持下去。

于 2008-09-11T05:35:27.153 回答
2

你可以做到,但开发和维护它是一个巨大的痛苦。从从事几乎所有业务逻辑都编码在存储过程中的项目的人那里得到它。

为了安全起见,ASP.NET 内置了用户和角色管理,因此您可能会节省访问数据库的次数,但那又如何呢?作为交换,处理和调试系统和验证错误变得更加烦人,因为它们必须从数据库中冒出来。

单元测试要困难得多,因为可用于单元测试 sprocs 的框架还不够发达。

正确的 oop 和域驱动设计几乎是不可能的。

如果有的话,性能提升将很小。我们在这里谈到了这个。

我建议,如果您想保持作为开发人员的理智,那么您必须竭尽全力将数据库保留为持久层

于 2008-09-11T05:31:34.430 回答
2

恕我直言:

应用服务层 -> 应用逻辑和验证
应用数据层 -> 数据逻辑和安全
数据库 -> 数据一致性

你迟早会被 sproc 方法所困扰,我已经学会了这一点。
Procs 非常适合需要大量性能的一次性操作,但 CRUD 部分是数据层的工作

于 2008-09-11T19:25:34.503 回答
1

这完全取决于您的情况,最好不要走 SP 路线并以 DDD 方式做所有事情(在代码中创建域模型并使用它)。

但是,如果您的数据库不仅被您的应用程序使用,而且被许多人使用,那么您可能应该考虑使用 Web 服务。无论如何,数据库应该只能通过执行业务规则的一层来访问,否则您最终会得到“脏”数据,并且事后清理数据比事先编写一些业务规则要痛苦得多。一个好的数据库应该设置检查约束和索引,所以不管你喜欢与否,它都会有一些业务规则。

如果您必须处理数百万和数十亿条记录,您将很高兴有一个优秀的 DB-guy 为您解决问题。

于 2008-09-11T07:34:33.077 回答
1

存储过程通常是安全的胜利。简化应用程序和数据库之间的关系可以减少可能出错的地方;将业务逻辑连接到数据库的代码中的错误往往是安全问题。因此,您的 DBA 将事情锁定到存储过程并没有错。

将应用程序锁定到存储过程的另一个好处是,应用程序堆栈的数据库连接可以将其权限锁定到特定的存储过程调用,仅此而已。

让 DBA 参与应用程序的安全逻辑的好处是,不同的应用程序功能和角色可以在数据库中划分为视图,因此即使需要动态 SQL 和通用选择语句,SQL 漏洞造成的损害可以约束。

当然,另一方面是失去了灵活性。与 DBA 就存储过程参数的不断协商相比,ORM 的开发显然要快得多。而且,随着这些存储过程的压力越来越大,这些过程本身越来越有可能求助于动态 SQL,这与应用程序组合的 SQL 一样容易受到攻击。

这里有一个快乐的中间地带,你应该尝试找到它。我最近从事的项目从非常可怕的 SQL 注入问题中解救出来,因为 DBA 已经为“最小权限”仔细配置了数据库、它的连接和它的存储过程,因此任何一个数据库用户都只能访问他们的内容需要知道。

显然,当您在应用程序逻辑中编写 SQL 代码时,请确保您始终使用参数化准备好的语句,您正在清理您的输入,您注意国际化输入(有很多很多方式可以说单一-quote over HTTP),并且当输入对于列宽而言太大时,您要注意数据库的行为。

于 2008-09-11T19:22:24.700 回答
0

我的观点是应用程序本身应该处理身份验证和授权。在数据库方面,您应该只根据需要处理数据加密。

于 2008-09-11T05:37:48.987 回答
0

我过去构建了基于存储过程的应用程序。在您的情况下,可能有一种方法可以在数据库层保持身份验证并将您的业务逻辑放在 C# 中。使用视图来限制数据(您只能看到您有权访问的行)。这些视图可以在 LINQ 中像表一样轻松使用。您将更新设置为使用存储过程进行。

这允许 linq、C# 中的业务逻辑以及数据库中控制对数据的访问的通用身份验证层。

于 2008-09-11T05:55:52.937 回答