繁体   English   中英

Laravel:为时间表设计一个数据库表

[英]Laravel: Designing a DB table for schedules

我正在创建一个应用程序,其中一个功能将是人员调度程序 - 你知道,为员工创建当前和下个月的工作时间表,在哪里写轮班、病假、休假等。

现在我使用 JSON 格式设计了一个结构,如下所示:

在此处输入图片说明

这里, schedule字段以 JSON 格式包含相应员工的相应月份的时间表,如下所示: [{"date": "2020-10-01", "shift": "B"},{"date": "2020-10-02","shift": "B"}, ...]

这种结构有效并选择它,因为它不会因每天乘以员工数量而使数据库过载大量条目。 但是我意识到我将无法搜索某些字段,我还需要在我的 PHP 和 JS 中计算总工作时间(和其他时间),这意味着服务器的大量工作和负载。

第二个版本是制作一个只有id (int), staff_id (int), date (date), value (string) ,其中将存储每个员工每天的班次 (value)。 但我可能会假设它会很重,比方说,10 名员工(至少 3650 个条目)使用一年后。 但这将使搜索数据、制作统计报告、进行小时计算(仅使用 JS)变得更容易,并且将简化服务器端代码。

staff_id将包含员工的 ID,我将使用 Eloquent 关系访问该数据。

对于作为专家的您来说,哪个版本更好,为什么(谈到应用程序性能)? DB条目数量不会对其产生重大影响吗?

PS 让我们暂时忽略导出功能,但我知道我只能导出这个表,而只能使用它的第 2 版。

PPS 我使用 MySQL(用于开发环境)和 MariaDB(用于登台和生产)。

谢谢!

避免在 RDBMS 中以 JSON 存储结构化数据

MySQL 等是 RDBMS(关系数据库管理系统)。 如果可以按列定义表结构,则在使用 RDBMS 时应始终避免将数据存储在 JSON 中 原因是与 JSON 相关的数据库查询可能较慢(需要解析 JSON 并且因为 JSON 列可以存储非结构化数据)。

使用 JSON 等效格式存储数据也将占用更多空间也不足为奇,因为您每行都重复键"date""shift" 这也会对网络负载造成影响,我将在后面讨论。 MySQL 存储数据的方式与 CSV 是“可比的”。 您可以在这个站点上尝试我刚刚在 Google 搜索中找到的CSVJSON ,并观察 JSON 消耗了多少空间。

此外,您在查询方面的灵活性可能会降低,并且无法利用 Laravel 的某些功能(非常重要)

我建议将时间表存储在另一个表中,形成一对多(时间表到班次)的关系。

然后你就可以做这样的事情,假设你的屏幕截图中的表被称为schedules并且schedule列被转换为一个名为shifts的表。

class Schedule extends Model {
  function shifts() {
    return $this->hasMany(Shift::class);
  }
}
$staffSchedule = Schedule::whereStaffId(1)->first();
$numOfShifts = $staffSchedule->shifts()->count(); // You can query build off of `shifts()`
$shifts = $staffSchedule->shifts; // Magic property that returns a collection of shifts

如果可能,使用 SQL 计算所有内容,然后使用服务器端 Web 框架。 客户端计算是最后的手段。

原因如下:

  • 服务器被认为是更强大的机器。

  • 返回中间结果需要大量网络流量。

    如果您的客户端必须通过慢速 Internet 下载 MB 数据,您的应用程序将会变慢。 优化通过网络传输尽可能少的数据,而不是尝试将计算卸载到客户端。

  • 从数据库结果中补充 Laravel 模型会消耗更多不必要的计算资源。

    如果您要处理大量行加上错误代码,有时甚至会达到 PHP 内存限制

  • PHP 的计算速度可能比 SQL 慢。

    通常,您可能想要处理几个关系,这种数据库访问开销确实会减慢计算速度。 例如,您收到了 n 个模型并且想要计算它们的每个班次。

     // Just a toy example. No one would realistically do this. $schedules = Schedules::where(/*...*/)->get(); // 1 SQL call returns n objects $totalShiftCount = $schedules->map( fn (Schedule $schedule) => $schedule->shifts()->count() )->sum(); // n SQL calls. BAD! Avoid scaling SQL calls to number of rows.

Laravel 会一一等待该行的 SQL 结果,并在运行下一个 SQL 之前构造一个表示该行数据的模型。 正是这种开销减慢了执行速度

如果您想计算某些东西,请避免使用 Laravel 模型,但需要访问数千行,否则不会使用模型。 如果您无法使用 Laravel 查询构建器形成查询,请使用原始表达式形成一个。 努力编写 1 个 SQL 查询来完成您需要的一切。

相信我,使用 Laravel 模型而不是纯 SQL 计算某些东西会慢很多 将不必要的数据传递给客户端通常会对您的服务器造成更大的损失,因为您发送的是 unicode 编码的 JSON 数据,而不是自己在服务器上进行计算。


不确定我是否已经回答了您的所有问题,但如果您有任何希望我澄清的内容,请随时在下面发表评论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM