ИМХО, это в основном проблема нормализации. Столбец с именем «id» не имеет однозначного адреса строки, поэтому он никогда не может быть PK. Необходим как минимум новый (суррогатный) ключ (элемент). Само ограничение не может быть выражено как выражение «внутри строки», поэтому оно должно быть выражено в терминах FK.
Таким образом, он разбивается на две таблицы: одна с PK = id и FK REFERENCING two.sid
Два с суррогатным ключом PK= и идентификатором FK ССЫЛКА на one.id Исходное «значение» полезной нагрузки также находится здесь.
«Однобитовая переменная» исчезает, потому что ее можно выразить в терминах СУЩЕСТВУЕТ. (фактически таблица one указывает на строку, содержащую токен)
[Я ожидаю, что система правил Postgres может использоваться для использования вышеупомянутой модели с двумя таблицами для эмуляции предполагаемого поведения OP. Но это был бы уродливый взлом...]
РЕДАКТИРОВАТЬ/ОБНОВИТЬ:
Postgres поддерживает частичные/условные индексы. (не знаю о ms-sql)
DROP TABLE tmp.one;
CREATE TABLE tmp.one
( sid INTEGER NOT NULL PRIMARY KEY -- surrogate key
, id INTEGER NOT NULL
, status INTEGER NOT NULL DEFAULT '0'
/* ... payload */
);
INSERT INTO tmp.one(sid,id,status) VALUES
(1,1,0) , (2,1,1) , (3,1,0)
, (4,2,0) , (5,2,0) , (6,2,1)
, (7,3,0) , (8,3,0) , (9,3,1)
;
CREATE UNIQUE INDEX only_one_non_zero ON tmp.one (id)
WHERE status > 0 -- "partial index"
;
\echo this should succeed
BEGIN ;
UPDATE tmp.one SET status = 0 WHERE sid=2;
UPDATE tmp.one SET status = 1 WHERE sid=1;
COMMIT;
\echo this should fail
BEGIN ;
UPDATE tmp.one SET status = 1 WHERE sid=4;
UPDATE tmp.one SET status = 0 WHERE sid=9;
COMMIT;
SELECT * FROM tmp.one ORDER BY sid;
person
wildplasser
schedule
20.10.2011
Status 1
строка для каждого идентификатора или не более одной? т.е. разрешено ли иметь идентификатор без строкиStatus 1
? - person Andriy M   schedule 22.10.2011