
 Πρέπει να διασφαλίσω ότι η βάση δεδομένων μου περιέχει μόνο καταχωρήσεις όπου δύο ή περισσότερες στήλες είναι μοναδικές. Αυτό μπορεί εύκολα να επιτευχθεί με ένα `UNIQUE` περιορισμός σε αυτές τις στήλες. 

 Στην περίπτωσή μου, πρέπει να απαγορεύσω την επανάληψη μόνο για αλληλεπικαλυπτόμενα χρονικά διαστήματα. Ο πίνακας έχει `valid_from` και `valid_to` στήλες. Σε ορισμένες περιπτώσεις μπορεί πρώτα να χρειαστεί να λήξει η ενεργή καταχώριση με τη ρύθμιση `valid_to = now` και, στη συνέχεια, εισάγοντας μια νέα καταχώρηση προσαρμοσμένη σε `valid_from = now` και `valid_to = infinity` . 

 Φαίνεται ότι μπορώ να λήξω την προηγούμενη καταχώριση χωρίς προβλήματα στη χρήση `UPDATE` , αλλά η εισαγωγή της νέας καταχώρησης φαίνεται να είναι ενοχλητική, καθώς οι βασικές στήλες μου είναι αυτήν τη στιγμή `UNIQUE` και επομένως δεν μπορεί να προστεθεί ξανά. 

 Σκέφτηκα να προσθέσω `valid_from` και `valid_to` ως μέρος του `UNIQUE` περιορισμός, αλλά αυτό θα καθιστούσε τον περιορισμό πιο χαλαρό και θα επέτρεπε την ύπαρξη διπλών *και* αλληλεπικαλυπτόμενων χρονικών ορίων. 

 Πώς μπορώ να κάνω έναν περιορισμό για να διασφαλίσω ότι δεν υπάρχουν διπλότυπα με επικάλυψη `valid_from` και `valid_to``tsrange` ; 

 Φαίνεται να ψάχνω `EXCLUDE USING GIST` , αλλά δεν φαίνεται να υποστηρίζει πολλές στήλες; Αυτό δεν φαίνεται να λειτουργεί για μένα: 


```
ALTER TABLE registration 
DROP Constraint IF EXISTS registration_{string.Join('_', listOfAttributes)}_key, 
ADD Constraint registration_{string.Join('_', listOfAttributes)}_key EXCLUDE USING GIST({string.Join(',', listOfAttributes)} WITH =, valid WITH &&);

```
 
Πώς να διασφαλίσετε καταχωρίσεις με μη επικαλυπτόμενα χρονικά όρια;
===================================================================



 Ήσουν στο σωστό δρόμο. Ωστόσο, η [σύνταξη για τους περιορισμούς αποκλεισμού](https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE) είναι ελαφρώς διαφορετική: 


```
CREATE TABLE registration  (
  tbl_id  integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
, col_a   integer NOT NULL
, col_b   integer NOT NULL
, valid_from timestamptz
, valid_to   timestamptz
, CONSTRAINT no_overlap
    EXCLUDE USING gist (**col\_a with =, col\_b with =, tstzrange(valid\_from, valid\_to) WITH &&**)
);
```
 Ίσως χρειαστεί να εγκαταστήσετε την πρόσθετη μονάδα `btree_gist` πρώτα, ανάλογα με τον μη γνωστό ορισμό του πίνακα σας. 

 Κάθε στήλη πρέπει να αναφέρεται στον αντίστοιχο χειριστή της. 

 Και χρειάζεστε έναν *τύπο εύρους* . Υποθέτοντας `timestamp with time zone` Για `valid_from` και `valid_to` , η έκφραση `tstzrange(valid_from, valid_to)` θα το έκανε. 

 Σχετίζεται με: 

* [Εκτελέστε αυτό το ερώτημα ωρών λειτουργίας στο PostgreSQL](https://stackoverflow.com/questions/22108477/perform-this-hours-of-operation-query-in-postgresql/22111524#22111524)
* [Μη αλληλεπικαλυπτόμενα, συνεχή χρονικά σήματα (tstzrange) για ώρες λειτουργίας](https://stackoverflow.com/questions/26539259/non-overlap-continuous-timestamp-ranges-tstzrange-for-opening-hours/26539981#26539981)
* [Το ερώτημα Postgresql 9.4 γίνεται σταδιακά πιο αργό όταν συμμετέχετε στο TSTZRANGE με &&](https://stackoverflow.com/questions/33987739/postgresql-9-4-query-gets-progressively-slower-when-joining-tstzrange-with/33990737#33990737)
* [Αποθηκεύστε την ημέρα της εβδομάδας και την ώρα;](https://stackoverflow.com/questions/19895140/store-the-day-of-the-week-and-time/19897592#19897592)



---

 *Ίσως* , ένας ανώτερος σχεδιασμός να είναι μια σχέση μεταξύ σας `registration` πίνακες και 1-Ν καταχωρήσεις σε μια νέα `registration_range` τραπέζι. Και κάποια λογική για τον προσδιορισμό της τρέχουσας έγκυρης καταχώρισης (για οποιαδήποτε δεδομένη χρονική στιγμή). Εξαρτάται από περισσότερες άγνωστες πληροφορίες. 

 