LINUX.ORG.RU

Организация ограничений целостности в РСУБД

 ,


0

2

Приветствую всех. Какие распространенные/хорошие/плохие практики есть на случай, если нужно ограничение

  • в контексте таблицы(или даже нескольких), а не строки
  • не реализуемое посредством встроенных механизмов(как, например, unique)
  • желательно иметь производительность хотя бы чуть-чуть повыше плинтуса

БД postgresql, но специфичные для других БД случаи тоже интересны

Deleted

Триггер. Для производительности надо писать правильные запросы и создавать правильные индексы.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Да, первое, что на ум приходит. Но тут детали такие, нехорошие, в общем - невозможно(по крайней мере я не знаю как) написать триггер, не ломающийся в транзакции с неподходящим уровнем изоляции. Как пример:

CREATE TABLE TEST ( ID SMALLINT NOT NULL, SINCE TIME NOT NULL, UNTIL TIME NOT NULL );
CREATE INDEX TEST_ID ON TEST(ID);
CREATE FUNCTION TEST_CHECK() RETURNS TRIGGER LANGUAGE PLPGSQL AS '
	DECLARE VIOLATED BOOLEAN;
	BEGIN
		LOCK TABLE TEST IN SHARE ROW EXCLUSIVE MODE;
		SELECT COUNT(*) <> 0 INTO VIOLATED
		    FROM (SELECT SUM(UNTIL-SINCE) > INTERVAL ''1 DAY'' AS OVERTIMED FROM TEST GROUP BY ID) AS T
		    WHERE OVERTIMED;
		IF VIOLATED THEN RAISE EXCEPTION ''constraint violated''; END IF;
		RETURN NULL;
	END;
';
CREATE TRIGGER TEST_CHANGE AFTER INSERT OR UPDATE ON TEST EXECUTE PROCEDURE TEST_CHECK();
INSERT INTO TEST VALUES (0, TIME '00:00:00', TIME '12:00:00'), (0, TIME '12:00:00', TIME '23:59:59');

------------------------------------------------------

START TRANSACTION ISOLATION LEVEL REPEATABLE READ READ WRITE;
SELECT * FROM TEST;
-- *** вторая транзакция в это же время ***
--START TRANSACTION READ WRITE;
--INSERT INTO TEST VALUES(0, TIME '00:00:00', TIME '00:00:01');
--COMMIT;
INSERT INTO TEST VALUES(0, TIME '00:00:00', TIME '00:00:01');
COMMIT;
И оно не обломает вставку. Поэтому на клиенте БД появляются неявные ограничения(запускать всё на read committed, а если будет мало - орудовать блокировками). А хотелось бы иметь некоторый интерфейс к схеме БД, который сам по рукам даст в случае чего. Может быть я ошибаюсь и всё не так мрачно?

Deleted
()
Ответ на: комментарий от sanwashere

Да, смотрел по диагонали этот механизм, но судя по

The PostgreSQL rule system allows one to define an alternative action to be performed on insertions, updates, or deletions in database tables

Проблемы те же, что и у триггеров

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.