Ini memohon masalah. Anda akan terus mengalami ketidaksesuaian kecil. Atau bahkan tidak menyadarinya sampai lama kemudian, ketika kerusakan terjadi. Jangan lakukan itu. Gunakan PostgreSQL secara lokal juga. Ini tersedia secara bebas untuk sebagian besar setiap OS. Untuk seseorang yang terlibat dalam "proyek kursus database" ini adalah kebodohan yang mengejutkan. Terkait:
Saran lainnya:
-
Seperti @Priidu disebutkan dalam komentar , batasan kunci asing Anda mundur. Ini bukan untuk diperdebatkan, mereka hanya salah .
-
Di PostgreSQL gunakan
serial
atauIDENTITY
kolom (Postgres 10+) alih-alih SQLiteAUTOINCREMENT
. Lihat: -
Gunakan
timestamp
(atautimestamptz
) bukannyadatetime
. -
Jangan gunakan pengidentifikasi huruf besar-kecil.
-
Jangan gunakan nama kolom yang tidak deskriptif seperti
id
. Pernah. Itu anti-pola yang diperkenalkan oleh middleware setengah cerdas dan ORM. Saat Anda bergabung dengan beberapa tabel, Anda akan mendapatkan beberapa kolom dengan namaid
. Itu sangat menyakitkan. -
Ada banyak gaya penamaan, tetapi sebagian besar setuju bahwa lebih baik memiliki istilah tunggal sebagai nama tabel. Ini lebih pendek dan setidaknya intuitif/logis.
label
, bukanlabels
.
Semuanya disatukan, bisa terlihat seperti ini:
CREATE TABLE IF NOT EXISTS post (
post_id serial PRIMARY KEY
, author_id integer
, title text
, content text
, image_url text
, date timestamp
);
CREATE TABLE IF NOT EXISTS label (
label_id serial PRIMARY KEY
, name text UNIQUE
);
CREATE TABLE IF NOT EXISTS label_post(
post_id integer REFERENCES post(post_id) ON UPDATE CASCADE ON DELETE CASCADE
, label_id integer REFERENCES label(label_id) ON UPDATE CASCADE ON DELETE CASCADE
, PRIMARY KEY (post_id, label_id)
);
Pemicu
Untuk menghapus label yang tidak digunakan, terapkan pemicu . Saya menyediakan versi lain karena saya tidak senang dengan yang disediakan oleh @Priidu :
CREATE OR REPLACE FUNCTION f_trg_kill_orphaned_label()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
DELETE FROM label l
WHERE l.label_id = OLD.label_id
AND NOT EXISTS (
SELECT 1 FROM label_post lp
WHERE lp.label_id = OLD.label_id
);
END
$func$;
-
Pemicu fungsi harus dibuat sebelum pemicu .
-
DELETE
simple sederhana perintah dapat melakukan pekerjaan. Tidak diperlukan kueri kedua - khususnya tidak adacount(*)
.EXISTS
lebih murah. -
Kutipan tunggal di sekitar nama bahasa ditoleransi, tetapi itu benar-benar pengidentifikasi, jadi hilangkan omong kosong:
LANGUAGE plpgsql
CREATE TRIGGER label_post_delaft_kill_orphaned_label
AFTER DELETE ON label_post
FOR EACH ROW EXECUTE PROCEDURE f_trg_kill_orphaned_label();
Tidak ada CREATE OR REPLACE TRIGGER
di PostgreSQL, belum. Cukup CREATE TRIGGER
.