0

我有以下表格

父表

ds_id(pk)   / state
-------------------------
        1.       /    valid
        2.       /    invalid

子表

d_id(pk)  /   ds_id(fk)  /  approve
-----------------------------------------
  1.     /       1.        /       false
  2.     /       1.        /       true
  3.     /       2.        /       false
  4.     /       2.        /       false

state如果子表中的其中一个子表的已批准列设置为 true,则父表中的列应更改为有效

我想找到最简单最有效的方法来根据其子项计算和设置状态列。

我正在使用 SQL Server 2008。

状态的改变必须是即时的。

预计该系统将有几千名父母,每人大约有 5 个孩子。

孩子们更有可能被更新

4

1 回答 1

1

您没有提供足够的信息来决定什么是“最佳”方法。两个基本思想是在子值更改时更新父项中的数据或在查询时从子项中汇总。

以下是在这些方法之间做出决定的一些问题:

父级读取与子级更改的比率是多少?如果子值每改变一千次就读取一次父值,那么动态地(在查询时)执行它可能更有效。如果每次子值更改时都会读取父值一千次,那么静态执行(使用更新)可能更有效。

改变孩子和从父母那里阅读的预期响应时间是多少?

我们在谈论多少数据?如果以数百行测量子数据,则可能不值得努力提高查询效率。

而且,建议的数据对于自动更新来说有点尴尬。如果一个孩子从approved = true 变为false,那么会发生什么?您必须阅读所有其他子项才能在父项中设置值。另一种方法是保留已批准子项的计数,然后对该值进行逻辑处理。一种方法是使用父表中的计算列:

create table . . .
    stats as (case when ApprovedCount > 0 then valid else invalid end)

作为对自动更新的一般观察,我认为触发器相对难以维护。使用触发器似乎并不“简单”。相反,我将有一个用于更新子表的存储过程,并使用该存储过程进行更新和任何其他逻辑。

[回复评论] 建议的数据很小。孩子和父母很可能都适合一个数据页。除非您要进行事务处理基准测试,否则您可以在查询父母时即时进行计算:

select p.id, (case when count(*) > 0 then valid else invalid end) as validness
from parent p left outer join
     child c
     on c.parentid = p.parentid and c.accepted = true
group by p.id

这会非常快。而且,如果您一次只寻找一个父母,那将非常非常快。当然,如果您预先计算该值,它会快一点。然而,相对于维持价值的复杂性,速度的提高不太可能很重要。

于 2012-08-19T20:32:10.647 回答