PostgreSQLのファイティングビュー(CREATE VIEW)

私がPostgreSQLで作業している最後の1.5年間、美しいソリューションを必要とするいくつかのタスクが定期的に発生することがたまたま起こりました。



問題



約60個のフィールドがある広告プレートがあります。 これらのフィールドの値に応じて、広告はさまざまな場所に表示される場合があります。 これは通常、ビューを作成することで解決します( CREATE VIEW-マニュアル)。 ただし、この方法には重大な欠点が1つあります。



ビューを再作成するたびに必要です。 これにより、データベースの開発と保守が複雑になります。







小さな免責事項:データベース構造全体が「例」のために作成されており、先頭から取られています。 上記のデメリットなどなく、同じ効果を得る方法を示しています。 はい、ここに書かれていることはすべて、おそらくMySQLに適用できます。




ソリューションを検索する



構造:



CREATE TABLE adv (

id INT,

title TEXT,

info_short TEXT,

info_full TEXT,

is_working BOOLEAN,

can_display BOOLEAN

);









性能:



CREATE VIEW adv_working

AS

SELECT *

FROM adv

WHERE is_working;









ダンプ:



Postgresはこのビューを「展開」しました(したがって、ダンプされます):

CREATE OR REPLACE VIEW "public"."adv_working" (

id,

title,

info_short,

info_full,

is_working,

can_display)

AS

SELECT adv.id, adv.title, adv.info_short, adv.info_full, adv.is_working, adv.can_display

FROM adv

WHERE adv.is_working;






ここで、列とその名前のリストを修正したことがわかります。



分析の説明:



EXPLAIN ANALYZE SELECT * FROM adv_working WHERE id = 123;







結果:



QUERY PLAN

Seq Scan on adv (cost=0.00..17.50 rows=2 width=106) (actual time=0.002..0.002 rows=0 loops=1)

Filter: (is_working AND (id = 123))

Total runtime: 0.028 ms









クエリプランは、postgresが2つの条件を1つに「スタック」することを示しています。「(is_working AND(id = 123))」



私の解決策:



純粋なSQLでフィルタープロシージャを記述しましょう。



CREATE OR REPLACE FUNCTION "public".adv_filter_only_working (adv) RETURNS boolean AS

$body$

SELECT $1.is_working

$body$

LANGUAGE 'sql' IMMUTABLE RETURNS NULL ON NULL INPUT SECURITY INVOKER;









分析の説明:



EXPLAIN ANALYZE SELECT * FROM adv WHERE id = 123 AND adv_filter_only_working(adv);





結果:

QUERY PLAN

Seq Scan on adv (cost=0.00..17.50 rows=2 width=106) (actual time=0.007..0.007 rows=0 loops=1)

Filter: (is_working AND (id = 123))

Total runtime: 0.061 ms









ご覧のとおり、効果は同じですが、プラスもあります。









UPD:彼らは私を理解していないようです。 開発中にテーブルを変更する必要があります。 新機能の追加など。 テーブルの構造の動的な変化については誰も語りません!



All Articles