Đây là cầu xin cho rắc rối. Bạn sẽ tiếp tục gặp phải những điểm không tương thích nhỏ. Hoặc thậm chí không nhận thấy chúng cho đến sau này, khi thiệt hại đã được thực hiện. Đừng làm điều đó. Sử dụng PostgreSQL cục bộ. Nó có sẵn miễn phí cho hầu hết mọi hệ điều hành. Đối với một người nào đó tham gia vào một "dự án khóa học cơ sở dữ liệu" thì đây là một sự điên rồ đáng ngạc nhiên. Có liên quan:
Lời khuyên khác:
-
Như @Priidu được đề cập trong nhận xét , các ràng buộc khóa ngoại của bạn bị ngược. Điều này không cần phải tranh luận, họ chỉ đơn giản là sai .
-
Trong PostgreSQL, sử dụng
serial
hoặcIDENTITY
cột (Postgres 10+) thay vìAUTOINCREMENT
của SQLite . Xem: -
Sử dụng
timestamp
(hoặctimestamptz
) thay vìdatetime
. -
Không sử dụng số nhận dạng chữ hoa và chữ thường hỗn hợp.
-
Không sử dụng các tên cột không mang tính mô tả như
id
. Bao giờ. Đó là một mô hình chống được giới thiệu bởi phần mềm trung gian và ORM. Khi bạn tham gia một vài bảng, bạn sẽ có nhiều cột có tênid
. Điều đó tích cực gây tổn thương. -
Có nhiều kiểu đặt tên, nhưng hầu hết đều đồng ý rằng tốt hơn hết nên có các thuật ngữ số ít làm tên bảng. Nó ngắn hơn và ít nhất là trực quan / logic.
label
, không phải nhãnlabels
.
Mọi thứ kết hợp lại với nhau, nó có thể trông như thế này:
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)
);
Trình kích hoạt
Để xóa các nhãn không sử dụng, hãy triển khai trình kích hoạt . Tôi cung cấp một phiên bản khác vì tôi không hài lòng với phiên bản do @Priidu cung cấp :
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$;
-
Trình kích hoạt chức năng phải được tạo trước khi trình kích hoạt .
-
Một
DELETE
đơn giản lệnh có thể thực hiện công việc. Không cần truy vấn thứ hai - đặc biệt không cầncount(*)
.EXISTS
rẻ hơn. -
Dấu ngoặc đơn xung quanh tên ngôn ngữ được chấp nhận, nhưng nó thực sự là một mã định danh, vì vậy chỉ cần bỏ qua những điều vô nghĩa:
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();
Không có CREATE OR REPLACE TRIGGER
trong PostgreSQL, chưa. Chỉ cần CREATE TRIGGER
.