PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Batasan postgres

Itu "mudah" karena PostgreSQL sangat dapat diperluas. Anda dapat menentukan tipe Anda sendiri, operator perbandingan untuk tipe dan kelas operator yang akan digunakan dengan btree indeks sehingga PostgreSQL tahu cara membandingkannya.

Triknya adalah dengan mendefinisikan "sama" sedemikian rupa sehingga nilai-nilai yang bertentangan adalah sama.

Pertama, kita mendefinisikan tipe kita:

CREATE TYPE tod AS ENUM ('morning', 'afternoon', 'anytime');

Kemudian kami mendefinisikan rutin dukungan indeks sehingga btree index tahu cara membandingkan nilai:

CREATE FUNCTION tod_compare(tod, tod) RETURNS integer
   IMMUTABLE LANGUAGE sql AS
$$SELECT CASE WHEN $1 = 'morning' AND $2 = 'afternoon' THEN -1
            WHEN $1 = 'afternoon' AND $2 = 'morning' THEN 1
            ELSE 0
       END$$;

Berdasarkan fungsi perbandingan ini, kami mendefinisikan fungsi yang mengimplementasikan operator perbandingan:

CREATE FUNCTION tod_eq(tod, tod) RETURNS boolean IMMUTABLE LANGUAGE sql
   AS 'SELECT tod_compare($1, $2) = 0';

CREATE FUNCTION tod_lt(tod, tod) RETURNS boolean IMMUTABLE LANGUAGE sql
   AS 'SELECT tod_compare($1, $2) = -1';

CREATE FUNCTION tod_le(tod, tod) RETURNS boolean IMMUTABLE LANGUAGE sql
   AS 'SELECT tod_compare($1, $2) <= 0';

CREATE FUNCTION tod_ge(tod, tod) RETURNS boolean IMMUTABLE LANGUAGE sql
   AS 'SELECT tod_compare($1, $2) >= 0';

CREATE FUNCTION tod_gt(tod, tod) RETURNS boolean IMMUTABLE LANGUAGE sql
   AS 'SELECT tod_compare($1, $2) = 1';

CREATE FUNCTION tod_ne(tod, tod) RETURNS boolean IMMUTABLE LANGUAGE sql
   AS 'SELECT tod_compare($1, $2) <> 0';

Sekarang kita dapat mendefinisikan operator pada tipe kita:

CREATE OPERATOR ~=~ (
   PROCEDURE = tod_eq,
   LEFTARG = tod,
   RIGHTARG = tod,
   COMMUTATOR = ~=~,
   NEGATOR = ~<>~
);

CREATE OPERATOR ~<>~ (
   PROCEDURE = tod_ne,
   LEFTARG = tod,
   RIGHTARG = tod,
   COMMUTATOR = ~<>~,
   NEGATOR = ~=~
);

CREATE OPERATOR ~<=~ (
   PROCEDURE = tod_le,
   LEFTARG = tod,
   RIGHTARG = tod,
   COMMUTATOR = ~>=~,
   NEGATOR = ~>~
); 

CREATE OPERATOR ~<~ (
   PROCEDURE = tod_lt,
   LEFTARG = tod,
   RIGHTARG = tod,
   COMMUTATOR = ~>~,
   NEGATOR = ~>=~
);

CREATE OPERATOR ~>~ (
   PROCEDURE = tod_gt,
   LEFTARG = tod,
   RIGHTARG = tod,
   COMMUTATOR = ~<~,
   NEGATOR = ~<=~
);

CREATE OPERATOR ~>=~ (
   PROCEDURE = tod_ge,
   LEFTARG = tod,
   RIGHTARG = tod,
   COMMUTATOR = ~<=~,
   NEGATOR = ~<~
);

Sekarang yang tersisa hanyalah mendefinisikan kelas operator yang dapat digunakan untuk mendefinisikan indeks (ini memerlukan hak pengguna super):

CREATE OPERATOR CLASS tod_ops DEFAULT FOR TYPE tod USING btree AS
   OPERATOR 1 ~<~(tod,tod),
   OPERATOR 2 ~<=~(tod,tod),
   OPERATOR 3 ~=~(tod,tod),
   OPERATOR 4 ~>=~(tod,tod),
   OPERATOR 5 ~>~(tod,tod),
   FUNCTION 1 tod_compare(tod,tod);

Sekarang kita dapat mendefinisikan tabel yang menggunakan tipe data baru.

Karena kita mendefinisikan tod_ops sebagai kelas operator default untuk tipe tod , kita dapat membuat batasan unik yang sederhana, dan indeks yang mendasarinya akan menggunakan kelas operator kita.

CREATE TABLE schedule (
   id integer PRIMARY KEY,
   day date NOT NULL,
   time_of_day tod NOT NULL,
   UNIQUE (day, time_of_day)
);

Mari kita uji:

INSERT INTO schedule VALUES (1, '2018-05-01', 'morning');

INSERT INTO schedule VALUES (2, '2018-05-01', 'afternoon');

INSERT INTO schedule VALUES (3, '2018-05-02', 'anytime');

INSERT INTO schedule VALUES (4, '2018-05-02', 'morning');
ERROR:  duplicate key value violates unique constraint "schedule_day_time_of_day_key"
DETAIL:  Key (day, time_of_day)=(2018-05-02, morning) already exists.

Bukankah PostgreSQL keren?




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara memasukkan pandas DataFrame ke tabel PostgreSQL?

  2. SqlAlchemy(Flask+Postgres):Bagaimana cara memperbarui hanya atribut tertentu dari bidang json?

  3. Spring Batch - Tidak dapat membuat tabel metadata di Postgres dan memuat data aktual ke mysql

  4. PostgreSQL:Kueri tidak memiliki tujuan untuk data hasil

  5. Tidak dapat terhubung ke wadah buruh pelabuhan Postgres dari wadah Golang