我真的需要看一些关于当前公认的企业应用程序设计范例的优点的诚实,深思熟虑的辩论.
我不相信实体对象应该存在.
实体对象我指的是我们倾向于为我们的应用程序构建的典型事物,如"人","帐户","订单"等.
我目前的设计理念是这样的:
(注意:我还使用Java EE构建了企业应用程序,java人员请用等价替换我的.NET示例)
我不是反OO.我为不同的目的写了很多类,而不是实体.我承认我编写的大部分类都是静态助手类.
我不是在建造玩具.我在谈论跨多台机器部署的大型高容量事务应用程序.Web应用程序,Windows服务,Web服务,b2b交互,您可以为其命名.
我使用过OR Mappers.我写了几个.我使用过Java EE堆栈,CSLA和其他一些等价物.我不仅使用它们,而且还在生产环境中积极开发和维护这些应用程序.
我已经得出了经过实战考验的结论,即实体对象正在阻碍我们,如果没有它们,我们的生活会变得如此简单.
考虑这个简单的例子:你得到一个关于你的应用程序中某个页面不能正常工作的支持调用,可能其中一个字段没有像它应该那样持久化.使用我的模型,分配给发现问题的开发人员正好打开3个文件.ASPX,ASPX.CS和带有存储过程的SQL文件.该问题可能是存储过程调用缺少的参数,需要几分钟才能解决.但是对于任何实体模型,您总是会启动调试器,开始逐步执行代码,最终可能会在Visual Studio中打开15-20个文件.当你走到堆栈底部时,你忘记了你的起点.我们一次只能在头脑中保留这么多东西.软件非常复杂,无需添加任何不必要的图层.
开发复杂性和故障排除只是我抱怨的一个方面.
现在让我们谈谈可扩展性.
开发人员是否意识到每次编写或修改与数据库交互的任何代码时,他们都需要对数据库的确切影响进行彻底的分析?而不仅仅是开发副本,我的意思是模仿生产,所以你可以看到你现在需要的对象的附加列只是使当前的查询计划失效,而在1秒内运行的报告现在需要2分钟,因为您在选择列表中添加了一个列?事实证明,您现在需要的索引是如此之大,以至于DBA将不得不修改文件的物理布局?
如果让人们通过抽象让物理数据存储距离太远,他们就会对需要扩展的应用程序造成严重破坏.
我不是狂热者.我可以确信我是否错了,也许我是,因为Linq对Sql,ADO.NET EF,Hibernate,Java EE等有如此强烈的推动.请通过您的回答思考,如果我遗漏了一些东西我我真的想知道它是什么,为什么我应该改变我的想法.
[编辑]
看起来这个问题突然再次激活,所以现在我们有了新的评论功能,我直接评论了几个答案.感谢回复,我认为这是一个健康的讨论.
我可能应该更清楚我正在谈论企业应用程序.我真的不能评论一个在某人的桌面或移动应用程序上运行的游戏.
有一点我必须在顶部提出以回应几个类似的答案:正交性和关注点分离经常被引用作为实体/ ORM的理由.对我来说,存储过程是我能想到的关注点分离的最好例子.如果您不允许除了通过存储过程之外的所有其他数据库访问,理论上您可以重新设计整个数据模型而不破坏任何代码,只要您维护存储过程的输入和输出即可.它们是按合同编程的完美示例(只要您避免"select*"并记录结果集).
询问那些已经在这个行业工作了很长时间并且使用过长期应用程序的人:在数据库存在的时候,有多少应用程序和UI层已经出现了?当有4个或5个不同的持久层生成SQL来获取数据时,调整和重构数据库有多难?你什么都不能改变!ORM或任何生成SQL的代码都会锁定您的数据库.
我正在编写一个rake任务,在Rails/ActiveRecord之外执行一些数据库工作.
有没有办法获得当前环境中的数据库连接信息(主机,用户名,密码,数据库名称)database.yml?
我想得到它所以我可以用它来连接这样......
con = Mysql.real_connect("host", "user", "pw", "current_db")
Run Code Online (Sandbox Code Playgroud) 我有兴趣了解数据库引擎的工作原理(即它的内部).我知道CS中教授的大多数基本数据结构(树,哈希表,列表等)以及对编译器理论的非常好的理解(并且实现了一个非常简单的解释器)但我不明白怎么去关于编写数据库引擎.我已经搜索了关于这个主题的教程,我找不到任何教程,所以我希望别人可以指出我正确的方向.基本上,我想了解以下信息:
以及可能与此相关的任何其他主题.它不一定是磁盘上的数据库 - 即使内存数据库也没问题(如果它更容易),因为我只想学习它背后的原理.
非常感谢您的帮助.
我刚刚开始使用外键第一次使用外键,我想知道是否有一个标准的命名方案可用于它们?
鉴于这些表格:
task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)
Run Code Online (Sandbox Code Playgroud)
任务具有Notes,任务由用户拥有,用户拥有Notes.
在这种情况下如何命名三个外键?或者,它甚至是否重要?
更新:这个问题是关于外键名称,而不是字段名称!
您能否指出替代数据存储工具并提供充分的理由来使用它们而不是旧的关系数据库?在我看来,大多数应用程序很少使用SQL的全部功能 - 看看如何构建一个无SQL的应用程序会很有趣.
在多个课程,书籍和工作中,我看到将文本字段定义为VARCHAR(255)作为"短"文本的默认类型.有没有什么好的理由经常选择长度为255,而不是一个漂亮的圆数?在有充分理由(无论今天是否适用)的情况下,过去的某个时间是坚持吗?
当然,我意识到,如果你以某种方式知道字符串的最大长度,那么更严格的限制会更理想.但是如果你使用VARCHAR(255)可能表示你不知道最大长度,那只是它是一个"短"字符串.
注意:我发现这个问题(VARCHAR(255)V TINYBLOB v TINYTEXT),它表示,VARCHAR(Ñ)需要Ñ 1个字节的存储空间用于Ñ <= 255,Ñ 2个字节的存储对的Ñ > 255.这是唯一的原因吗?这似乎有点武断,因为与VARCHAR(256)相比,你只能保存两个字节,你可以通过声明VARCHAR(253)轻松地保存另外两个字节.
我的要求是:
其他信息:
选项:
使用StringValue1,StringValue2创建一个大表... IntValue1,IntValue2,...等我讨厌这个想法,但如果有人能告诉我它比其他想法更好,为什么会考虑它.
创建一个动态表,根据需要按需添加新列.我也不喜欢这个想法,因为除非你索引每一列,否则我觉得性能会很慢.
创建一个包含UDFName,UDFDataType和Value的表.添加新的UDF时,生成一个View,它只提取该数据并将其解析为指定的任何类型.不符合解析标准的项返回NULL.
创建多个UDF表,每种数据类型一个.所以我们有UDFStrings,UDFDates等的表.可能和#2一样,并且只要添加新字段就自动生成View
XML数据类型?我之前没有使用过这些,但已经看过它们了.不确定他们是否会给我我想要的结果,尤其是性能.
别的什么?
您可以使用以下两种方法从EF中删除数据库中的项目.
第一个是EntityCollection第二个,第二个是ObjectContext.
什么时候应该使用?
一个优先于另一个吗?
Remove()返回a bool并DeleteObject()返回void.
不可重复读和幻读之间有什么区别?
我已经阅读了维基百科的隔离(数据库系统)文章,但我有一些疑问.在下面的例子中,会发生什么:不可重复的读取和幻像读取?
交易A.SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
1----MIKE------29019892---------5000
Run Code Online (Sandbox Code Playgroud)
交易B.
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
交易A.
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Run Code Online (Sandbox Code Playgroud)
另一个疑问是,在上面的例子中,应该使用哪个隔离级别?为什么?
database oracle transactions transaction-isolation isolation-level
database ×10
sql ×4
orm ×2
activerecord ×1
c# ×1
entities ×1
environment ×1
foreign-keys ×1
mongodb ×1
nosql ×1
oracle ×1
ruby ×1
theory ×1
transactions ×1
types ×1
varchar ×1