优化数据库结构

dun*_*unc 8 javascript php mysql

我正在为我们的VLE开发奖励系统,它使用三种独立的技术 - 用于大多数客户端/显示处理的JavaScript,用于与数据库通信的PHP和用于数据库本身的MySQL.

我附上了三张"交易"表的截图.它的结构,一些示例记录和其细节的概述.

前提是工作人员奖励学生表现良好的行为等.这可能意味着30名学生的课程一次获得积分.工作人员每周限制300点,目前有大约85名员工正在访问该系统(这可能会上升).

我现在这样做的方式,每个"交易"都有一个"Giver_ID"(工作人员授予点的成员),一个"Recipient_ID"(接收积分的学生),一个类别和一个理由.这样,每当一名员工发出30分时,我就会在数据库中放入30行.

这似乎在早期工作,但在三周内我已经在数据库中有超过12,000个事务.

此时它变得有点复杂.在"指定点"页面(附带的另一个屏幕截图)上,当教师点击其中一个班级或搜索单个学生时,我希望显示学生的积分.我目前在我的系统上执行此操作的唯一方法是执行" SELECT * FROM 'transactions'"并使用以下JS将所有信息放入数组中:

var Points = { "Recipient_ID" : "0", "Points" : "0" };

function getPoints (data) {
    for (var i = 0; i < data.length; i++) {
        if (Points[data[i].Recipient_ID]) {
            Points[data[i].Recipient_ID] = parseInt(Points[data[i].Recipient_ID]) + parseInt(data[i].Points);
        } else {
            Points[data[i].Recipient_ID] = data[i].Points;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在内部登录系统时,这似乎足够快.但是,在外部登录时,此过程大约需要20秒,因此在您单击/搜索几次之前,不会显示学生的分数值.

我在PHP中使用以下代码来访问这些事务:

function getTotalPoints() {
    $sql = "SELECT * 
        FROM `transactions`";

    $res = mysql_query($sql);
    $rows = array(); 
    while($r = mysql_fetch_assoc($res)) {
        $rows[] = $r;
    }

    if ($rows) {
        return $rows;
    } else {
        $err = Array("err_id" => 1);
        return $err;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,我该如何实际接近这个?全文索引; 也许学生表的总分值会在每次输入交易时得到更新; 大众交易(即多个同一类别的同一个点的学生)被分组到一个数据库行?这些都是我所想到的,但我会爱上比我更有DB知识的人来提供启发.

示例记录 示例记录

表结构 表结构

表概述 表概述

分配点界面 分配点界面

提前谢谢了.

Tom*_*Tom 3

你的问题是你的查询:

SELECT * FROM `transactions`
Run Code Online (Sandbox Code Playgroud)

随着数据集变大,加载时间会更长,并且需要更多内存来存储。而是确定您具体需要哪些数据。如果是针对特定用户:

SELECT SUM(points) FROM `transactions` WHERE Recipient_ID=[x]
Run Code Online (Sandbox Code Playgroud)

或者,如果您想要所有学生的所有金额:

SELECT Recipient_ID, SUM(points) AS Total_Points FROM `transactions` GROUP BY Recipient_ID;
Run Code Online (Sandbox Code Playgroud)

要加快对特定字段的选择,您可以为该字段添加索引。这将加快选择速度,尤其是随着表的增长。

ALTER TABLE `transactions` ADD INDEX Recipient_ID (Recipient_ID);
Run Code Online (Sandbox Code Playgroud)

或者,如果您想显示以下位置中所有条目的分页列表transactions

SELECT * FROM `transactions` LIMIT [page*num_records_per_page],[num_records_per_page];

e.g.: SELECT * FROM `transactions` LIMIT 0,25 ORDER BY Datetime; # First 25 records
Run Code Online (Sandbox Code Playgroud)