php - 优化数据库结构

标签 php javascript mysql

我正在为我们的 VLE 开发一个奖励系统,它使用三种不同的技术 - 用于大多数客户端/显示处理的 JavaScript、用于与数据库通信的 PHP 以及用于数据库本身的 MySQL。

我附上了“交易”表的三个屏幕截图。它的结构、一些示例记录及其详细信息的概述。

前提是工作人员会为学生的良好行为等奖励积分。这可能意味着一次给 30 名学生的类(class)打分。员工每周有 300 点的限制,目前大约有 85 名员工访问该系统(这可能会增加)。

我目前的做法是,每个“交易”都有一个“Giver_ID”(授予积分的员工)、一个“Recipient_ID”(获得积分的学生)、一个类别和一个原因。这样,每次工作人员发出 30 分时,我都会将 30 行放入数据库中。

这似乎很早就奏效了,但在三周内我的数据库中已经有超过 12,000 笔交易。

在这一点上,它变得有点复杂。在“分配分数”页面(附上另一个屏幕截图)上,当老师点击进入他们的类(class)或搜索个别学生时,我希望显示学生的分数。我目前可以在我的系统上执行此操作的唯一方法是执行“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;
        }
    }
}

在内部登录系统时,这似乎工作得足够快。但是,在外部登录时,此过程大约需要 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;
    }
}

所以,我的问题是,我实际上应该如何处理这个问题?全文索引;也许是一张学生表,其中包含每次输入交易时都会更新的总分值;大量交易(即不止一名学生在同一类别中获得相同分数)分组到一个数据库行中?这些都是我考虑过的事情,但我希望有比我拥有更多数据库知识的人来提供启发。

示例记录 Example records

表结构 Table structure

表格概览 Table overview

分配点数界面 Assign Points interface

非常感谢。

最佳答案

您的问题是您的查询:

SELECT * FROM `transactions`

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

SELECT SUM(points) FROM `transactions` WHERE Recipient_ID=[x]

或者,如果您想要所有学生的所有总和:

SELECT Recipient_ID, SUM(points) AS Total_Points FROM `transactions` GROUP BY Recipient_ID;

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

ALTER TABLE `transactions` ADD INDEX Recipient_ID (Recipient_ID);

或者,如果您想显示 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

关于php - 优化数据库结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7650332/

相关文章:

PHP $_GET 问题

mysql - 关于如何完成特定MySQL JOIN的建议

JavaScript : Parameter Passed Is "Not Defined"

php - MySQL 使用 mysqli_real_escape_string 转义单引号

PHP ob_get_length 似乎返回不正确的值

javascript - 需要禁用内联 Fancybox 画廊的循环 - 循环 : false and cyclic: false not working

javascript - 我可以使样式应用于文件中定义的第一个类以外的类吗?

Javascript - 在一个页面上打开窗口,然后在另一页面上关闭它

php - 建立与CakePHP数据库的连接时出错

mysql - 外键的值为 NULL