У меня есть база данных postrges, таблица содержит коды ключей, которые я создал с помощью функции python. Я хотел бы иметь возможность хэшировать этот столбец таким образом, что каждый раз, когда к нему добавляется ключевой код, ключ хешируется. Как я могу получить postgres для этого? Или что будет лучшим способом для хранения этих кодов. Вот пример столбца, который я хотел бы использовать в моей таблице.
key_codes |
-----------+
L7G4J83K |
J70KG169 |
L69E540K |
GL8E9C3J |
6C0LE215 |
9G01C8JA |
1G9KC58A |
Ответ 1
С помощью триггера установите столбец хеша при вставке и обновлении. Для SHA-256 используйте pgcrypto
digest
модуля расширения pgcrypto
.
Поскольку вы не указали свою версию PostgreSQL, я предполагаю, что вы используете текущий 9.2 в следующих примерах.
Здесь, как вызвать функцию digest 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();