草庐IT

php - 计划在PHP/MySQL中使用模板和替代内容进行搜索

coder 2023-10-06 原文

我正在寻找有关相当复杂的搜索算法的一些建议/帮助。任何有关相关技术等的文章将不胜感激。

背景

简而言之,我正在构建一个应用程序,该应用程序允许用户在任何给定的一天内设置其“可用性”。用户首先设置一个通用可用性模板,该模板允许他们说:

Monday - AM   
Tuesday - PM  
Wednesday - All Day  
Thursday - None  
Friday - All Day

因此,该用户通常在星期一上午,星期二下午等可用。

架构:
id  
user_id  
day_of_week  (1-7)(Monday to Sunday)
availability

然后,他们可以手动覆盖特定日期,例如:
2013-03-03 - am  
2013-03-04 - pm  
2013-03-05 - all_day

架构:
id
user_id
date
availability

这一切都很好-我正在生成一个日历,该日历结合了模板和替代项,并允许用户修改其可用性等。

问题

现在,我需要允许管理员用户搜索具有特定可用性的用户。因此,管理员用户可以使用日历来选择所需的日期和可用性,然后点击搜索。

例如,找到我可用的用户:
2013-03-03 - pm
2013-03-04 - pm
2013-03-05 - pm

搜索过程必须使用模板化的可用性和替代来搜索可用的用户,然后返回最佳结果。理想情况下,它将返回所有时间都可用的用户,但是在没有单个用户可以匹配日期的情况下,我需要提供可以合并的用户的组合。

我知道这是一个非常复杂的问题,我不是在寻找完整的答案,也许只是一些指导或与潜在相关技术的链接等。

我尝试过的

目前,我有一个中途的解决方案。我要捕获所有可用的用户,遍历每个用户,并在该循环中,遍历所有必需的日期,并在用户未达到必需的日期时立即中断。显然,这是非常不可扩展的,并且只返回“完美匹配”。

可能的解决方案

汇总表全文搜索

我考虑过创建一个具有以下架构的单独表:
user_id
body
body字段将填充有Users模板的天数和替代值,因此示例记录如下所示:
user_id: 2
body: monday_am tuesday_pm wednesday_pm thursday_am friday_allday 2013-03-03_all_day 2013-03-03_pm

然后,我会将用户搜索查询转换成类似的格式。因此,如果用户正在寻找在2013年3月19日(全天)和2013年3月20日(下午)有空的人,我会将其转换为字符串。

首先,由于3月19日是星期二,我将其转换为tuesday_allday,与20日相同。因此,我最终得到:
tuesday_allday wednesday_pm 2013-03-19_allday 2013-03-20_pm

然后,我将对我们的汇总表进行全文搜索,并返回一个“加权”结果集,然后可以遍历并进一步查询。

我不确定这在实践中如何工作,所以这就是为什么我问是否有人可以使用我可以使用的技术或相关文章的任何链接。

最佳答案

我相信可以使用定义更完善的数据库架构来解决此问题。
如果需要的话,通过使用更详细的数据库模式,您将能够找到任何给定时间范围内的可用用户(而不仅仅是am&pm)。
它还将允许您保留模板数据,而不用模板信息污染可用性数据(相反,您可以从模板表中进行选择,以编程方式填写给定日期的可用性,然后用户可以对其进行修改)。

我花了一些时间来图解这个问题,并提出了一个架构结构,我相信它可以解决您指定的问题,并允许您以最少的架构更改来发展您的应用程序。
(为使阅读更容易,我在建议的答案末尾添加了SQL)

我还提供了一个示例select语句示例,该语句允许您使用任意数量的参数提取可用性数据。
为了清楚起见,在我的解释性文本的末尾,SELECT位于模式上方的SQL的上方。
请不要被选择所吓倒,它乍看起来可能很复杂,但实际上它是对整个架构的映射(保存模板表)。
(顺便说一句,我并不是说,因为我怀疑您是否可以理解它,我敢肯定,但是我知道很多程序员都忽略了更复杂的数据库结构,这对他们自己不利,因为它看起来过于复杂,但是当进行分析时,实际上它们不如他们在程序中进行杂技操作才能获得相似的结果...关系数据库基于a branch of mathematics,它是@准确,一致且(相对)简洁地关联数据)。

一般用途:
(有关更多详细信息,请阅读SQL CREATE TABLE语句中的注释)
-填充DaysOfWeek表。
-使用要跟踪的一些时间帧填充TimeFrames表(AM时间帧的StartTime可以为00:00:00,结束时间为11:59:59,而PM的StartTime可以为12:00:00&EndTime之23:59:59)
-添加用户
-添加要跟踪的日期(有关避免过大膨胀的想法以及此表的优点,请参阅SQL中的注释)
-为每个用户填充模板表
-为每个用户生成默认可用性列表(及其关联的AvailableTimes数据)
-向用户公开默认功能,以便他们可以覆盖默认设置
注意:您还可以为“参与度”添加一个可选的表,以使其与“可用性”相反(或者可能会有更好的抽象,包括两个概念……)
免责声明:我没有花额外的时间来完全填充我的本地数据库并验证所有内容,因此可能存在一些我在图表中没有看到的弱点/错误...(对不起,我花的时间比预期的要长得多,并且必须完成逾期未完成的项目的工作)。
尽管我在数据库结构和与其他人已经创建12年以上的数据库中进行了相当广泛的工作,但我确信我并非没有错,但我希望StackOverflow上的其他人能够解决我可能包括的错误。

对于不包含更多示例数据,我深表歉意。
如果我在不久的将来有时间,我会提供一些信息((例如,将George,Fred和Harry添加到users表中,在Dates表中添加一些日期,然后详细说明George&Fred在上学期间与Harry相比他们有多忙)可用性,AvailableTimes和TimeFrames表)。

SELECT语句(注意:我强烈建议将其变成view ...这样,您可以选择所需的任何列,并在WHERE子句中添加所需的任何参数/条件,而不必编写每个连接时间...所以该 View 将不包括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,
主键(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.';

关于php - 计划在PHP/MySQL中使用模板和替代内容进行搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15483547/

有关php - 计划在PHP/MySQL中使用模板和替代内容进行搜索的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