Mysql

如何為插槽表添加插槽,以免發生衝突

  • July 7, 2018

我有一個插槽表,其中包含以下欄位:

  CREATE TABLE `Slot` (
     `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
     `starttime` datetime NOT NULL,
     `endtime` datetime NOT NULL,
     `assigned_To_Id` int(10) unsigned DEFAULT NULL,

     PRIMARY KEY (`id`),
     KEY `appointment_assigned_to_id_foreign` (`assigned_To_Id`),
     CONSTRAINT `appointment_assigned_to_id_foreign` FOREIGN KEY (`assigned_To_Id`) REFERENCES `Employee` (`id`),
   )
ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1

現在,管理員可以通過指定槽位為特定日期的員工(assigned_To_Id)添加槽位:例如:

7 July Slots : 
11:45-12:00
12:00-13:00
and slot time = 15 mins (above time range will be divided in slot time intervals of 15 mins and assigned_To_Id = 1

現在,在添加插槽之前,我們需要檢查插槽是否與 db 中分配給 1 的現有數據的任何衝突。

select count(*) from Slots
where 
(
   (starttime >= '2018-07-07 11:45:00' and  ('2018-07-07 11:59:59' between starttime and endtime))
    or
   (starttime Between '2018-07-07 11:45:00' and  '2018-07-07 11:59:59' and endtime <= '2018-07-07 11:59:59')
   or
   ('2018-07-07 11:45:00' Between starttime and endtime  and '2018-07-07 11:59:59' Between starttime and endtime)
)


or 
(
   (starttime >= '2018-07-07 12:00:00' and  ('2018-07-07 12:59:59' between starttime and endtime))
    or
   (starttime Between '2018-07-07 12:00:00' and  '2018-07-07 12:59:59' and endtime <= '2018-07-07 12:59:59')
   or
   ('2018-07-07 12:00:00' Between starttime and endtime  and '2018-07-07 12:59:59' Between starttime and endtime)
)
and assigned_To_Id = 1
so if there are 'n' slots --> check for each slot

就像管理員給出的每個時間段一樣,我們有 3 個條件可以用來檢查是否存在任何時間衝突或任何現有時間段

如果查詢返回的計數為 0,這意味著我們可以將像將 11:45-12:00 劃分為 15 分鐘的時隙和 12:00-13:00 的時隙添加到 15 分鐘的時隙中。

我的問題是:如何將這個插入與 count(*) 查詢一起執行,這樣如果兩個管理員嘗試做類似的事情,只有其中一個成功。

Can we combine insert statement with condition ?
Is stored procedure a good idea for this one ?
BEGIN;
SELECT ... FOR UPDATE;
check for no overlaps (or whatever)
INSERT (or update) new entry
COMMIT;

在 InnoDB 中,鎖定整個表相當於鎖定每一行。我是否需要解釋這鎖定單行成本高得多?

SELECT ... FOR UPDATE應該悲觀地鎖定您不想弄亂的任何行,直到事務結束。通常它是單行(鎖定一行…更新行)。或者,它可能涉及在決定實際更新哪些行(如果有的話)之前鎖定幾行。

您應該盡量減少鎖定的行數——為了 的速度SELECT,為了ROLLBACK/的速度COMMIT,以及為了盡量減少對其他查詢的干擾。

除非您每秒發生數百UPDATEs次,否則鎖定太多行並不是什麼大問題——畢竟,您的事務應該設計為僅在幾毫秒內完成,而不是預設的 `innodb_lock_wait_timeout=50(秒)。

引用自:https://dba.stackexchange.com/questions/211533