Laravel:为时间表设计数据库 table
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)
制作一个 table,其中将存储每位员工每天的班次(值)。但我可能会假设,在 10 名员工(至少 3650 个条目)使用一年之后,它会变得相当沉重。但这将使搜索数据,统计报表,计算小时(仅使用JS)变得更加容易,并且会简化服务器端代码。
staff_id
将包含工作人员的 ID,我将使用 Eloquent 关系访问该数据。
对您来说,作为专家,哪个版本更好,为什么(谈到应用程序性能)?数据库条目数量不会对其产生重大影响吗?
P.S。让我们暂时忽略导出功能,但我知道我只能导出这个 table,而只能使用这个的版本 2。
P.P.S。我正在使用 MySQL(用于开发环境)和 MariaDB(用于暂存和生产)。
谢谢!
避免在 JSON
中的 RDBMS 中存储结构化数据
MySQL 等是 RDBMS(关系数据库管理系统)。如果可以根据列定义 table 结构,则在使用 RDBMS 时应始终 避免将数据存储在 JSON 中。原因是 JSON 相关的数据库查询可能较慢(需要解析 JSON 并且因为 JSON 列可以存储非结构化数据)。
使用 JSON 等效格式存储数据也将花费更多 space 也就不足为奇了,因为您重复了密钥 "date"
和 "shift"
每一行。这也会对网络负载造成影响,我将在稍后讨论。 MySQL 存储数据的方式与 CSV 类似。您可以在 CSVJSON 我刚刚在 Google 搜索中找到的网站上尝试,并观察 space JSON 消耗了多少。
此外,您可能 查询的灵活性较低 并且 将无法利用某些 Laravel 功能(真的很重要).
我建议将时间表存储在另一个 table 中,形成一对多(时间表到轮班)关系。
然后你就可以做这样的事情,假设你的屏幕截图中的 table 被称为 schedules
并且 schedule
列被转换为 table 称为 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 查询构建器构建查询,请使用 raw expressions 构建一个查询。努力 编写 1 SQL 查询 来满足您的所有需求。
相信我,使用 Laravel 模型而不是纯粹的 SQL 计算某些东西会 慢很多 。将不必要的数据传递给客户端通常会对您的服务器造成更大的损失,因为您发送的是 unicode 编码的 JSON 数据,而不是您自己在服务器上进行计算。
不确定我是否已经回答了您的所有问题,但如果您有任何希望我澄清的内容,请随时在下方发表评论。
我正在创建一个应用程序,它的功能之一是人员调度程序 - 你知道,为员工创建当前和下个月的工作时间表,在哪里写班次、病假、工作日-关闭等
现在我用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)
制作一个 table,其中将存储每位员工每天的班次(值)。但我可能会假设,在 10 名员工(至少 3650 个条目)使用一年之后,它会变得相当沉重。但这将使搜索数据,统计报表,计算小时(仅使用JS)变得更加容易,并且会简化服务器端代码。
staff_id
将包含工作人员的 ID,我将使用 Eloquent 关系访问该数据。
对您来说,作为专家,哪个版本更好,为什么(谈到应用程序性能)?数据库条目数量不会对其产生重大影响吗?
P.S。让我们暂时忽略导出功能,但我知道我只能导出这个 table,而只能使用这个的版本 2。
P.P.S。我正在使用 MySQL(用于开发环境)和 MariaDB(用于暂存和生产)。
谢谢!
避免在 JSON
中的 RDBMS 中存储结构化数据MySQL 等是 RDBMS(关系数据库管理系统)。如果可以根据列定义 table 结构,则在使用 RDBMS 时应始终 避免将数据存储在 JSON 中。原因是 JSON 相关的数据库查询可能较慢(需要解析 JSON 并且因为 JSON 列可以存储非结构化数据)。
使用 JSON 等效格式存储数据也将花费更多 space 也就不足为奇了,因为您重复了密钥 "date"
和 "shift"
每一行。这也会对网络负载造成影响,我将在稍后讨论。 MySQL 存储数据的方式与 CSV 类似。您可以在 CSVJSON 我刚刚在 Google 搜索中找到的网站上尝试,并观察 space JSON 消耗了多少。
此外,您可能 查询的灵活性较低 并且 将无法利用某些 Laravel 功能(真的很重要).
我建议将时间表存储在另一个 table 中,形成一对多(时间表到轮班)关系。
然后你就可以做这样的事情,假设你的屏幕截图中的 table 被称为 schedules
并且 schedule
列被转换为 table 称为 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 查询构建器构建查询,请使用 raw expressions 构建一个查询。努力 编写 1 SQL 查询 来满足您的所有需求。
相信我,使用 Laravel 模型而不是纯粹的 SQL 计算某些东西会 慢很多 。将不必要的数据传递给客户端通常会对您的服务器造成更大的损失,因为您发送的是 unicode 编码的 JSON 数据,而不是您自己在服务器上进行计算。
不确定我是否已经回答了您的所有问题,但如果您有任何希望我澄清的内容,请随时在下方发表评论。