我使用.NET创建了一个数据访问层。在我更新数据库记录的任何地方,我都使用了
行的SQLUPDATE Customer SET FirstName =:FirstName,LastName =:LastName,Address1 =:Address1,Address2 =:Address2,.... etc
这意味着记录中的每个字段都会更新,即使只有一个字段可能已更改。一位同事已经对此提出异议,说我们应该只更新一个字段,如果它已经改变,引用带宽作为问题 - 比如我们有160个字段,然后我们传递160个字段的数据。我想如果我检查一个值是否已经改变,我可以节省Web服务器和数据库服务器之间的带宽,并且纯粹基于实际更改的值生成sql。
在Web服务器和客户端之间,我现在需要传递旧值和新值,所以我可能会在那里增加带宽(但是无论如何ASP.NET已经这样做了,我不确定我们是否可以切换那一点关闭所以这可能不是问题。)
那么最佳做法是什么?我是否应该担心更新数据库记录中的所有字段?我如何仅更新已更改的字段?
编辑10月29日添加:有谁知道NHibernate的作用?也许这是一个争论时间来学习如何这样做的理由。
答案 0 :(得分:6)
过早优化是万恶之源。
有没有理由,你真的有带宽问题吗?
根据我的经验,跟踪更改可能需要大量工作(即需要维护大量代码),具体取决于实现方式。有一些优雅的方式,但我认为你做的很好,除非有一些证据支持改变。
如果您计划实施一些自定义形式的更改跟踪,我肯定不会与数据库“聊天”。首次从数据库中提取对象并在本地进行比较时,在本地制作对象的副本。
答案 1 :(得分:4)
也许与带宽一样,您可能还需要考虑多用户争用。根据应用程序的设计方式,更新所有字段的方法可能会导致问题。
如果有两个用户同时加载记录编号1.用户A将LastName从“Smith”更改为“Smythe”并保存。用户B然后将Address1从“The Street”更改为“Any Street”并保存。
根据您的方法,第二次保存也会将LastName再次还原为“Smith”(因为这就是用户B加载它时的情况)。
遵循这个逻辑结论,您还需要在保存(可能是某种时间戳)时进行其他检查,以确保数据库中的值是您认为的。
答案 2 :(得分:2)
假设您在Web服务器和数据库服务器之间有一个千兆位网络连接,那么您必须更新每秒100兆字节数据 的区域内的somwhere,这样才能接近是一个问题。这大约是每天8太字节。我的猜测是你没有更新这么多数据,所以这可能不是问题。
答案 3 :(得分:1)
网络带宽在各个层面都在不断提高。除非你合法地在某个地方遇到瓶颈,否则不要担心。即便如此,我的预感是增益足够小,你会花费更多的时间和精力(和风险)来尝试优化你的更新,而不是在其他地方找到性能改进。
答案 4 :(得分:1)
好吧,你要么按照你已经完成的方式(有效,每次都传递每个字段),要么花时间为每个字段生成定制的SQL,然后为每个字段传递一个SQL语句,或者生成一个巨大的字段一点一点的SQL动态只包含更新的字段(如果你犯了错误,SQL注入的风险)。通过在参数化存储过程中进行更新并仅传递字段值而不是名称,可以更好地节省带宽。
除非带宽确实是个问题,否则我认为你没有问题。无论如何,SP路线是更好的选择。
答案 5 :(得分:1)
表中的PK不是其中一个字段吗?你真的在更新PK吗?外键怎么样?你也在更新这些吗?
问题不在于带宽。至少隔离记录的非关系元素,只更新该组(不包括PK和外键)。
答案 6 :(得分:1)
我发现自己处于同样的境地。我编写了自己的轻量级ORM / DAL来连接到一个非最佳设计的数据库,即包含200多个字段的表。
我发现尝试更新行的所有字段确实存在开销,而不仅仅是那些已更改的字段。
在我的情况下,我能够通过对ORM属性使用智能“setter”来解决问题,这将记录是否尝试修改特定字段。这意味着当我将对象提交回数据库时,我可以发出一个SQL UPDATE语句,该语句仅引用标记为已修改的字段。
N.B。 对于SELECT语句,最佳实践要求您应明确引用要返回的字段,而不是使用“SELECT * FROM”。据说,这是出于性能/带宽的原因,因此逆转对UPDATES来说是有意义的。