2016-06-01 11 views
2

Angenommen, es gibt eine term_terminationstabelle für eine Liste von Managern (oder HRs) mit startDatetime und endDatetime, dann wie die Tabelle sorgfältig so entwerfen, dass sie nächsten Überlappungen nicht akzeptiert derselbe Manager, wenn er/sie einen Termin mit einer anderen Person hat.SQL-Interview: Überlappenden Datumsbereich verhindern

Wenn Manager: A hat einen Termin aus 2016-01-01 11:00 to 2016-01-01 14:00 mit Employee-1 dann, wenn Employee-2 (oder someother Mitarbeiter) einen Termin aus 20-16-01-01 13:00 to 16:00 buchen versucht, dann sollte es nicht zulassen.

Hinweis: Es geht darum, die Tabelle so zu gestalten, dass Trigger/Prozeduren nicht unterstützt werden.

+6

diese Einschränkung erzwingen Sie einen Trigger oder benutzerdefinierte Funktion benötigen (zumindest in den meisten Datenbanken). –

+0

Wenn es sich wirklich um eine SQL-Interview-Frage handelt, könnte man einfach antworten, dass dies zur Entwurfszeit nicht möglich ist. –

+0

Sie können dies in SQL Server tun, wenn Sie auch die Zeiträume der Freizeit modellieren, Querverweise auf Fremdschlüssel haben, die jeden Zeitraum mit seinem Vorgänger und Nachfolger verknüpfen, und wirklich schreckliche 'MERGE'-Anweisungen schreiben, um Einfügen/Löschen zu verhindern (In den meisten Fällen müssen Sie eine freie Periode aufteilen, indem Sie eine aktualisieren, eine neue Zeile einfügen und den neuen Termin einfügen, alles in einer einzigen Anweisung, damit die Fremdschlüssel erfüllt bleiben). Es ist machbar, aber oft sind die Kosten höher als der Wert. –

Antwort

1

Anstatt Bereiche einzufügen, können Sie Zeitscheiben einfügen. Sie könnten die Scheiben so breit machen, wie Sie möchten, aber so tun, als könnten Sie einen Manager für jeweils 30 Minuten buchen. Um von 11:30 bis 12:00 Uhr zu buchen, fügen Sie eine Zeile mit dem Zeitwert um 11:30 Uhr ein. Um von 11:30 bis 12:30 Uhr zu buchen, würden Sie zwei Zeilen einfügen, eine um 11:30 Uhr, die andere um 12:00 Uhr. Dann können Sie einfach eine Primärschlüsselbeschränkung oder eine eindeutige Einschränkung verwenden, um eine Überbuchung zu verhindern.

create table appointment_booking (
    manager char not null, 
    startSlice DateTime, 
    visiting_employee varchar2(255), 
    primary key (manager, startSlice) 
) 

Ich weiß, das nicht genau Ihre Prämisse der Tabelle mit einer Start- und Endzeit passen, aber wenn Sie die Kontrolle über die Tabellenstruktur haben, würde dies funktionieren.

0

Check-Constraint + FUNKTION (das ist so nah wie ich auf eine DDL Antwort zu bekommen)

Sie könnten eine skalare Funktion erstellen - „SCHEDULE_OPENING_EXISTS()“, die beginnen nimmt, Ende, employeeID als Eingänge und gibt wahr oder falsch aus.

Dann könnten Sie eine Check-Einschränkung auf den Tisch erstellen

CREATE TABLE... 
    WITH CHECK ADD CONSTRAINT OPENING_EXISTS 
    CHECK (SCHEDULE_OPENING_EXISTS(begin, end, employeeID)) = 'True') 

TRIGGERS:

Ich versuche Auslöser zu vermeiden, wo ich kann. Sie sind nicht per se böse - aber sie fügen Ihrer Anwendung eine neue Ebene der Komplexität hinzu. Wenn Sie es nicht vermeiden können, benötigen Sie ein INSTEAD OF INSERT und auch ein INSTEAD OF UPDATE (vermutlich). Technet-Referenz Hier: https://technet.microsoft.com/en-us/library/ms179288%28v=sql.105%29.aspx

Denken Sie daran, wenn Sie einen Einfüge-/Aktualisierungsversuch ablehnen, ob oder wie Sie das dem Benutzer mitteilen müssen.

