Уважаемые читатели!

В нескольких номерах журнала Database Programming & Design известные специалисты в области систем управления базами данных Крис Дейт и Том Джонсон вели интенсивную дискуссию относительно возможных альтернатив для применяемых в языке SQL неопределенных значений и соответственно трехзначной логики. Мы предлагаем вашему вниманию пересказ хронологически последней заметки на эту тему. Она дает представление о дискуссии в целом. Пересказ ведется в первом лице, но это именно краткое изложение сути заметки. Поскольку я не совсем согласен с утверждениями Джонсона относительно связи неопределенных значений и многозначной логики с повышением уровня выразительности языка запросов, в конце текста приведен мой краткий комментарий.

С позицией Дейта по поводу будущих языков баз данных можно ознакомиться в статье Х.Дарвина и К.Дейта "Третий манифест"
(СУБД, N 1, 1996, 110-123).

С уважением, Сергей Кузнецов

The Fault with Defaults

Tom Johnson, independent consultant in Atlanta, tjohnson@acm.org
(Промашка со значениями по умолчанию - игра слов по-английски,
Database Programming & Design On-Line, vol.11, N 2, February 1998,
оригинал статьи можно найти по адресу http://www.dbpd.com/9802xtra.htm)

Я с удовлетворением воспринимал позицию Криса Дейта относительно значений по умолчанию, поскольку ожидал чего-то, что можно было бы использовать вместо неопределенных значений и многозначной логики (MVL - Multi-Valued Logic), предлагаемой SQL. Тогда мы имели бы два способа работы с отсутствующей информацией. С одной стороны, можно было бы использовать консервативную схему применения двузначной логики совместно со значениями по умолчанию. С другой стороны, для любителей дополнительной сложности и повышенной выразительности оставалась бы возможность пользоваться неопределенными значениями и MVL.

Но, к сожалению, в своей серии статей "Faults and Defaults" (ноябрь 1996 г., январь, февраль и апрель 1997 г.) Дейт занялся не этим. Вместо этого он предложил схему "специальных значений" (как он их называет), не поддерживаемую существующими СУБД и требующую отказа использования в SQL MVL и внедрения в язык поддержки альтернативного подхода. Дейт и не отрицает этого, говоря, что "в сегодняшних SQL-ориентированных продуктах могут быть трудности с применением нововведенных понятий", т.е. его схемы со специальными значениями, но "это их проблема" (декабрь 1996 г.).

UNK и равенство

После объяснения того, что его схема потребует заменить каждый домен (скажем, домен XXXX) новым доменом XXXX_OR_UNK, Дейт переходит к рассмотрению различных операций над специальным значением UNK. (Мне кажется, что предложенное Дейтом именование новых доменов может привести к заблуждению, поскольку эти домены содержат как реальные значения, так и UNK, а не одно или другое. Обсуждение Дейта было бы немного более понятным, если бы домены с именами XXXX_OR_UNK понимались как содержащие значения XXXX и значение UNK.) Он начинает с операции установления равенства и после определения операции применительно к специальному значению UNK говорит: "Заметим, что из определения следует, что сравнение 'UNK=UNK' вырабатывает значение true. Здесь нет никакой трехзначной логики!" (январь 1997 г.).

На самом деле, трудно было бы найти лучший пример потребности в трехзначной логике! И поскольку именно этот вопрос определяет то, может ли подход со специальными значениями обеспечить ту же выразительность, что и MVL, мы должны очень тщательно проанализировать утверждение Дейта о UNK и равенстве.

Рассмотрим таблицу с двумя столбцами и 100 строками, каждая из которых содержит пару UNK. Предположим, что домен каждого столбца включает a) целые числа и b) UNK. Следовательно, для каждой строки с реальными значениями в обоих столбцах (числа от 1 до 100) шансы того, что строка содержит одинаковые значения, составляют 1 к 10000 (100*100). Шансы того, что во всех строках значения столбцов будут одинаковы и того меньше (1 к миллиону).

Предположим, что на интерфейс базы данных подается запрос "Сколько строк в этой таблице содержат столбцы с равными значениями" (с использованием схемы со специальными значениями). В соответствии с определением Дейта ответом будет "Все 100". Но поскольку мы не знаем реальных значений чисел во всех строках, шансы того, что этот ответ правильный, составляют 1 к миллиону! Та ли это схема, которую хотелось бы использовать для обращения к базе данных за информацией?

