应用程序“智能”应该驻留在数据库中多少?

时间:2009-01-21 06:49:30

标签: database

我最近注意到一种趋势,人们正在越来越多地处理数据库和应用程序。有些人认为这对我来说是荒谬的极端。

我见过应用程序设计不仅禁止使用存储过程,还禁止在数据库中强制执行任何类型的约束(这包括主键,外键,唯一和检查约束)。我甚至看到过只需要使用数据库中存储的一种数据类型的应用程序,即varchar(2000)。不允许使用DateTime和数字类型。事务和并发也在数据库外部处理。

有没有人见过这类应用成功实施?我所处理的两个实现都是以这种方式实现的,具有各种数据完整性和并发性问题。任何人都可以解释这种趋势,将数据(逻辑,处理,约束)移出数据库吗?它背后的动机是什么?这是我想象的东西吗?

13 个答案:

答案 0 :(得分:8)

首先,我真的希望没有PKs和FK以及合理数据类型的数据库没有趋势。这真的是一个悲剧。

但是肯定有一大批开发人员喜欢在他们的应用程序中使用逻辑而不是存储过程。我同意Riho的主要原因是:通常,DBA管理数据库,这意味着开发人员必须经历一系列管理开销 - 获得DBA的批准 - 以便创建和更新存储过程。程序员本质上喜欢控制他们的世界,并且“按他们的方式”做事。

还有一些有效的技术原因:

  1. 用于开发存储过程的SQL(例如T-SQL)的过程扩展传统上缺乏用户定义的数据类型,可调试性,可移植性以及与外部系统的互操作性 - 所有质量都有助于开发可靠的大型软件。 (而且笨拙的语法无济于事。)
  2. 软件版本控制(例如svn)适用于管理甚至非常大的代码库,但管理数据库架构更改是一个更难的问题,并且支持不太好。每个认真的商店都对其应用程序代码库使用版本控制,但许多仍然没有任何严格的系统来管理他们的数据库;因此,存储过程可能很容易陷入一个无法解决的“黑洞”,使编码人员感到紧张。
  3. 我个人认为,核心业务逻辑越接近数据越好,特别是如果有多个代理访问数据库(或将来可能会这样做)。这是一个令人遗憾的历史人工制品,T-SQL及其类似弱语言,导致“数据和逻辑应该分离”这一观念的兴起。我的理想世界是每个业务规则都封装在数据库强制执行的约束中,并且所有不一致快速失败

答案 1 :(得分:6)

我喜欢将逻辑排除在数据库之外。我倾向于避免存储过程和触发器。但是,我总是使用正确的数据类型,键,标记和约束。我看到它的方式是数据库是一个数据库,应用程序是应用程序。数据库应该保持您的数据正确有效地存储,而应用程序应该拥有逻辑。也许我从来没有遇到需要存储过程或触发器的情况;因此从未倾向于使用它们来解决问题。但对我来说,给逻辑提供数据库的主页对我来说似乎“混乱”;我宁愿控制应用程序本身的所有内容。

答案 2 :(得分:4)

这一趋势源于软件技术行业主要由人类居住和驱动,因而受到趋势和非理性行为的影响。要了解今天发生的事情,需要在数据库历史中有一些观点,以及它们与编程语言的并行开发。

简要回答这个可能会被低估的答案:SQL是数据库语言世界的IE6。它破坏了关系模型的许多规则 - 换句话说,它有点像计算器不正确地执行乘法,并且没有减运算符。 SQL不够完整,无法成为真正的解决方案。它从未在原型阶段之外开发,并且从未打算用于工业环境。但后来被oracle天真地使用,结果证明它是一个“杀手级应用程序”,SQL成为行业标准,而不是技术上优越的竞争对手,其余的都是历史。 SQL的语法基于一组命令行表格数据处理工具和COBOL。充满了错误,不一致以及没有数学或逻辑基础的混杂的专有版本和功能,导致一种情况,即不清楚到底是什么。

我认为你必须谈论的趋势是最近ORM的激增:错误的和错误的思考试图修补SQL的明显缺陷。数据库触发器和过程是另一种错误,试图修补SQL的问题。

如果历史以合乎逻辑的顺序发挥作用,那么你的问题的答案就很简单:只要遵循关系模型的规则,一切都会自行解决。遗憾的是,关系模型的规则并不完全适合当前基于SQL的DBMS,因此不幸的是,某些应用程序级别的摆弄,触发器或其他任何愚蠢的补丁都是必要的,并且它最终成为主观意见的问题,而不是推理论证,你使用愚蠢的黑客。

所以真正的答案是尽可能地关注关系模型,然后在剩下的时间里捏造它。如果您是唯一使用db的人,则将逻辑放在应用程序中,并且需要将所有源代码保存在版本库中。如果多个应用程序可能使用数据库,请将数据库作为防弹并且自给自足 - 这里的主要目标是确保数据保持一致。

答案 3 :(得分:3)

最终,数据库以及如何连接到它是“持久性API” - 数据库中有多少,应用程序中有多少是特定于应用程序的。但重要的是,API 边界负责生成或使用正确的数据。

