Какие операции БД одновременно идемпотентны и коммутативны?

Я исследовал фреймворки / оболочки Scala DB и наткнулся на Gizzard из Twitter. Хотя сначала я был впечатлен, но охладился, когда прочитал ограничение. Они говорят, что все операции с БД должны быть идемпотентными и коммутативными. Если я правильно понимаю, от этого практически ничего не остается. Например, если у меня есть объект с целочисленным счетчиком, который нужно увеличить. Я могу использовать либо операцию «приращения», либо операцию «установить». Но приращение не будет идемпотентным (если вы запустите его дважды, вы получите другой результат, а затем запустите его один раз), и set не будет коммутативным (установка сначала 5, а затем 2 дает другой результат, затем установка первых двух, а затем 5). Осталось ли что-нибудь, кроме «вставить-если-отсутствует», что не очень полезно для большинства случаев использования. В чем смысл структуры распределенной базы данных, которая настолько ограничена, что вы в принципе не можете сделать с ней ничего полезного? Должно быть, я упускаю что-то важное.

[РЕДАКТИРОВАТЬ] Помимо «вставить-если-отсутствует» (и «удалить-если-присутствует»), я думаю, что «сравнить-отметку-время-и-установить» будет как идемпотентным, так и коммутативным, если вместо этого изменения ставятся в очередь отброшенных, когда "предыдущие изменения" все еще отсутствуют. Но я не знаю, реализует ли это какая-либо БД.


person Sebastien Diot    schedule 15.08.2011    source источник


Ответы (2)


Коммутативные операции - это просто операции, которые вызывают монотонный рост значения. Идемпотентными примерами указанных операций являются:

  • Вставка элементов в набор,
  • Установка значения как максимум числа и его предыдущего значения,
person dan_waterworth    schedule 28.10.2011

В общем, идемпотентные действия должны проверять состояние, прежде чем действовать. Применительно к контексту обновлений базы данных это означает проверку состояния данных, которые должны быть изменены, перед обновлением. Например:

update some_table set
some_column = 'some_new_value'
where id = 123
and some_column = 'its_current_value'; -- idempotent check

Если бы это было выполнено дважды, второй вызов бы ничего не сделал.

Чтобы быть коммутативными, два обновления должны повлиять на разные аспекты состояния данных (разные столбцы / строки). То есть действительность каждой идемпотентной проверки не должна зависеть от действия обновления другой команды.

person Bohemian♦    schedule 15.08.2011
comment
Итак, вы можете обновить столбец, проверив, что старое состояние имеет ожидаемое значение, но вы не можете обновить его дважды, потому что, если обновления приходят в неправильном порядке, они оба будут отброшены. Таким образом, это будет работать, только если между двумя обновлениями будет достаточно времени, чтобы вы могли быть уверены, что они поступят в правильном порядке. - person Sebastien Diot; 15.08.2011