私が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
ご覧のとおり、効果は同じですが、プラスもあります。
- 列数に同順位はありません。
- 恐れることなく他の列の名前を変更できます。
- 列を安全に削除することもできます。
- 機能的なインデックスを作成できますが、ロジックはまだ1つの場所にあります(インデックスで複製する必要はありません)。
UPD:彼らは私を理解していないようです。 開発中にテーブルを変更する必要があります。 新機能の追加など。 テーブルの構造の動的な変化については誰も語りません!