これはトラブルを懇願しています。あなたはマイナーな非互換性に遭遇し続けるでしょう。または、損傷が発生するずっと後まで、それらに気付くことさえありません。 しないでください。 ローカルでもPostgreSQLを使用します。ほとんどすべてのOSで無料で利用できます。 「データベースコースプロジェクト」に携わっている人にとって、これは驚くべき愚かさです。関連:
その他のアドバイス:
-
コメントで言及されている
@Priiduとして 、外部キー制約は後方にあります。これは議論の余地がありません、彼らは単に間違っています 。 -
PostgreSQLでは
serial
を使用します またはIDENTITY
SQLiteAUTOINCREMENT
の代わりに列(Postgres 10+) 。参照: -
timestamp
を使用します (またはtimestamptz
)datetime
の代わりに 。 -
大文字と小文字が混在する識別子は使用しないでください。
-
id
のようなわかりにくい列名は使用しないでください 。これまで。これは、半ばウィットのミドルウェアとORMによって導入されたアンチパターンです。いくつかのテーブルを結合すると、id
という名前の複数の列ができあがります。 。それは積極的に害を及ぼします。 -
多くの命名スタイルがありますが、ほとんどの場合、テーブル名として単一の用語を使用する方がよいことに同意しています。それはより短く、少なくとも直感的/論理的です。
label
、labels
ではありません 。
すべてをまとめると、次のようになります。
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)
);
トリガー
未使用のラベルを削除するには、トリガーを実装します 。 @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$;
-
トリガー関数 前に作成する必要があります トリガー 。
-
単純な
DELETE
コマンドは仕事をすることができます。 2番目のクエリは必要ありません-特にcount(*)
は必要ありません 。EXISTS
安いです。 -
言語名を一重引用符で囲むことは許容されますが、実際には識別子であるため、ナンセンスを省略してください:
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();
CREATE OR REPLACE TRIGGER
はありません PostgreSQLではまだです。 CREATE TRIGGER
だけ
。