Как создать 'двухсторонний' уникальный индекс на двух полях?

Оператор Parallel.Foreach порождает кучу потоков, и мой метод LongRunningTaskInsert () не получает никакого времени. Если я изменяю это на синхронный цикл foreach, мое количество потоков уменьшается с 8 до 4, и я получить ожидаемые результаты (где смешиваются длительные вызовы консоли задач).

5
задан Seun Osewa 23 October 2008 в 12:21
поделиться

4 ответа

Как насчет того, чтобы управлять, что входит в таблицу так, чтобы Вы всегда хранили самое маленькое количество в первый столбец и самое большое во втором? Пока это 'означает' то же самое, конечно. Вероятно, менее дорого сделать это, прежде чем это даже доберется до базы данных.

Если это невозможно, Вы могли бы сохранить поля, как, всего лишь копировали их в числовом порядке в два ДРУГИХ поля, на которых Вы создали бы первичный ключ (псевдо выход кода):

COLUMN A : 2
COLUMN B : 1

COLUMN A_PK : 1  ( if new.a < new.b then new.a else new.b )
COLUMN B_PK : 2  ( if new.b > new.a then new.b else new.a )

Это могло легко быть сделано с триггером (как в ответе Ronald) или обработано выше в приложении.

6
ответ дан 13 December 2019 в 05:44
поделиться

В Oracle Вы могли использовать функциональный индекс как это:

create unique index mytab_idx on mytab (least(a,b), greatest(a,b));

Я не знаю MySQL, но возможно что-то подобное возможно? Например, Вы могли добавить 2 новых столбца leastab и greatestab к таблице, с триггером, чтобы поддержать их со значениями наименьшего количества (a, b) и самый большой (a, b) соответственно, и затем создать уникальный индекс на (leastab, greatestab).

2
ответ дан 13 December 2019 в 05:44
поделиться

Я думаю, что это может только быть сделано с помощью триггера FOR INSERT (в сочетании с ограничением на уникальность данных на два столбца). Я действительно не бегло говорю на синтаксисе MySql (мой T-SQL лучше), таким образом, я предполагаю, что следующее будет содержать некоторые ошибки:

Править: Очищенный синтаксис, таким образом, это работает на MySQL. Кроме того, обратите внимание, что Вы, вероятно, захотите поместить это как a BEFORE UPDATE инициируйте также (с другим именем, конечно).

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

CREATE TRIGGER tr_CheckDuplicates_insert
BEFORE INSERT ON t
FOR EACH ROW
BEGIN
    DECLARE rowCount INT;
    SELECT COUNT(*) INTO rowCount
                   FROM t
                   WHERE a = NEW.b AND b = NEW.a;

    IF rowCount > 0 THEN
        -- Oops, we need a temporary variable here. Oh well.
        -- Switch the values so that the key will cause the insert to fail.
        SET rowCount = NEW.a, NEW.a = NEW.b, NEW.b = rowCount;
    END IF;
END;
3
ответ дан 13 December 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: