Hallo Michael,
die Frage ist hier, ob Du ein festes Terminraster hast, mit festen Terminlängen, oder ob Termine relativ frei beginnen und enden können.
Bei einem festen Terminraster würde ich empfehlen, einfach Datum und Uhrzeit als eindeutigen Index zu definieren - bei einem Duplikat schlägt dann der INSERT Befehl einfach fehl und gut ist.
Bei einem variablen Raster wird es schwieriger.
Letztlich musst Du ja nur wissen, ob es für den gewünschten Zeitraum keine Überlappungen gibt. D.h. jeder Termin in der Tabelle muss einen Ende-Zeitpunkt haben, der vor deinem Startzeitpunkt liegt ODER einen Start-Zeitpunkt, der hinter deinem Endezeitpunkt liegt. Ob "vor" und "hinter" nun als <
und >
oder als <=
und >=
zu implementieren sind, musst Du Dir überlegen.
Wenn Du einen Termin (newStart, newEnde) hast, wäre ein Termin aus der Tabelle t mit (t.start, t.ende) also kollisionsfrei, wenn gilt:
t.ende <= newStart OR t.start >= newEnde
Du musst aber das Gegenteil finden. Zeit für den Kollegen De Morgan:
NOT( t.ende <= newStart OR t.start >= newEnde )
wird zu
NOT( t.ende <= newStart ) AND NOT( t.start >= newEnde )
wird zu
t.ende > newStart AND t.start < newEnde
Ich kriege Kopfschmerzen, wenn ich das anschaue, aber ich vertraue der De Morgan Regel 😉
Also:
SELECT COUNT(*)
FROM termine t
WHERE t.ende > newStart AND t.start < newEnde
liefert Dir die Anzahl der kollidierenden Termine (wobei Du newStart und newEnde mit geeigneten Mitteln in die Query einsetzen musst). Leg einen Index auf (t.start, t.ende) und das Ganze sollte akzeptabel schnell sein.
Und dann würde ich stumpf die Tabelle sperren:
LOCK TABLES termine WRITE
SELECT COUNT(*)...
Wenn Ergebnis 0 ist
INSERT
UNLOCK
Wenn der LOCK WRITE die regulären Terminabfragen zu sehr behindert, dann führe eine Dummy-Tabelle ein, wo nichts drin steht, und die Du vor Terminupdates lockst. Das muss dann aber sehr konsequent passieren, jeder INSERT und jeder UPDATE auf start oder ende muss vorher die Dummy-Table locken.
Wenn wirklich viel los ist auf der Termine-DB, mag das immer noch zu Engpässen führen und man muss sich ggf. andere Datenstrukturen überlegen. Aber nur dann.
Rolf
sumpsi - posui - obstruxi