我相信这个问题可以通过定义更明确的数据库模式来解决。通过使用更详细的数据库模式,您将能够在任何给定的时间范围内(不仅仅是上午和下午)找到任何可用的用户,如果您应该选择的话。它还允许您保留模板数据,同时不会用模板信息污染您的可用性数据(相反,您可以从模板表中选择以编程方式填写给定日期的可用性,然后可以由用户修改)。
我花了一些时间绘制这个问题的图表,并提出了一个模式结构,我相信它可以解决您指定的问题,并允许您以最少的模式更改来扩展您的应用程序。(为了使这更容易阅读,我在此建议答案的末尾添加了 SQL)
我还包含了一个示例 select 语句,它允许您使用任意数量的参数提取可用性数据。为了清楚起见,SELECT 在我的解释性文本的结尾处位于架构的 SQL 之上。请不要被选择吓倒,乍一看它可能看起来很复杂,但实际上是整个模式的映射(保存模板表)。(顺便说一句,我并不是说因为我怀疑你能理解它,我相信你能理解,但我知道许多程序员忽略了更复杂的数据库结构而对自己不利,因为它看起来过于复杂但分析时实际上比他们在程序中为获得相似结果而必须做的杂技要简单......关系数据库基于数学的一个分支这很好@准确,一致,&(相对)简洁,关联数据)。
一般使用:
(有关更多详细信息,请阅读 SQL CREATE TABLE 语句中的注释) - 填充 DaysOfWeek 表。- 使用您要跟踪的一些时间范围填充 TimeFrames 表(上午时间范围的开始时间可能为 00:00:00 和结束时间为 11:59:59,而下午可能有开始时间为 12:00:00 和结束时间23:59:59)-添加用户-添加要跟踪的日期(请参阅 SQL 中的注释以了解避免膨胀的想法以及此表的优点)-为每个用户填充模板表-生成默认可用性列表(与每个用户相关联的可用时间数据) - 向用户公开默认可用性,以便他们可以覆盖默认值注意:您还可以为参与添加一个可选表以与可用性相反(或者可能有一个更好的抽象可以包括这两个概念...)
免责声明:我没有花额外的时间来完全填充我的本地数据库并验证所有内容,因此可能存在一些我在图表中没有看到的弱点/错误......(对不起,我在这方面花费的时间比预期的要长得多,必须开始工作在一个过期的项目上完成)。虽然我在数据库结构和其他人创建了 12 年以上的数据库方面进行了相当广泛的工作,但我确信我并非没有错,但我希望 StackOverflow 上的其他人能够完善我可能包含的错误。
对于没有包含更多示例数据,我深表歉意。如果我在不久的将来有时间,我会提供一些,(考虑将 George、Fred 和 Harry 添加到 users 表中,在 Dates 表中添加一些日期,然后详细说明 George 和 Fred 在上学期间与 Harry 相比有多忙可用性、可用时间和时间框架表)。
SELECT 语句(注意:我强烈建议将其放入视图中……这样您就可以选择所需的任何列并在 WHERE 子句中添加所需的任何参数/条件,而不必每次都写出联接。 ..所以视图将不包括 WHERE 子句...只是为了说明这一点):
SELECT *
FROM Users Us
JOIN Availabilities Av
ON Us.User_ID=Av.User_ID
JOIN Dates Da
ON Av.Date_ID=Da.Date_ID
JOIN AvailableTimes Avt
ON Av.Av_ID=Avt.Av_ID
WHERE Da.Date='2014-01-03' -- whatever date
-- alternately: WHERE Da.DayOWeek_ID=3 -- which would be Wednesday
-- WHERE Da.Date BETWEEN() -- whatever date range...
-- etc...
DaysOfWeek 中的推荐数据(实际上是一个查找表):
INSERT INTO DaysOfWeek(DayOWeek_ID,Name,Description)
VALUES (1,'Sunday', 'First Day of the Week'),(1,'Monday', 'Second Day of the Week')...(7,'Saturday', 'Last Day of the Week'),(8,'AllWeek','The entire week'),(9,'Weekdays', 'Monday through Friday'),(10,'Weekends','Saturday & Sunday')
示例模板数据:
INSERT INTO Templates(Time_ID,User_ID,DayOWeek_ID)
VALUES (1,1,9)-- this would show the first user is available for the first time frame every weekday as their default...
,(1,2,2) -- this would show the first user available on Tuesdays for the second time frame
以下是推荐的架构结构:
CREATE TABLE `test`.`Users` (
User_ID
INT NOT NULL AUTO_INCREMENT ,
UserName
VARCHAR(45) NULL , PRIMARY KEY ( User_ID
) );
CREATE TABLE `test`.`Templates` (
`Template_ID` INT NOT NULL AUTO_INCREMENT ,
`Time_ID` INT NULL ,
`User_ID` INT NULL ,
`DayOWeek_ID` INT NULL ,
PRIMARY KEY (`Template_ID`) )
`COMMENT = 'This table holds the template data for general expected availability of a user/agent/person (so the person would use this to set their general availability)'`;
CREATE TABLE `test`.`Availabilities` (
`Av_ID` INT NOT NULL AUTO_INCREMENT ,
`User_ID` INT NULL ,
`Date_ID` INT NULL ,
PRIMARY KEY (`Av_ID`) )
COMMENT = 'This table holds a users actual availability for a particular date.\nIf the use is not available for a date then this table has no entry for that user for that date.\n(btw, this suggests the possiblity of an alternate table that could utilize all other structures except the templates called Engagements which would record when a user is actually busy... in order to use this table & the other table together would need to always join to AvailableTimes as a date would actually be in both tables but associated with different time frames).';
CREATE TABLE `test`.`Dates` (
`Date_ID` INT NOT NULL AUTO_INCREMENT ,
`DayOWeek_ID` INT NULL ,
`Date` DATE NULL ,
PRIMARY KEY (`Date_ID`) )
COMMENT = 'This table is utilized to hold actual dates whith which users/agents can be associated.\nThe important thing to note here is: this may end up holding every day of every year... this suggests a need to archive this data (and everything associated with it for performance reasons as this database is utilized).\nOne more important detail... this is more efficient than associating actual dates directly with each user/agent with an availability on that date... this way the date is only recorded once, the other approach records this date with the user for each availability.';
CREATE TABLE `test`.`AvailableTimes` (
`AvTime_ID` INT NOT NULL AUTO_INCREMENT ,
`Av_ID` INT NULL ,
`Time_ID` INT NULL ,
PRIMARY KEY (`AvTime_ID`) )
COMMENT = 'This table records the time frames that a user is available on a particular date.\nThis allows the time frames to be flexible without affecting the structure of the DB.\n(e.g. if you only keep track of AM & PM at the beginning of the use of the DB but later decide to keep track on an hourly basis you simply add the hourly time frames & start populating them, no changes to the DB schema need to be made)';
CREATE TABLE `test`.`TimeFrames` (
`Time_ID` INT NOT NULL AUTO_INCREMENT ,
`StartTime` TIME NOT NULL ,
`EndTime` TIME NOT NULL ,
`Name` VARCHAR(45) NOT NULL ,
`Desc` VARCHAR(128) NULL ,
PRIMARY KEY (`Time_ID`) ,
UNIQUE INDEX `Name_UNIQUE` (`Name` ASC) )
COMMENT = 'Utilize this table to record the times that are being tracked.\nThis allows the flexibility of having multiple time frames on the same day.\nIt also provides the flexibility to change the time frames being tracked without changing the DB structure.';
CREATE TABLE `test`.`DaysOfWeek` (
`DaysOWeek_ID` INT NOT NULL AUTO_INCREMENT ,
`Name` VARCHAR(45) NOT NULL ,
`Description` VARCHAR(128) NULL ,
PRIMARY KEY (`DaysOWeek_ID`) ,
UNIQUE INDEX `Name_UNIQUE` (`Name` ASC) )
COMMENT = 'This table is a lookup table to hold the days of the week.\nI personally would recommend adding a row for:\nWeekends, All Week, & WeekDays \nThis will often be used in conjunction with the templates and will allow less entries in that table to be made with those 3 entries in this table.';