Серьезность последствий неадекватности подхода Дейта зависит от ситуации. Например, предположим, что столбцы чисел - это координаты ста целей, вычисленные независимыми прицельными механизмами для системы наведения ракетного крейсера. Пусть для безопасности применяется правило, что ракета запускается только в том случае, когда прицельные механизмы выдают одинаковые координаты. И, наконец, предположим, что условия стрельбы настолько неудачны, что для всех 100 целей прицельные механизмы не могут вычислить координаты. Поскольку каждый из них работает с доменом TARGETING_COORDINATE_OR_UNK, он занесет в свой столбец значение UNK во всех 100 строках.

Теперь используем интерфейс, основанный на новой схеме Дейта, чтобы определить, по каким из ста целей следует стрелять. Мы сказали: "Стрелять по каждой из 100 целей в том и только в том случае, когда сравнение coordinate1=coordinate2 дает значение true". И все 100 ракет будут запущены, хотя ни один из прицельных механизмов не обеспечил координат ни одной цели!

Конечно, если бы мы догадались добавить к условию конъюнктивное требование истинности сравнения coordinate1 != UNK, то ракеты не были бы запущены.

Если Дейт захочет, он может назвать пересмотренный запрос "решением", но для меня очевидно, что здесь что-то неправильно. Пользователя заставляют компенсировать ошибку в семантике оператора сравнения в схеме Дейта. Она связана с тем, что как всем известно, ответом на вопрос "Равны ли два неизвестных значения" не является "Да". И если Дейт ответит, что при определении равенства специального значения UNK он не имел в виду "неизвестные значения", то он должен признать, что его схема не представляет семантику неизвестных значений "реального мира".

UNK и неравенство: основы

После неудачной попытки определить равенство Дейт переходит к определению операций "больше" и "меньше". Немедленно сталкиваясь с проблемами, он утверждает, что потребность в таких операциях с операндом UNK сомнительна. Попробовав предложить возможную интерпретацию с теми же изъянами как интерпретация равенства, он приходит к мнению, что использование этих операций, когда один или оба операнда есть UNK, "не имеет смысла".

Теперь вы можете видеть, что я имел в виду, говоря, что с точки зрения семантики неправильным в подходе со значениями по умолчанию является то, что семантика этого подхода неверна и мешает получению информации из базы данных (ноябрь 1996 г.; Дейт "полностью не согласен" с этим в апреле 1997 г.). Позиция Дейта приводит к тому, что его схема не может обеспечить пользователей информацией, если какая-либо из этих двух операций используется при наличии UNK. Поэтому я полагаю, что позиция Дейта совместно с некорректностью определения равенства теперь демонстрирует истинность моего утверждения.

UNK, неравенство и реальный мир

До этого места я просто предполагал, что операции сравнения с "больше" и "меньше" имеют смысл при наличии значения UNK. Но я думаю, что Дейт попытался бы доказать, что основным вопросом являются потребности реального мира при столкновении с неизвестными значениями. Если отвергать любой вопрос вида "Является ли значение X большим (или меньшим), чем значение Y", когда значения X, Y или оба неизвестны (что, кстати, является потребностью реального мира), то мы ничем не пожертвуем при использовании подхода Дейта. С другой стороны, нам пришлось бы внимательно отслеживать семантику неизвестных значений при использовании двузначной логики (по крайней мере, для "больше" и "меньше").

Сейчас я покажу, что правильный ответ на запрос с "больше" или "меньше" при наличии неизвестных значений действительно имеет смысл, но этот ответ есть "unknown", поскольку значения одного или обоих операндов неизвестны. (Если это покажется тривиальным, позвольте напомнить, что именно это запрещает схема Дейта.) Попробуем оценить, какое количество информации запрещается использовать схемой Дейта при том, что эта информация содержится в базе данных.

Предположим, что наша таблица представляет 100 вариантов расклада игральных карт двух игроков. Числа от 2 до 14 соответствуют картам от двойки до туза. Первый игрок - Джонс, второй - Смит. Пусть a) в 10 вариантах неизвестны оба значения, b) в 23 вариантах неизвестно только одно значение и c) в оставшихся 67 вариантах известны оба значения. Для этих 67 вариантов предположим, что 42 случаях карта Джонса бьет карту Смита, а 21 случае карта Смита бьет карту Джонса. (Чтобы избежать ненужной сложности допустим, что в случае b) известное значение отличается от 2 и 14.)

Теперь рассмотрим следующие вопросы:

  1. Сколько раз Джонс точно выиграл у Смита?
  2. Сколько раз Джонс мог бы обыграть Смита?
  3. Сколько было точных ничьих?
  4. Сколько могло бы быть ничьих?
Понятно, что ответы на вопросы следующие:
  1. 42
  2. 75 (42 + 10 + 23)
  3. 4
  4. 37 (4 + 10 + 23)
