トリガーを使用して、挿入および更新時にハッシュ列を設定します。SHA-256 の場合は、拡張モジュールの関数を使用しpgcrypto
digest
ます。
PostgreSQL のバージョンを指定していないため、次の例では現在の 9.2 を使用していると仮定します。
sha256 ダイジェスト関数を呼び出す方法は次のとおりです。
regress=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
regress=> SELECT digest('blah', 'sha256');
digest
--------------------------------------------------------------------
\x8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52
(1 row)
CREATE EXTENSION
関数はスーパーユーザーとして実行する必要があることに注意してください。
トリガーはとてもシンプルです。テーブルが次のようになっていると仮定すると、次のようになります。
CREATE TABLE some_table ( key_codes text, hash bytea );
CREATE OR REPLACE FUNCTION hash_update_tg() RETURNS trigger AS $$
BEGIN
IF tg_op = 'INSERT' OR tg_op = 'UPDATE' THEN
NEW.hash = digest(NEW.key_codes, 'sha256');
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER some_table_hash_update
BEFORE INSERT OR UPDATE ON some_table
FOR EACH ROW EXECUTE PROCEDURE hash_update_tg();
使用法:
regress=> INSERT INTO some_table(key_codes) VALUES ('fred');
INSERT 0 1
regress=> SELECT * FROM some_table;
key_codes | hash
-----------+--------------------------------------------------------------------
fred | \xd0cfc2e5319b82cdc71a33873e826c93d7ee11363f8ac91c4fa3a2cfcd2286e5
(1 row)
更新トリガーを条件付きにすることで、トリガー実行のオーバーヘッドを削減できます。上記の代わりに、CREATE TRIGGER
次の両方を使用します。
CREATE TRIGGER some_table_hash_insert
BEFORE INSERT ON some_table
FOR EACH ROW
EXECUTE PROCEDURE hash_update_tg();
CREATE TRIGGER some_table_hash_update
BEFORE UPDATE ON some_table
FOR EACH ROW
WHEN ( NEW.key_codes IS DISTINCT FROM OLD.key_codes )
EXECUTE PROCEDURE hash_update_tg();