簡體   English   中英

PHP / MySQL約會/預訂系統的最佳實踐

[英]Best practice for PHP/MySQL Appointment/Booking system

我需要一些人為我目前正在從事的美發師的PHP / MySQL約會系統爭取“最佳實踐”。 希望我們可以一起清理一些事情,以避免以后再做該系統。 我一直在尋找SO和Google的一些教程,最佳實踐等,但是沒有找到適合我需求的東西。

基本信息

每天有多個理發師,每個理發師都有自己的日程安排,其中包含與客戶的約會。 與美發師連接的表包含他/她一周中有空的時間。

表:人

+----+------+-------+-----------+
| id | name | email | available |
+----+------+-------+-----------+
| 1  | John | i@a.c | Y         |
| 2  | Sara | c@i.a | N         |
+----+------+-------+-----------+

表格:次( 此表格有一個主鍵,我在下面的時間表中省略了它

+-----------+-------------+-----------+-----------+
| people_id | day_of_week | start     | end       |
+-----------+-------------+-----------+-----------+
| 1         | 1           | 08:00     | 12:00     |
| 1         | 1           | 12:30     | 17:00     |
| 1         | 3           | 09:00     | 12:00     |
| 1         | 4           | 10:30     | 16:00     |
| 1         | 5           | 09:00     | 17:00     |
| 1         | 6           | 09:00     | 12:00     |
| 2         | 1           | 09:00     | 12:00     |
| 2         | 2           | 09:00     | 12:00     |
| 2         | 3           | 09:00     | 12:00     |
+-----------+-------------+-----------+-----------+

如您所見,人與時間之間存在一對多的關系(顯然,因為一周中有7天)。 但是除此之外,還有一個選項可以在一天的小時之間添加休息時間(請參見people_id = 1,day_of_week = 1:08:00-12:00和12:30-17:00)。

此外,還有一個名為“ hairdress_types”的表,該表包含一個人可以進行的各種約會(例如,染發,剪發,洗臉等)。 該表包含此約會花費的時間(以分鍾為單位)。

最后,我有一個非常簡單的表appointments

id, people_id, types_id, sex, fullname, telephone, emailaddress, date_start, date_end

日期開始和日期結束將是MySQL中完整的DATETIME字段,這使得使用MySQL查詢函數進行計算變得更加容易。

最佳做法是什么?

因此,按照我的設置方式,前端用戶會在字段中選擇一個日期,從而觸發ajax / jquery函數,該函數查找在所選日期可用的所有美發師。 然后,用戶指定發型師(這不是強制性的:用戶還可以選擇“任何”發型師選項)以及他/她想要進行的約會類型。

提交第一份表格后,可以使用以下信息:

  1. 日期(日,月和年)
  2. people_id(對於“ Any”,可以為0;如果選擇了美發師,則可以為ID)
  3. hairdress_type(與約會所花費的分鍾數相關聯)

使用此信息,我將從選擇的美發師中選擇可用的日期, 或者循環所有可用的美發師及其可用的日期。

這是我的思想崩潰的地方! 因為什么是檢查可用日期的最佳方法。 我認為最好的方法是:

  1. 查詢給定日期的理發師時間(一次1次)
  2. 使用查詢1的結果的開始日期+約會類型花費的分鍾數來查詢約會表(因此: SELECT * FROM appointments WHERE ((date_start >= $start AND date_start <= ($start+$time)) OR (date_end > $start AND date_end <= ($start+$time)) AND people_id = 1
  3. 一旦未找到結果,我就假定該位置是免費的,並且作為選項提供給用戶

我面臨的更大的問題是要點2:我對這個查詢的想法真的發瘋了,這是我需要查找匹配特定時間范圍的約會的完整查詢嗎?

感謝您的閱讀和思考! :-)

//編輯:多一點“ testdata”:

約翰-星期一-12:00-17:00。 預約:-12:00-12:30-14:30-15:30

用戶想要預約需要2個小時的約會,在上面的示例中,我將檢查:

  1. 在12:00和14:00之間有約會嗎? 是的..前往下一個地點
  2. 在14:00和16:00之間有約會嗎? 是的..前往下一個地點
  3. 在16:00和18:00之間有約會嗎? 錯誤,在17:00之后不可用

因此,使用10/15分鍾的“時間塊”可能是一個更好的選擇。 進行檢查:

  1. 12:00-14:00
  2. 12:10-14:10
  3. 12:20-14:20等。

這將在12:30和14:30之間找到可用的位置。

//編輯2:可能的查詢進入第2步

我一直在寫一些紙上的東西(一張桌子,上面有約會和可能要使用的空白點)。 我想出了以下幾點。 在以下情況下無法預約:

  1. 與start_date BETWEEN $ start和$ end約會
  2. 在$ start和$ end之間有一個end_date約會
  3. 約會為start_date <$ start和end_date> $ end

將上面的內容與people_id一起查詢到約會表中將導致沒有行(=自由點)或一個/多個行,在這種情況下將采用該點。

我猜找到空位的最好方法是在數據庫中查詢X分鍾的塊,起始間隔為10分鍾。 該解決方案的缺點是,我每小時每小時要查詢6個查詢,每個美發師大約要查詢48個查詢...關於如何減少該查詢數量的任何想法?

最后,我去了一個為數據庫中的開始日期和結束日期生成時間戳的系統。 在檢查時,我在開始時增加了1秒,在結束時減去了1秒,以免約會重疊。

我最終做了什么

顯然,我不確定這是否是最佳做法,但這確實對我有用。 用戶首先選擇自己的性別和當天的偏好。 這將發送一個AJAX請求,以獲取可用的人員和各種約會類型(例如染發,剪發等)。

選擇所有設置(性別,日期,人員和類型)后,我將通過一些簡單的驗證開始:檢查日期,檢查date(“ N”)是否不是7(星期日)。 如果一切正常,則開始更重要的事情:

1)從數據庫中獲取約會類型,包括該類型所花費的總時間(30分鍾,45分鍾等)2)獲取可用的個人(當天完整的人員列表,或者僅包含一個人)選擇一個),包括其可用時間