При использовании схемы Дейта были бы получены следующие ответы:
  1. 42
  2. По меньшей мере 42, но не больше 65 (но с 23 вхождениями "вопрос некорректен)
  3. 14 (4 + 10)
  4. По меньшей мере 14 (4 + 10) (но с 23 вхождениями "вопрос некорректен")

Теперь сравним результаты. Для первого вопроса оба подхода дают один и тот же правильный результат.

Для второго вопроса схема Дейта должна была бы определить, что правильный результат - 75, но не смогла этого сделать по причине наличия UDK в качестве операнда в 23 операциях сравнения. Однако в этих 23 случаях Джонс действительно мог выиграть у Смита. Это показывает, что при наличии в базе данных информации схема Дейта не обеспечивает ей пользователей. Кстати, заметим, что правильный ответ (75) находится за пределами диапазона, выданного схемой Дейта, так что полученный на ее основе ответ является не только неточным, но и абсолютно некорректным. Схема Дейта считает те 10 вариантов, в которых оба числа есть UDK, как ничьи, т.е. как случаи с равными значениями. Поэтому они не учитываются в качестве возможных ситуаций выигрыша Джонса у Смита. К сожалению (для Дейта), в реальном мире в этих случаях Джонс мог бы выиграть у Смита.

Для третьего вопроса схема Дейта снова выдает неверный результат. Джонс и Смит точно сыграли вничью в четырех, а не четырнадцати случаях. И это по причине использования правила Дейта: "Сравнение UDK=UDK вырабатывает true... Здесь нет трехзначной логики!"

Конечно, при понимании ограничений схемы Дейта мы могли бы сформулировать запрос по поводу точных ничьих с использованием условия "where column 1 = column 2 and column 1 != UDK and column 2 != UDK". Для такого запроса был бы выдан правильный результат. Но это не решает проблем схемы Дейта, а только перекладывает на плечи пользователя компенсацию фундаментальных ошибок в семантике схемы.

Для четвертого вопроса схема Дейта выдает правильный результат, но менее информативный, чем это возможно, поскольку каждый из 23 вариантов представляет возможную ничью.

Заметим, что СУБД, поддерживающая неопределенные значения и MVL выдала бы именно приведенные выше корректные ответы. При использовании трехзначной логики X = Y, X > Y, X < Y вырабатывают логическое значение uknown, если значение одного или обоих операндов неизвестно. Например, при выработке ответа на четвертый вопрос СУБД с неопределенными значениями и MVL руководствовалась бы следующими соображениями: "Я знаю, что Джонс и Смит сыграли вничью в четырех раскладах. Для 10 вариантов я не знаю ни одной карты, так что они могли бы сыграть вничью в каждом из этих раскладов. В 23 случаях я не знаю одной карты, так что они могли бы сыграть вничью и в этих раскладах. Общее число случаев - 37". Попытка Дейта убедить нас в том, что в реальном мире не используется трехзначная логика, опровергается наличием повседневных соображений такого рода. И снова Дейт проиллюстрировал истинность моего приведенного выше высказывания.

Сложность

В последней части статьи Дейт говорит, что ожидает очевидной реакции на то, что его схема со специальными значениями значительно усложняет запросы. У меня имеются три комментария относительно этого свойства его схемы.

Во-первых, беглый взгляд на критику Дейта многозначной логики показывает, что она в основном опирается на усложненность MVL, в результате чего увеличивается вероятность ошибок. Мне кажется интересным, что теперь Дейт запускает собственную петарду сложности. Возможно, он будет объяснять нам, что сложность MVL плохая и приводит к ошибкам, а сложность его схемы, требующая мастерства от пользователей, хорошая и к ошибкам не приводит.

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

Наконец, я не сомневаюсь, что Дейт найдет много слов в ответ. Но следует понимать, что не обязательно тот, кто говорит слово последним, занимает лучшую позицию.

Практическая схема специальных значений

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

Прежде всего, я согласен с Дейтом в том, что по возможности нам стоит устранить в своих базах данных атрибуты, допускающие неопределенные значения. С некоторыми оговорками (которые здесь не буду разъяснять) я согласен и с тем, что хорошим подходом является расщепление типа сущности с подобным атрибутом на два подтипа. В первом подтипе атрибут не сможет содержать неопределенные значения, а во втором не будет самого этого атрибута.

Во-вторых, я полагаю, что для идентификации специальных значений следует зарезервировать одно или несколько значений из обычного домена атрибута. Все что требуется, это одно значение, которое означает, что "реальное значение отсутствует". Возможно, потребуется различать случаи неприменимости, неизвестности и "то или другое, не знаю точно что". В ответ на часто используемый Дейтом аргумент, что имеется произвольное число различных типов неопределенных значений и, следовательно, потребуется MVL с произвольным числом истинностных значений, я заметил бы, что мне кажется наивным полагать необходимость наличия формально отличаемого вида неопределенных значений для каждого способа формулировки условия отсутствия значения на естественном языке. В книге Atzeni и DeAntonellis "Relational Database Theory" (Benjamin/Cummings, 1993) показано, что любое такое условие можно свести к одному из упомянутых выше.

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

Однако иногда это невозможно. Если на предприятии допускаются счета нулевого размера, то наличие в столбце значения "$000,000,00" будет означать a) счет нулевого размера и b) "реальное значение отсутствует". Чтобы разобраться с подобными омонимами, требуются дополнительные расходы. Выходом из положения является добавления флага, отличающего нулевые счета ото всех остальных, или использование в качестве специального значения менее критичного и очень редко используемого реального значения (например, "$999,999,98"). В последнем случае мы не устраняем расходы на различение омономов, но существенно их сокращаем. На самом деле, этот вид стратегии удешевленного использования омонимов использовался десятки лет.

