我正在为我们的员工设计轮班日历。这是我迄今为止正在使用的表:
CREATE TABLE IF NOT EXISTS `Shift` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`accountId` smallint(6) unsigned NOT NULL,
`grpId` smallint(6) unsigned NOT NULL,
`locationId` smallint(6) unsigned NOT NULL,
`unitId` smallint(6) unsigned NOT NULL,
`shiftTypeId` smallint(6) unsigned NOT NULL,
`startDate` date NOT NULL,
`endDate` date NOT NULL,
`needFlt` bit(1) NOT NULL DEFAULT b'1',
`needBillet` bit(1) NOT NULL DEFAULT b'1',
`fltArr` varchar(10) NOT NULL,
`fltDep` varchar(10) NOT NULL,
`fltArrMade` bit(1) NOT NULL DEFAULT b'0',
`fltDepMade` bit(1) NOT NULL DEFAULT b'0',
`billetArrMade` bit(1) NOT NULL DEFAULT b'0',
`billetDepMade` bit(1) NOT NULL DEFAULT b'0',
`FacilityId` smallint(6) unsigned NOT NULL,
`FacilityWingId` mediumint(9) unsigned NOT NULL,
`FacilityRoomId` int(11) unsigned NOT NULL,
`comment` varchar(255) NOT NULL,
`creation` datetime NOT NULL,
`lastUpdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`lastUpdateBy` mediumint(9) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
我希望能够在日历上显示(以不同的颜色)是否已收到某一天的时间表。
我的第一个想法是创建一个单独的表,并按天列出每个员工的单独条目,T/F。但是,对于每个员工,整个月从单独的查询返回的数据量肯定是巨大且低效的。
第二个想法是以某种方式将信息放入此 Shift 表中,并带有分隔符 - 然后用 PHP 对其进行分解。愚蠢的想法。
正如前面所暗示的,我想您自己也意识到了,将数据序列化为单列或使用某种其他形式的分隔字符串会导致打包和解包中的计算效率低下,以及未来严重的维护问题。
堆更好的是获得正确的数据结构,即正确规范化的表。毕竟,MySQL 相当擅长处理这些结构。
您无需为每位员工撤回每条线路。如果您将它们放在一起,您可以按员工和日期对结果集进行“分组”,甚至可以通过(例如)提取工时摘要来使其成为潜在有用的结果。零结果或空结果将不显示时间表,总小时数可能会以其他方式有所帮助。
如果您一次提取一名员工和一个日期,那么您的应用程序结构可能需要查看,但您可以使用 SQL LIMIT 关键字最多提取一条记录,然后测试是否有返回。