我该如何处理数据库中的渐进状态代码?

时间:2011-10-05 17:05:52

标签: c# tsql data-structures

我正在为一个学术机构开展项目,我需要就解决这个问题的最佳方法提出建议。自从我进行任何传统的应用程序开发(接近五年)以来已经很长时间了。

大学管理部门最近修改了学院的学术标准政策。以前,政府只有三个状态代码,所以这不是一个大问题。但是,新政策有六个状态代码:

  1. 良好的信誉
  2. 学术关注
  3. 学术干预(1)
  4. 一次解雇
  5. 学术干预(2)
  6. 四期解雇
  7. 从这里开始,我将通过说cumGPA来说明termGPA和累积GPA来区分GPA。如果学生的 termGPA 低于2.0,并且导致他/她的 cumGPA 也低于2.0,则他/她将获得学术关注。一旦学术关注,学生可以通过以下方式完成以下三项任务之一。它们:

    1. 如果他们的termGPA和cumGPA升至2.0以上,则恢复良好状态。
    2. 如果他们的termGPA高于2.0,则保持当前状态,但他们的cumGPA保持在2.0以下。
    3. 如果termGPA和cumGPA都低于2.0,则转到下一个状态。
    4. 通常,我会通过编写一个控制台应用程序来处理这个过程,该应用程序迭代地处理每个学生并按照我的方式构建状态代码。但是,我们至少处理了8000名学生,大多数情况下每学期约有12,500名学生。

      此外,此政策必须在尚未指定的时间段内追溯应用(因为以前的学生可以返回大学,然后受新政策的限制),并且一旦我将学生纳入数据集,我必须回顾那个学生与大学的整个历史。我保守地猜测我会通过至少一百万的学生记录并计算每个学生的termGPA和滚动cumGPA。

      问题:

      1. 有没有办法在SQL中处理这个问题并避免使用游标?
      2. (假设答案为1.是“否”)我应该如何构建控制台应用程序?我应该在写入数据库之前创建一个大型集合并一次处理几千名学生,或者在每次处理每个学生之后更新数据库吗?
      3. 我是否对这个问题做了太大的讨论?
      4. 提前感谢任何见解和建议。


        编辑:根据对此处的答案的评论,我应该提供有关数据结构的更多信息以及我计算GPA的方式。

        我不能在我们的数据库中使用预先计算出的cumGPA值 - 我需要在每个渐进期结束时学生的cumGPA,如此(注意:我在下面列出了GPA值):

        ID      TermID  CumGpa  TermGPA TermNumber PolicyCode
        123545  09-10-2  2.08   2.08      1         GoodStanding
        123545  09-10-3  1.94   0.00      2         AcademicConcern
        123545  09-10-4  1.75   1.00      3         AcademicIntervention
        123545  10-11-2  1.88   2.07      4         AcademicIntervention
        123545  10-11-4  2.15   2.40      5         GoodStanding
        123545  11-12-1  2.30   2.86      6         GoodStanding
        

        问题在于,每个后续术语的状态代码都可能取决于前一个术语的状态代码 - Good Standing实际上是唯一没有的状态代码。

        据我所知,这意味着我必须在SQL中使用游标来获取每个学生最新的状态代码,这不是我感兴趣的东西,因为我为一个资金短缺的大学工作有三个数据库服务器:一个用于测试,两个服务器上有相同的数据(我们正在迁移到SQL Server 2008 R2)。

4 个答案:

答案 0 :(得分:0)

这很有趣。我认为你不必过分担心SQL性能。它将为您的应用程序运行相当快。我只是运行了一个愚蠢的小控制台应用程序来修复一个混乱,并一次插入15000条记录。花了大约5秒钟。

答案 1 :(得分:0)

首先,12 000条记录对于现在的数据库来说都不算什么,所以这不是你的概念。你应该专注于保持简单。看起来您的数据库将基于事件而被拒绝所以我建议使用触发器即:插入termGPA时的fisrt trriger - 更新cumGPA,cumGPA更新后的第二个 - 检查您的标准并更新状态(如果它们发生)。

答案 2 :(得分:0)

即使SQL的免费版本现在也可以处理高达10 GB的数据库。 12,500条记录很小。除了100万条记录之外,您应该通过每个学生或组来进行检查,以便清除事务日志。这可以在使用游标或控制台应用程序中完成。如果您可以在TSQL中执行计算,那么批量它们可能会比一次更快。不利的一面是批量越大的交易日志,因此有一个最佳点。如果计算对于TSQL而言过于复杂并且几乎与插入语句一样长(或更长),则可以在单独的线程上插入(或在单独的线程上计算),因此插入和计算是并行的。我这样做是一个应用程序,我解析文本中的单词 - 解析需要花费大量时间来插入单词。但我不会让它旋转多个theads。在SQL方面,它仍然必须维护索引并使用来自两个线程的插入来降低它的速度。只有两个线程,较快的线程等待较慢。您进行更新的顺序也很重要。如果按照聚簇索引的顺序进行处理,那么记录已经存在于内存中的可能性更大。

答案 3 :(得分:0)

我最终在C#中编写了一个控制台应用程序来处理这些状态代码。我的用户将初始状态更新要求更改为仅包括前两个术语,但是该过程有足够的边缘情况,我选择花时间编写更清晰,面向对象的代码,这些代码更容易回收(他说,希望这一政策成熟和改变。

此外,我最终不得不将此数据库部署到SQL 2005实例上,因此我无法使用表值参数。如果是的话,我会选择在处理每个学生之后才提交数据库,而不是在为每个学生处理每个学期之后。