然后,人員(或一個人)從他們自己的開始時間開始循環播放。 此時,我有一組數據,其中包含:

$duration (of the appointment type)
$startTime (starting time of the person selected in the loop)
$endTime (= $startTime + $duration)
$personStart (= starting time of the person)
$personEnd (= end time of the person)

讓我們看一下這個演示數據:

$duration = 30 min
$startTime = 9.00h
$endTime = 9.30h
$personStart = 9.00h
$personEnd = 12.00h

我在這里做的是:

while( $endTime < $personEnd )
{
    // Check the spot for availability
    $startTime = $endTime;
    $endTime = $startTime + $duration;
}

顯然,在這種情況下已經簡化了。 因為當我檢查可用性時,現貨不是免費的。 我將$ startTime設置為等於找到的最新約會,然后從循環中的那里開始。

例:

I check for a free spot at 9.00 but the spot is not free because there's an appointment from 9.00 till 10.00, then 10.00 is returned and $startTime is set to 10.00h instead of 9.30h. This is done to keep the number of queries to a minimum since there can be quiet a lot.

檢查可用性功能

// Check Availability
public static function checkAvailability($start, $end, $ape_id)
{
  // add one second to the start to avoid results showing up on the full hour
  $start += 1;
  // remove one second from the end to avoid results showing up on the full hour
  $end -= 1;

  // $start and $end are timestamps
  $getAppointments = PRegistry::getObject('db')->query("SELECT * FROM appointments WHERE
    ((
        app_start BETWEEN '".date("Y-m-d H:i:s", $start)."' AND '".date("Y-m-d H:i:s", $end)."' 
          OR
        app_end BETWEEN '".date("Y-m-d H:i:s", $start)."' AND '".date("Y-m-d H:i:s", $end)."'
      ) 
    OR
      (
    app_start < '".date("Y-m-d H:i:s", $start)."' AND app_end > '".date("Y-m-d H:i:s", $end)."'
     ))
    AND
     ape_id = ".PRegistry::getObject('db')->escape($ape_id));

    if(PRegistry::getObject('db')->num_rows($getAppointments) == 0) {
      return true;
    } else {
      $end = 0;
      foreach(PRegistry::getObject('db')->fetch_array(MYSQLI_ASSOC, $getAppointments, false) as $app) {
        if($app['app_end'] > $end) {
          $end = $app['app_end'];
            }
    }
    return $end;
     } 
}

由於我將約會存儲為“發件人:10.00,直到:11.00”,因此我必須確保檢查從11:00:01到11:59:59的地點,因為否則將在結果中顯示11:00的約會。

在函數的末尾,如果找到約會,我將循環結果並返回最新的末尾。 這是我上面提到的循環中的下一個起點。

希望這對任何人都有幫助。 就像信息一樣: ape_id是與其鏈接的“約會人員”的ID。

使用MySQL關鍵字BETWEEN

SELECT * FROM mytable WHERE mydate BETWEEN start_date AND end_date;

如果要查看現在和一天之間是否有約會,可以執行以下操作:

$enddate = strtotime('+1 day', time());

SELECT * FROM mytable WHERE mydate BETWEEN NOW() AND {$enddate};

資源

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM