我正在考虑在Microsoft SQL Server 2008中设计一个带有计算列的表。这将是一个简单的计算,如(ISNULL(colA,(0))+ ISNULL(colB,(0))) - 就像一个总计。我们的应用程序使用Entity Framework 4。
我并不完全熟悉计算列,所以我很好奇其他人在适合使用它们时必须说什么,而不是其他实现相同结果的机制,例如视图或计算的实体列
我有什么理由不想在表中使用计算列吗?
如果我使用计算列,是否应该保留?我已经阅读了使用持久化而非持久化的不同性能结果,其中包含索引和非索引计算列here。鉴于我的计算看起来很简单,我倾向于说不应该坚持下去。
答案 0 :(得分:9)
根据我的经验,当它们可以在其他地方使用时,它们是最有用/最合适的,例如索引或检查约束,这有时需要保留列(物理存储在表中)。有关详细信息,请参阅Computed Columns和Creating Indexes on Computed Columns。
答案 1 :(得分:9)
如果您的计算列未保留,则每次访问时都会计算它。一个SELECT
。如果基于它的数据经常变化,那可能没问题。
如果数据不经常更改,例如如果你有一个计算列来将你的数字OrderID INT
变成一个人类可读的ORD-0001234
或类似的东西,那么肯定会使你的计算列保持不变 - 在这种情况下,该值将被计算并物理存储在磁盘上,以及对它的任何后续访问就像读取表中的任何其他列 - 不会一遍又一遍地重新计算。
我们也开始使用(并高度赞赏!)计算列从XML列中提取某些信息,并将它们作为单独的(持久的)列在表上显示。这使得查询这些项目的效率远远高于不断使用XQuery检索XML以检索信息的效率。对于这个用例,我认为持久计算列是加速查询的好方法!
答案 2 :(得分:1)
假设您有一个名为ProspectRanking的计算列,它是对几列中值的评估结果:ReadingLevel,AnnualIncome,Gender,OwnsBoat,HasPurchasedPremiumGasolineRecently。
我们还要说,您的大型公司中的许多分散部门都使用这些数据,并且他们都有自己的程序员,但您希望ProspectRanking算法由公司总部的IT集中管理,他们保持密切沟通与营销副总裁。我们还要说,经常调整算法以反映一些不断变化的条件,如利率或通货膨胀率。
如果管理前端客户端就像放牧猫一样,您希望计算成为后端数据库引擎的一部分而不是数据的客户端使用者。
如果你可以避免放牧猫,那就这样做。
答案 3 :(得分:1)
确保您只查询所需的列
我发现使用计算列非常有用,即使没有持久化,尤其是在MVVM模型中,您只获取该特定视图所需的列。只要你没有在计算列代码中放置性能较差的逻辑,你应该没问题。最重要的是,如果您正在使用该数据,那么无论如何都必须查找计算的(非持久列)。
何时达到效果
对于性能,您将查询范围缩小到行和计算列。如果你在计算列上放一个索引(如果允许已检查且不允许),我会谨慎,因为执行引擎可能决定使用该索引并通过计算这些列来损害性能。大多数情况下,您只是从连接表中获取名称或描述,所以我认为这很好。
不要暴力
使用大量计算列的唯一时间就是使用单个视图模型类来捕获所有列中的所有数据,包括计算的那些列。在这种情况下,您的性能将根据您选择的计算列数和数据库中的行数而降低。
ORM的计算列很棒。
对象关系映射器(如EntityFramework)允许您查询查询中的列的子集。使用LINQ to EntityFramework可以很好地工作。通过使用计算列,您不必使用每个模型类型的映射视图来混乱ORM类。
var data = from e in db.Employees
select new NarrowEmployeeView { Id, Name };
仅查询ID和名称。
var data = from e in db.Employees
select new WiderEmployeeView { Id, Name, DepartmentName };
假设DepartmentName是一个计算列,那么您将获得后一个查询的计算执行。
Peformance Profiler
如果使用性能分析器并对sql查询进行过滤,则可以看到实际上当不在select语句中时,将忽略计算列。
答案 4 :(得分:0)
如果您打算按该信息进行查询,则计算列可能是合适的。
例如,如果您要在UI中显示数据集。拥有计算列将允许您在仍允许对计算列进行排序和筛选的同时对页面进行分页。如果该计算列仅在代码中,则根据该值合理地对数据集进行排序或过滤以进行显示将更加困难。
答案 5 :(得分:-7)
计算列是业务规则,更适合在客户端而不是存储中实现它。数据库用于存储/检索数据,而不用于业务规则处理。事实上它可以做某事并不意味着你应该这样做。你也可以自由地跳过埃菲尔铁塔,但这将是一个糟糕的决定:)