Stored Procedures/USER INTERFACE:

Würde eine Stored Procedure Arbeit für Ihre Situation? Beispielszenario:

  1. Benutzeroberfläche - Benutzer muss den Zeitplan der Person (en) sehen, mit denen sie einen Termin vereinbaren.

  2. Von der Benutzeroberfläche - versuchen Sie ein Einfügen/Aktualisieren mit einem gespeicherten Proc. Lassen Sie die Öffnung (in letzter Minute) erneut prüfen (geben Sie einen Fehler zurück, wenn die Öffnung nicht mehr vorhanden ist), und fügen Sie/conditional ein, wenn noch eine Öffnung vorhanden ist (Rückgabe einer Erfolgsmeldung).

Wenn die Prozedur einen Fehler auf der Benutzeroberfläche zurückgibt, damit umgehen, dass in der Benutzeroberfläche durch eine erneute Abfrage des sichtbaren Zeitplan aller Beteiligten, durch eine Fehlermeldung begleitet.

+0

Hinweis: Die Frage bezieht sich auf (überprüfen) Einschränkungen, Datenmodellierung und DDL in SQL. Die Anwendung oder die Benutzeroberfläche sind hier irrelevant, ebenso wie gespeicherte Prozeduren. – wildplasser

+0

@WildPlasser - eine CHECK CONSTRAINT-Option zur Antwort hinzugefügt ... nicht ganz DDL, aber ... näher. – Chains

0

Ich denke, diese Art von Fragen sind interessant, denn jedes Mal, wenn Sie eine Datenbank entwerfen, ist es wichtig zu wissen, die Anforderungen der Anwendung, die mit Ihrer Datenbank interagieren wird.

Dass gesagt wird, solange die Anwendung mehrere Tabellen verweisen kann, denke ich, Chris Steele Antwort ein guter Start ist, dass ich auf bauen ...

würde ich 2 Tabellen wollen. Die erste Tabelle unterteilt einen Tag in Teile (Slices), abhängig von den Geschäftsanforderungen der Organisation. Jede Scheibe wäre der Primärschlüssel dieser Tabelle. Ich persönlich würde 15-Minuten-Scheiben wählen, die in 96 Tage-Teile gleich sind. Jeder Tag-Teil in dieser Tabelle würde eine "Block-Start" - und eine "Block-Ende" -Zeit aufweisen, auf die die Scheduling-Anwendung Bezug nehmen würde, wenn ein Benutzer eine tatsächliche Startzeit und eine tatsächliche Endzeit für die Besprechung ausgewählt hat. Die Anwendung müßte Logik anwenden wie zwei „OR“ Operatoren zwischen 3 „und“ Anweisungen, um zu sehen, ob ein bestimmte blockID wird in Ihre Terminen Tabelle eingefügt:

  • eigentlichen Start> = Satzanfang und tatsächlichen Start < Blockende
  • tatsächliches Ende> Satzanfang und tatsächliche Ende < Blockende
  • eigentlicher Start < Satzanfang und tatsächliches Ende> Blockende

die von Chris Steele variiert leicht Antwort in th Bei ihr benutzt man zwei Tabellen. Die tatsächlichen Zeitstempel können weiterhin in Ihre Anwendungstabelle eingefügt werden, aber die Logik wird nur auf sie angewendet, wenn sie mit der Tabelle TimeBlocks verglichen wird. In meinem Termin Tabelle, ziehe ich Bruchdaten in Bestandteile für plattformübergreifende Analyse (unsere Organisation verwendet mehrere RDBMS sowie SAS für Analytik):

CREATE TABLE TimeBlocks (
      blockID Number(X) NOT NULL, 
      blockStart DateTime NOT NULL, 
      blockEnd DateTime NOT NULL, 
    primary key (blockID) 
); 


CREATE TABLE Appointments (
      mgrID INT NOT NULL, 
      yr INT NOT NULL, 
      mnth INT NOT NULL, 
      day INT NOT NULL, 
      blockID INT NOT NULL, 
      ApptStart DateTime NOT NULL, 
      ApptEnd DateTime NOT NULL 
      empID INT NOT NULL, 
    primary key (mgrID, yr, mnth, day, blockID), 
    CONSTRAINT timecheck 
      check (ApptStart < ApptEnd) 
);