sql >> データベース >  >> RDS >> PostgreSQL

独自の組み合わせの保存と比較

    配列として保存(非正規化)

    追加のモジュールintarray を検討します 便利な(そして高速な)関数uniq()を提供します およびsort() 。典型的な最新のPostgresインストールでは、次のように簡単です。

    CREATE EXTENSION intarray;
    

    これらを使用して、簡単なCHECK 制約は昇順を強制できます 明確なの配列 要素。

    CHECK (uniq(sort(cat_arr)) = cat_arr)
    

    さらに (オプションで)配列値を正規化するトリガーがありますON INSERT OR UPDATE 自動的。次に、任意のを渡すだけです。 配列(おそらくソートされておらず、重複あり)とすべてが正常に機能します。いいね:

    CREATE OR REPLACE FUNCTION trg_search_insup_bef()
      RETURNS trigger AS
    $func$
    BEGIN
       NEW.cat_arr := uniq(sort(NEW.cat_arr);
       RETURN NEW;
    END
    $func$ LANGUAGE plpgsql;
    
    CREATE TRIGGER insup_bef
    BEFORE INSERT OR UPDATE OF cat_arr ON search
    FOR EACH ROW
    EXECUTE PROCEDURE trg_search_insup_bef();
    

    追加のモジュールintarrayはオプションですが、他の方法があります。

    ただし、intarray関数は優れたパフォーマンスを提供します。

    次に UNIQUEを作成するだけです 制約 配列列に配置して、配列全体の一意性を強制します。

    UNIQUE (cat_arr)
    

    ちょうど2日前に、この関連する回答で、(非常に厳密で信頼性の高い)制約と(信頼性は低いがより便利な)トリガーを組み合わせる利点について詳しく説明しました。

    組み合わせごとに、カテゴリごとに保存する必要があるのがIDだけ(追加情報なし)の場合、これで十分です。
    ただし 、参照整合性は、この方法では簡単に保証されません。配列要素には(まだ)外部キー制約はありません-リンクに記載されています :カテゴリの1つが削除されたり、IDを変更したりすると、参照が壊れます...

    正規化されたスキーマ

    より多くを格納する必要がある場合、または参照整合性を適用するために正規化されたスキーマを使用する場合、または何らかの理由でそれを行うこともできます。トリガーを追加して、手作りのマテリアライズドビュー(冗長テーブル)にデータを入力します。同様の方法で一意性を適用します:

    CREATE TABLE search (
      search_id serial PRIMARY KEY
    , ... more columns
    );
    
    CREATE TABLE cat (
      cat_id serial PRIMARY KEY
    , cat text NOT NULL
    );
    
    CREATE TABLE search_cat (
      search_id int REFERENCES search ON DELETE CASCADE
    , cat_id    int REFERENCES cat
    , PRIMARY KEY (search_id, cat_id)
    );
    

    トリガーを示す関連する回答(一意の組み合わせではなく、一意の要素):



    1. phpはnext->rowsetでは機能しませんが実行します

    2. SQL Serverのストアドプロシージャにパラメータを追加することの違いは?

    3. SQLServerBCPエクスポートSQLフィールドのコンマ

    4. PHPとAjaxを使用してフォームデータをMySQLデータベーステーブルに挿入するにはどうすればよいですか?