【问题标题】:Best way to store attendance and get difference of time in MySQL?在 MySQL 中存储考勤并获得时间差异的最佳方法?
【发布时间】:2019-12-08 07:13:15
【问题描述】:

我对 SQL 语言和 MySQL 非常陌生。 我正在开发一个小时间和考勤应用程序IN PYTHON。它的作用是记录时钟的进出时间。然后计算工作小时数,并根据工作时间返回金额。

我想知道的是存储这些打卡和打卡时间的最佳方式以及如何获得时差?

到目前为止,我已经为员工制作了一张表格,如下所示:

CREATE TABLE employees (employee_id INT(50) AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(20), 
last_name VARCHAR(25), 
age INT(80), 
mobile_number VARCHAR(16), 
national_id VARCHAR(15), 
guardian_national_id VARCHAR(15), 
email_id VARCHAR(150), 
password VARCHAR(255), 
join_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP);

这里的join_date 是该员工的创建,其余的我猜是不言自明的。

我想到了 2 件事。要么制作两张单独的桌子,一张用于打卡,一张用于打卡。然后计算并返回在 Python 中工作的时间。为此,我不知道如何在这些表中验证employee_id。我是使用INNER JOIN 还是FOREIGN KEY

或者,我可以只有一张表包含打卡和打卡列,但我仍然不知道如何验证员工 ID。

我知道start_time 会是TIMESTAMP DEFAULT CURRENT_TIMESTAMP,但是当我去更新下班时间时,这不会再次更新吗?

我迷路了。请帮帮我,这很痛苦。我在任何地方都找不到我的答案。 谢谢,

【问题讨论】:

  • 您可以在employee_id, clock_in_time, clock_out_time 上拥有第二张桌子,然后您可以在employee_id 上加入您的两张桌子。您还可以执行employee_id | action | timestamp 之类的操作,其中操作为"Clock In""Clock Out"(目前),然后您只需要在其中一个操作发生时插入表格。有几种方法可以构建此架构。
  • 我不认识杰克。我之前写了一个非常详细的问题,但后来我的笔记本电脑关机了,所有进度都丢失了。我非常沮丧。请原谅我。
  • 无论您做什么,都不要制作两张单独的桌子(一张用于打卡,一张用于外出)。这些事件的一张桌子会很有意义。不管怎样,你必须把employee_id 作为这个额外表中的一列,因为这是你关键的一部分。
  • @JNevill 感谢您的回复。您能否更详细地描述作为答案?如果它有效,我会接受它。欣赏它:)
  • @JNevill 我明白了。所以只用一张桌子。我将如何设置这个表(CREATE TABLE)?而且我不知道“动作”是 MySQL 的一部分吗?

标签: mysql sql mysql-python


【解决方案1】:

这里的方法是创建一个单独的表来存储开始和结束时间。您可以将它们存储为整数(并使用 Unix 时间戳),或者更好的是,将它们存储为 MySQL 日期时间类型 - 这种方式你可以在MySQL中使用函数,比如TIMESTAMPDIFF

CREATE TABLE shifts (
  employee_id INT(50),
  start datetime NOT NULL, 
  finish datetime NULL,
  duration int(11) GENERATED AS (TIMESTAMPDIFF(MINUTE, start, end)) STORED NULL,
  PRIMARY KEY(employee_id, start)
);

然后,使用对雇员表中employee_id 列的外键引用将每一行链接到相应的雇员。

CREATE INDEX employee ON shifts(employee_id);

ALTER TABLE shifts
ADD FOREIGN KEY fk_employee_shifts(employee_id)
REFERENCES employees(employee_id)
ON DELETE CASCADE
ON UPDATE CASCADE

以上可能是伪代码,因为我晚上喝啤酒:)

通过使用存储的虚拟列来保存 TIMESTAMPDIFF 值,我使表格更加智能。这样您就不需要将数据拉入您的应用程序来计算每个会话的长度;让数据库完成工作!请注意时区...

【讨论】:

  • 嗨!非常感谢。就像我说的,我对 SQL 还很陌生。你能告诉我start datetime NOT NULL, 是什么意思吗?就像“日期时间”作为数据类型一样?我们不应该为此使用 TIMESTAMP 吗? STORED NULL 是什么意思?在(TIMESTAMPDIFF(MINUTE, start, end) 行中,我们还没有指定结束列?除此之外,ALTER TABLE shifts ADD FOREIGN KEY fk_employee_shifts(employee_id) REFERENCES employees(employee_id) ON DELETE CASCADE ON UPDATE CASCADE 这一切都在我脑海中浮现。
  • INT(50) 也不是一个东西。事实上,INT 声明后括号中的数字(几乎)完全没有意义——但就啤酒而言,这是公平的竞争。
  • "start datetime NOT NULL" 定义了一个名为 'start' 的列,它属于 'datetime' 类型,不能为空,即为空。您可以使用时间戳,是的,但除非您需要那种精确度,否则我会坚持使用日期时间。 “STORED NULL”实际上是列定义中的两个独立元素:“STORED”告诉 MySQL 将生成的值存储在虚拟列“duration”中,否则每次查询表时都会重新计算该字段。 “NULL”只是说我们希望该字段为空,直到您在“finish”中输入值之前这是正确的......
  • ...剩下的 SQL 告诉数据库,名为“shifts”的表中的数据与“employees”表相关,并由“employee_id”列链接。
  • @Strawberry 你说 INT(50) 不是一个东西是完全正确的......我很确定 MySQL 在幕后把它变成了 BIGINT。
猜你喜欢
  • 1970-01-01
  • 2020-05-30
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多