基础设施:模型作为应用程序的外部以避免存储过程
我的想法:
出于各种原因,我绝对鄙视存储过程:成本、可扩展性和兼容性。
成本:我可以用一台好的 MySQL 服务器的成本获得 2-3 台好的轻量级 Web 应用程序服务器。成本
可扩展性:当然,我可以缓存查询结果,但是当使用存储过程时,我失去了更精细地缓存内容的机会,而且它将应用程序与始终使用 MySQL 联系在一起(谁有钱重写)
兼容性:在某些情况下,list_foo_widgetsByUser() 存储过程可能无法满足客户端 #123 的需求。修改list_foo_widgetByUser()的签名无异于自杀……所以我必须编写一个新的sproc cl123_list_foo_widgetByUser(),这样会导致疯狂或杀人的DBA。
我的解决方案:
将模型从应用程序的存储库中取出,并将它们放入外部存储库中。每个应用程序都会有一个指向外部存储库的 models/Base 子目录。然后在前面放置一个简单的工厂方法,例如 GetModel("FooWidgets"),它将返回 baseFooWidget 类作为实例或应用程序特定的子实例。这将允许单个应用程序继承 FooWidget 的类或与 Liquabase 等工具结合使用,从而实现更大的可变性。
我脑后的一个声音说这太简单了……我在这里错过了什么?
参考: 我知道 PHP Kohana 框架做了一些类似的事情,允许应用程序设计者用附加功能包装 Kohana 的基础库,如果 PHP 可以做到这一点,我看不出任何其他语言有问题。
My thoughts:
I absolutely despise stored procedures for various reasons: cost, scalability, and compatibility.
Cost: I can get 2-3 good light weight web application servers for the cost of one good MySQL server.
Scalability: Sure I can cache query results, but when using stored procedures I lose the opportunity for a much finer granularity of what can be cached plus it ties the applications to always using MySQL ( who's got the money to re-write the stored procedures from MySQL to something else? )
Compatibility: at some point list_foo_widgetsByUser() stored procedure might not fit the needs of client #123. It would be suicidal to modify list_foo_widgetByUser()'s signature... so then I'd have to write a new sproc cl123_list_foo_widgetByUser() and that way leads to maddness or a homicidal DBA.
My solution:
Rip the models out of the application's repository and put them into an external repo. Every application would then have a models/Base subdirectory that was point to an external repository. Then put a simple factory method in front like GetModel("FooWidgets") that would either return the baseFooWidget class as an instance or a application specific child instance. That would allow individual applications to inherit FooWidget's class or combined with some tool like Liquabase, allow for a bigger base of variability.
A voice in the back of my head says this is too easy...what am I missing here?
References:
I know for a fact that the PHP Kohana framework does something along these lines to allow application designers to wrap Kohana's base library with added functionality and if PHP can do it, I can't see any other language having a problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
摆脱存储过程是一个很好的想法,你的三点完全击中了要害。
另一方面,PHP 不容易允许结构化包装。我不是 PHP 爱好者(更多的是 C# / Java 爱好者),但解决这个问题的最佳方法是单独的数据库/域/访问/业务层。简而言之:
这是一个简化的概述。我不知道您的解决方案是否是这个意思,但这通常是这样的:关注点分离。如果更改数据库,只需更改映射即可。如果需要不同的结果集,只需更改访问层即可。
可以帮助您完成此过程的工具是 Hibernate(但您需要 JavaBridge),它是首选的 ORM 工具,但学习曲线有点陡峭。对于 PHP,Doctrine 似乎可以为您做很多事情。还存在其他工具。理想情况下,工具允许往返工程:如果您更改某些内容,则再次运行该工具(或更改某些内容)并且不会破坏应用程序。
It's an excellent thought to get rid of stored procedures, you hit the nail exactly with your three points.
PHP, on the other hand, doesn't easily allow structured wrapping. I'm not a PHP addict (more of a C# / Java guy), but the best way to tackle this is separate database/domain/access/business layers. In short:
This is a simplified overview. I don't know if you meant this with your solution, but this is usually the way it goes: separation of concerns. If you change the database, you only need to change the mapping. If you need different result sets, you only change the access layer.
Tools that can help you with this process are Hibernate (but then you need JavaBridge), it's the ORM tool of choice, but has a bit of a steep learning curve. For PHP, it seems that Doctrine can do the lot for you. Other tools exist as well. Ideally, a tool allows roundtrip engineering: if you change something, you run the tool again (or change something) and you don't break the application.