Наконец, заметим, что стратегия избежания омонимов с использованием некоторого значения для идентификации "отсутствия реального значения", не значащего ничего больше, предоставляет ту же выразительную мощность (и те же сложности), что схема Дейта со специальными значениями. Собственно, стратегия состоит в том, чтобы найти представление UNK внутри обычного домена, а не заставлять производителей СУБД расширять этот домен.

Новая схема Дейта является альтернативой MVL с неправильно определенной операцией сравнения по равенству, полным отсутствием операций сравнения на больше и меньше, невозможностью получать полную информацию из базы данных и существенным усложнением написания даже простых запросов. Более того, теперь, когда мы понимаем, как далека схема Дейта от реализации, видно, что наши дебаты не имеют непосредственного отношения к практической разработке и использованию баз данных. И проектировщики, и пользователи будут продолжать работать при наличии ограничений, свойственных применяемым диалектам SQL.

Консерваторы будут избегать использовать неопределенные значения и MVL, осмотрительно остерегаясь сложности. Чтобы им помочь, я кратко изложил практический подход к управлению отсутствующей информации, который может быть использован при наличии сегодняшних продуктов баз данных. Этот подход не претендует на оригинальность и лишь немного расширяет существующую практику.

Более рисковые пользователи будут использовать неопределенные значения и, возможно, иногда им придется обжигаться. Но постепенно у них составится понимание сути неопределенных значений и MVL, которое невозможно получить при чтении книг.


Комментарий С.Кузнецова

Я полностью согласен с мнением господина Джонсона относительно ряда некорректностей в схеме, предложенной господином Дейтом. Однако я не могу согласиться с тем, что использование неопределенных значений и многозначной логики во всех случаях повышает выразительность языка и позволяет более естественно и просто пользоваться всей содержащейся в базе данных информацией, чем если ограничиться использованием выделенного значения "значение неизвестно" и двузначной логики.

Все дело в том, что (по крайней мере в языке SQL) логическое значение unknown является запрещающим, т.е. если для некоторой строки таблицы условие выборки вычисляется в unknown, то строка не входит в результирующую таблицу запроса. По этому поводу трехзначная логика действительно помогает более сжато формулировать условия ограничения, но никак не содействует извлечению из базы данных возможной информации.

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


(coordinate1 = coordinate2) OR ((coordinate1 IS NOT NULL) AND

(coordinate2 IS NULL)) OR ((coordinate1 IS NULL) AND (coordinate2 IS NOT NULL))

Попробуйте написать это по-другому! Здесь в чистом виде работает двузначная логика и специальное значение NULL. Трехзначная логика не помогает.

Аналогично обстоят дела в более простом случае второго примера: "Сколько раз Джонс и Смит смогли бы сыграть вничью?". Понятно, что хотелось бы написать условие в виде:


((column1 = column2) = true) OR ((column1 = column2) = unknown)

Но в языке SQL в таком виде условия задавать нельзя (да если бы и было можно, то так ли это просто и естественно?). Поэтому придется переформулировать условие следующим образом:


(column1 = column2) OR (column1 IS NULL) OR (column2 IS NULL)

Это ровно то же самое, что потребовалось бы написать при использовании схемы Дейта для получения корректного ответа. Опять работает двузначная логика и специальное значение NULL.

Ну и где же здесь повышение выразительной мощности и упрощение формулировки запросов?