我想开发员工时钟输入和输出系统(网站)。
我担心两件事:
如果员工从昨天开始忘记'闹钟'并且今天有'时钟输入',那么它应该标记给经理。
工作人员可能会长时间工作,例如:时钟周一上午11:00到周二上午01:30(午夜后)。我不希望系统认为工作人员忘记了时钟..
如何解决此问题以及数据库设计可以改进哪些内容?
员工表:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
| password | varchar(50) | NO | | NULL | |
| hourly_rate | decimal(6,2) | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
计时表:
+----------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| staff_id | int(11) | NO | | NULL | |
| clock_in_date | datetime | NO | | NULL | |
| clock_out_date | datetime | NO | | NULL | |
+----------------+----------+------+-----+---------+----------------+
答案 0 :(得分:5)
你在这里开的大量虫子是什么?在为一家只做时钟系统的公司工作之后,这是我永远不想再做的事了!
我意识到我的回答非常具有概念性,并解决了问题正常范围之外的一些问题,但这是为了概述此类应用程序中的数据库设计和结构概念。这些信息来自我在该领域最近的专业发展,因此它不仅仅是假设,而是在实践中得到证实。
当你看这种类型的系统时,你最好最初使用指标作为标志,这通常是打击的数量与比较每个记录。比较1000名员工的每条记录并不是最好的事情!
例如,如果用户在24小时内有8次拳击(一天开始,早间休息开始,早间休息结束,午餐开始,午餐结束,下午休息开始,下午休息结束和一天结束),您可以确定在此期间不可能没有错过的拳和加班已经发生,但是如果在24小时期间(白天开始,早上休息开始,早上休息结束,午餐开始,午餐结束,下午休息)有7次拳击一天的开始和结束)你知道缺少一拳,这个人忘记了当天的时间。请注意下午休息结束的时间。
然而,这不是完全证明并且仅提供指示性参考,您将需要将换班时间表与拳击比较以确保实际上没有错过任何内容。因为午餐结束和下午休息结束都可能错过了6个拳,你可以设置你的代码来标记那些不是该员工的X个拳头的任何东西。标记为您时,然后在该期间对该员工进行实际比较,以确定实际发生的情况和遗漏的内容。
这并不意味着你不会比较所有记录,但事情是根据员工的数量,它可能会导致一些大问题在每个记录上进行精确比较,这是通常更好的大数员工使用2台服务器,1台仅用于数据收集和接口,第二台用于运行比较流程。
正如我所提到的,对于这种类型的应用程序并使用不同的计划,您还需要查看保持班次计划以进行比较。您将希望为每位员工保留一份填充记录,该记录将在班次开始之前和班次结束之后给予相同的时间。这意味着超过一段时间的加班可能性将是最小的。基本的公式非常简单:班次中的小时数--24小时/ 2 =时间填充
现在,您可以在该用户的班次计划之前和之后放置时间填充。但是你仍然需要处理换班,换班或超过24小时轮班。这是它真正变得棘手的地方。您将需要查看一个重叠时间(填充,移位和打孔)的表格,然后可以对照计划的任何未来调整进行协调,因为事实变化在考勤时间并不少见。
现在,您还需要保留病假和假期的缺席时间表,这些数据通常需要在打卡/打卡表中进行标记,因为这是您的比较。当为一段时间设置一个标志时,可以跳过记录进行比较,并在报告中留下一个注释,而无需运行其他操作来检查它。
几乎到了最后,请注意你需要忘记正常的日期/时间约定来衡量一系列变量吗?更不用说在多个日期有效地工作了?因此,通常最好只使用开始和结束时间dd / mm / YYYY hh:mm:ss,测量使用UNIX时间来计算已经过了多长时间。在说要审计时,大多数系统都需要一个“日期戳”记录,因此在发布报告时可能需要对此进行服务器端处理。
最后,我还建议保留一个结果表,这将为每个用户提供报告结果,这样当您想要提供历史记录时,您可以动态生成文档,但是您不必浪费处理能力进行比较每次请求报告时记录。
我希望这有帮助!
答案 1 :(得分:2)
从域名的角度来看,这不完全正确。
出于审核目的或故障排除,需要时钟输入或输出/打孔。 因此,您需要为所有员工存储个人打孔历史记录。
您的案例中的时钟表可以是派生数据。
时钟表应为
+----------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| staff_id | int(11) | NO | | NULL | |
| clock_type | int(1) | NO | | 0 | 0-in, 1-out |
| clock | datetime | NO | | NULL | |
+----------------+----------+------+-----+---------+----------------+
答案 2 :(得分:2)
我并没有真正看到您的设计存在问题,因为我发现问题的要求很差。您需要更好地定义管理员何时被更改以考虑多天的转变。也许最好的规则是,如果有人没有24小时计时或者他们试图再次计时,主管会收到通知。您可能还需要数据库上的触发器,如果时钟丢失,则不允许时钟输入。或者您可以允许时钟输入并将缺少的时钟发送给主管以便采取行动。
您特别需要的一件事是审核(一个单独的表),以便您可以在何时查看谁更改了记录。你想知道是谁更改了记录,以及在有关某人的时间的问题时旧的价值是多少。
时间计时(我假设他们将根据计时时间获得报酬)是一项需要严格内部控制的活动(在数据库级别而不是应用程序!如果您试图阻止,内部控件绝不能处于应用程序级别欺诈。)没有人应该直接访问该表。他们应该只能通过一个存储过程来改变,这些存储过程决定了他们能做什么。
您可能希望针对主管副非监督人员制定具体规则。一般而言,任何与时间相关的事情都应该允许事后由该人的主管更改。我会有一个强制执行此操作的触发器,只允许进入时间表的人更改数据中的时钟,然后才允许它为空。所有其他更改应来自此人的主管。因此,您可能需要一个表来存储组织结构,或者至少需要一个显示员工的主管人员的字段。
如果人们基于时钟和操作人员会变得更加沉默,那么您可能需要与您的会计人员及其审计人员核实最终确定业务规则。对于这种事情的内部控制可能非常复杂并且难以纠正。
我看到的一个设计问题是每小时费率列,这会随着时间的推移而变化,你会希望能够告诉它(特别是如果因某种原因,费率在付费期中间变化),所以我会打破这个到相关的表格。同样,需要严格执行此表的权限。没有人能够将人力资源人员输入小时费率字段。
答案 3 :(得分:1)
您的数据库设计似乎很好。它应该只记录进出时间。在应用程序的其他位置,您应该编写业务规则。 You may read this article on wikipedia关于分离问题。
答案 4 :(得分:1)
您需要在NULL
上允许clock_out_date
。这样,您可以在发生时记录签入,只需离开clock_out_date
NULL
即表示用户尚未签出。
如果您计划支持每个事件/天的多次入住/退出,那么您还需要在时钟表中添加一个事件/日ID列,以便您可以按事件/日分组签到。如您所述,日期不能用于分组跨越午夜的签到。我们使用event_id,但您可能需要payroll_date。
我对类似系统使用相同的时钟表结构。它已经生产了一年,我不会改变一件事。我们按UTC存储所有时间。
请注意,我们不会将此系统用于工资核算,并且薪资系统可能存在重要的审计要求。