我个人更喜欢应用程序中的瘦访问层和数据库中的sprocs / PKs / FK,以强制执行事务正确性并启用API版本控制。这也允许其他应用程序修改数据库而不会破坏数据模型。

如果我看到另一个白痴使用* SELECT * FROM blah *我会用Uzi疯狂......: - )

答案 4 :(得分:3)

“数据库应该保持您的数据正确有效地存储,而应用程序应该拥有逻辑” - Nelson LaQeut在另一个答案中。

这似乎是问题的症结所在:所有“逻辑”都属于应用程序而不属于数据库。但“逻辑”是什么意思?有各种各样的“逻辑”,其中一些属于一个应用程序,一些,我想说,更好地放在数据库中。

我认为大多数开发人员会同意(当然?)基本数据完整性(如主键和外键)属于数据库。对更复杂的数据完整性逻辑的一致性较低 - 即使是简陋但有用的检查约束在一般情况下也很糟糕。

应用程序阵营看到数据库“仅仅”是存储“属于”其应用程序的数据的地方。数据库阵营(我所在的位置)将应用程序视为“仅仅”一个(可能是当前唯一的)“属于”数据库的数据用户 - 或者更确切地说属于该业务并且托管< / strong>用于数据库的业务(DBMS =数据库管理系统)。

如果你的应用程序中所有的数据逻辑都被束缚了,那么当应用程序需要在最新的时髦范例中重写时会发生什么(或者你认为J2EE是最后的例子)?正如Tom Kyte经常说的那样,it's all about the data

答案 5 :(得分:2)

数据库是应用程序不可或缺的一部分,但每个人都以不同的方式解释。孤立它们绝对是一个明智的举动,但这并不意味着你绕过他们在编程中所做的事情。正确的数据类型和主键引用是良好的数据库设计的重要组成部分,在此基础上可以构建一个好的应用程序。

答案 6 :(得分:2)

虽然我个人认为数据库应该有足够的智能来保护自己,但有些人不理解数据库不是愚蠢的服务,想想,而且不要错误地提醒你,数据和逻辑应该是分开的。现在在很多情况下,数据和逻辑的分离是一个强大的工具,但是大多数数据库已经为我们提供了原子性,冗余,处理,检查等的可靠实现......并且很多时候它就属于它所属的地方,但是这些服务及其API在供应商之间有所不同,许多应用程序员认为值得尝试在应用程序层实现这类内容,以避免将自己与特定的数据库层联系起来。

答案 7 :(得分:1)

我不能说我看到了一个“趋势”,用可怕的数据库设计创建糟糕的应用程序。编程就像任何其他学科一样,会有人不会学习工具或者只是想偷工减料。我甚至和一个不“信任”数据库的人交谈过。你描述的应用就像你说的那样,荒谬的噩梦。不要遵循这些“趋势”。

答案 8 :(得分:1)

我仍然喜欢在SQL server中使用存储过程和函数。它为应用程序增加了更多的灵活性。它也有性能优势。一般来说,我认为将所有内容都放在应用程序中并不是一个好主意。

答案 9 :(得分:1)

我认为那些创建没有索引或单个VARCHAR(2000)专栏的数据库的“开发人员”只是艺术专业人士,他们首次尝试进入高价IT世界。 没有人,即使只有一点点的IT教育,也会建立这种数据库结构。

我能理解将逻辑排除在格式良好的数据库之外的原因。通常,进行更改非常耗时(您必须说服数据库管理员进行更改,以及随附的所有繁文缛节)。如果业务逻辑在您的程序中,那么它只取决于您。

答案 10 :(得分:1)

在数据库中使用约束,但对于任何复杂的逻辑,我会将其放在数据访问层中,或者使用标准的对象关系映射(ORM)工具,如Hibernate / NHibernate。

人们普遍认为这会影响表现;基于存储过程是预编译的视图,但必须在每次调用时编译“原始”查询。但是,我主要在SQL Server 2005/2008中工作,这非常有效地处理'原始'参数化查询,缓存已编译的查询路径以便将来调用数据库。这意味着在SQL Server下,存储过程的性能与参数化SQL查询之间基本没有区别。

丢失存储过程的唯一缺点是,如果您非常精细地拥有数据库安全权限,并且要在数据库登录级别强制执行安全性。

答案 11 :(得分:1)

我有一个简单的哲学。

  • 如果需要保持数据库安全并处于一致状态,请确保在数据库中执行此操作

我也尝试在那里保留很多其他东西,在我的世界中,更新客户端的数据库比更新应用程序更容易......

基本上我尝试将数据库视为伪对象。我可以调用的一堆方法等,但我不希望应用关注内部数据存储的细节。

答案 12 :(得分:0)

根据我的经验,将任何应用程序逻辑放在数据库总是会产生WTF。无论数据库程序员有多聪明,数据库如何先进,它总是最终成为一个错误。相反的问题是“我的C#代码应该多久使用自己的平面文件结构和查询语言来管理关系数据”,答案(几乎)始终永远不会

我认为数据库应该用于数据存储,这是它擅长的。