MySQL多条件预订系统

3

我正在编写一个PHP/MySQL应用程序来跟踪预约情况,但是我在根据选择的任意条件查找下一个可用预约时遇到了困难。

CREATE TABLE IF NOT EXISTS `appointments` (
`appointmentID` int(9) unsigned NOT NULL AUTO_INCREMENT,
`patientID` int(9) unsigned NOT NULL,
`apptTitle` varchar(50) NOT NULL,
`apptDate` date NOT NULL,
`apptTime` time NOT NULL,
`apptLength` int(4) NOT NULL,
`apptStatus` varchar(25) NOT NULL,
`physician` int(9) unsigned NOT NULL,
`apptType` varchar(30) NOT NULL,
`apptInvoice` varchar(10) NOT NULL,
`apptNotes` varchar(1000) NOT NULL,
`apptLocation` varchar(25) NOT NULL,
`apptReminder` int(4) NOT NULL,
 PRIMARY KEY (`appointmentID`),
 KEY `patientID` (`patientID`),
 KEY `physician` (`physician`),
 KEY `apptStatus` (`apptStatus`),
 KEY `apptLocation` (`apptLocation`),
 KEY `apptType` (`apptType`)
 ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
附注:您会注意到我的“类型”、“地点”和“状态”字段是varchar类型,并且它们链接到查找表。因此,我存储的是实际值,而不是每个项目的ID(因此每个查找表只是字段值作为PK,没有ID列)。我这样做是为了减少将来的连接,但我知道这有点非规范化。如果这是错误的方法,请随时让我知道,除了知道我以后不必进行这些连接之外,我还没有找到令人信服的证据。在更新时有“on update”逻辑,因此如果进行更改,则会更新约会表中的值。

目标是显示所有可用的预约时间段(这些是15分钟的时间段,因此12:00am-12:14:59am、12:15:00am-12:29:59am等等)。默认情况下,我只会显示未来X天(可能是14天)的所有预约时间段,没有限制。但是,如果患者想看特定的医生,我希望限制一下,或者如果医生只需要咨询,我可以将位置限制在咨询室,而不占用检查室。或者,我们知道需要安排X个月的随访,因此我可以开始显示经过该时间的日期。或者,患者只能在周末或下午5点后预约。

从我所了解的情况来看,我需要某种预约“时间段”表,但是我不确定如何构建该表,以便可以将其与现有预约进行比较并找到我的时间段。

我对MySQL有一些了解,也总是喜欢接受挑战,但我似乎无法理解如何做到这一点。我寻找类似的问题,但没有一个真正涵盖我正在寻找的定制量,并且我无法弄清楚如何调整该代码使其适用于我。希望有人能帮助我理解我需要如何实现这个想法!

提前感谢您的帮助!


编写一个存储过程,动态生成一个临时的时间段表格,将现有的约会与该表进行匹配,并根据您的条件进行过滤。显示后,删除临时表。 - Alex Monthy
1个回答

0

我认为为未来的“减少连接”做计划不是一个好理由。你应该更担心你正在创建的未来的头痛问题(对你或其他人),比如你所说的,像类型、位置和状态这样的字段可能与你的时间段查询相关的元数据(类型“需要在X个月内跟进”,位置“是考试室”), 所以你最终还是需要连接。即使只是为了找到一个时间段的可用位置,如果我理解正确,你肯定需要连接。

我猜“时间段”是指5分钟的时间跨度?例如:12:00-12:04:59,12:05-12:09:59等?

就像Alex上面说的,你需要一个“所有可能的时间段”表来进行左连接(无论是临时的还是永久的)。

我可能会将其永久地存储在磁盘上,因为它被频繁引用。听起来有些浪费,但另一种选择是每次动态生成它,这也不是很好。

然后要查找医生的可用时间段,可以使用以下代码:

SELECT a.* 
FROM slots AS a
LEFT JOIN appointments AS b
ON a.startDate BETWEEN b.apptDate AND DATE_ADD(b.apptDate,INTERVAL b.apptTime MINUTE)
AND b.physician=1234 
WHERE b.appointment IS NULL

如果这听起来像是你想要的正确方向,我可以尝试帮助你解决其他更复杂的问题。


是的,它是15分钟的时间段。我已经更新了原始问题。我喜欢你关于为什么我不应该去规范化的推理。我还没有考虑到其他元数据方面,感谢您的评论。至于时间段表,那个表需要有多“大”?从你的查询中,看起来它必须是每天的每个时间段。将表分成几年,这样它们就不会成为庞大的表,这有意义吗?再次感谢您的评论! - bandgeekndb
是的,它应该是每个可能被预订的时间段。我会按照需要的时间表不断添加(例如,每天添加未来3年内缺失的时间段)。看起来很大,但对于10年来说只有<3MB(350k日期时间行),你会惊讶于MySQL处理它的效率。当然,在使用时只连接所需内容:如果一个人想要预订下周的某些东西,你的连接将限制该范围。 - gllen
你对“减少连接”和将表按年份拆分的评论告诉我你不相信MySQL能够完成它的工作。你真的应该更加信任它,保持表设计简单,并且有信心如果/当性能问题出现时,你会有很多选择。 - gllen
PS:刚注意到示例查询中我把表反了,我对其进行了编辑 :) - gllen
gllen,最近我有点被拉走了,但我又回到了代码中,并且我想接受你提供的关于一些查询的额外帮助。继续讨论的最佳方式是什么?我的联系信息在我的个人资料中。谢谢! - bandgeekndb
在您的个人资料中没有看到联系信息。如果您仍需要帮助,我已经将我的电子邮件地址添加到了“关于我”中。 - gllen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接