メインアプリでこの問題を解決する方法は次のとおりです。
ユーザーが検索できるメイン エンティティがあります。それを呼び出しますcustomer
。このエンティティには、1:n contact
(電話、電子メールなど) テーブルの詳細レコードが関連付けられています。
customer_quicksearch
クイックサーチ キーを計算するビュー を定義します。これは、顧客のレコードtext
の連結といくつかのフィールドを直接含むフィールドです。contact
customer
テーブルにトリガーを追加しましたcustomer
。トリガーは、行が挿入されたときにレコードを追加しcontact
customer_summary
、レコードが削除されたときに行を削除します。それらは、`customer_quicksearch. ビューの代わりに SQL 関数を使用することもできましたが、ビューの方が便利で高速であることがわかりました。ビューを使用すると、たとえば、一括挿入または一括更新の後、すべての顧客のクイック検索キーを計算する方が速くなります。customer
customer_summary
customer
customer
customer_summary
SELECT
CREATE VIEW customer_quicksearch AS
SELECT
customer.id AS customer_id, array_to_string(ARRAY[
customer.code,
customer.name,
string_agg(array_to_string(ARRAY[
contact.email::text,contact.altemail::text, contact.mobile_phone, contact.work_phone, contact.home_phone, contact.fax
],'|'),'|')
], '|') AS quicksearch_key
FROM customer
LEFT OUTER JOIN contact ON (customer.id = contact.customer_id)
GROUP BY customer.id;
およびトリガーの 1 つ:
CREATE OR REPLACE FUNCTION customer_summary_update_for_contact() RETURNS trigger AS $$
DECLARE
_customer_id integer;
BEGIN
-- When a contact is added/removed/changed we have to regenerate the customer search key
IF tg_op = 'INSERT' OR tg_op = 'UPDATE' THEN
_customer_id = NEW.customer_id;
ELSE
_customer_id = OLD.customer_id;
END IF;
UPDATE customer_summary
SET quicksearch_key = (SELECT quicksearch_key FROM customer_quicksearch WHERE customer_id = _customer_id)
WHERE customer_id = _customer_id;
RETURN NULL;
END;
$$
LANGUAGE 'plpgsql'
SET search_path = 'public';
CREATE TRIGGER customer_summary_update_for_contact_trg AFTER INSERT OR UPDATE OR DELETE ON contact
FOR EACH ROW EXECUTE PROCEDURE customer_summary_update_for_contact();
また、その顧客のレコードを適切に維持するために、および顧客customer
を処理するためのトリガーも必要です。insert
update
delete
customer_summary
テーブルには、次のようなフィールドのパイプ連結である をcustomer_summary
含むレコードが含まれています。quicksearch_key
'1800MA|1800 MAKE IT BUILDERS|info@1800makeit.example.com|1234 5678|0499 999 999'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
[from customer record] [from 1st contact record] [from another contact record]
これは単純なLIKE
パターンで検索されます。プレフィックス検索を行っている場合は、パフォーマンスを向上させるためにインデックスを追加できtext_pattern_ops
ますが、ほとんどの場合、左右LIKE '%search%'
のアンカーを使用せずに検索を行っているため、メリットはありません。