Никто из нас не работает с изолированными записями, мы манипулируем более сложными конструкциями - формальным признанием этого является наличие внешних ключей (foreign keys). Попыток перейти от обработки записей к обработке конструкций, состоящих из них, предпринималось по крайней мере две.
Одна состояла в создании указателя и последовательном перемещении его от записи к записи. В реальности получилось даже хуже: был внедрен ограниченный вариант указателя, называемый курсором (CURSOR), который может перемещаться не по всей базе данных, а только в пределах одной таблицы [1]. Наличие более одного одновременно открытого курсора указывает, что мы работаем фактически с иерархическими данными, а не с декартовыми произведениями. А применение оператора LOOP (мы же не используем его для формирования декартовых произведений!) говорит о том, что мы заставили человека трассировать работу машины, а наш оператор является калькой с ассемблерной мнемоники LOOP. Решение откровенно неприемлемое, приводящее к непроизводительному [2] расходованию человеческого времени. Выходом является манипулирование целым деревом сразу, а не обработка индивидульных записей. Предлагаю осудить использование курсоров и не рекомендовать их к дальнейшему использованию.
Другая состояла в отказе от нотации WHERE field1=field2 и обращении к синтаксису tablename1(_, X), tablename2(X, _). Авторов [3] не смутил тот факт, что этот синтаксис труден как в изучении, так в контроле промежуточных результатов выполнения программы, что было уже известно на примере первородного Пролога. Провал японской программы ЭВМ пятого поколения лишь подтвердил неюзабельность этого решения. Последствия этой второй попытки были поистине ужасны: в стандарт SQL:1999 была введена конструкция WITH RECURSIVE - теперь человек стал отслеживать итератор в прологовском стиле. Как будто кальки с ассемблерной мнемоники не хватало. Разумеется, также предлагаю осудить использование конструкции WITH RECURSIVE и не рекомендовать ее к дальнейшему использованию.
Почему когда мы пишем адрес на конверте, мы не используем указатель для стран, указатель для городов, указатель для улич, а перечисляем "записи разных таблиц" через запятую? Почему когда мы пишем путь в shell-е по файловой системе, мы не создаем функцию, вызывающую саму себя, а перечисляем "записи одной таблицы" через слэш? То же самое мы делаем, когда пишем путь на XPath. Почему в тех случаях мы оставляем конкретную реализацию в за кадром, а в случае SQL не догадываемся??.
Что мешает повторить это очевидно хорошее решение, указав требования к записям в WHERE и перечислив таблицы, в которых записи находятся, через другой знак, отличный от запятой и слэша - 'tablename1.tablename2.tablename3 WHERE field1a=field2a and field2b=field3b' [4]? И если дерево ветвится, взять обе его ветви в скобки 'tablename1.(tablename2.tablename3 tablename7.tablename8)'. А, например, в операторе UPDATE указывать, с каких точках дерева должны происходить обновление полей 'UPDATE tablename1.tablename2.tablename3 SET field2c=5 WHERE field1a=field2a and field2b=field3b)'.
Рассмотрим SQL/XML как способ извлечения иерархических данных (а не как способ оформления иерархических данных в xml-виде). Использование SQL/XML-функций, равно как и синтаксиса проприетарного веб-сервера [5], дают очень громоздкий код, который тяжело писать. В то же время обычно извлекаются записи, уже связанные внешним ключом - мы имеем дерево, уже сформированное в схеме базы данных. Предлагаю лаконичное 'select a.b.c' для выбора данных из таких уже связанных таблиц 'a', 'b', 'c' [6] (предполагается, что таблицы ссылаются друг на друга только одним внешним ключом, и что две таблицы не ссылаются друг на друга одновременно [7]).
Например, для нахождения самого дешевого маршрута между городами
[1] В общем случае представления (view)
[2] Человек должен формулировать решение, а не прослеживать выполнение отдельных команд. Оставим в стороне тот факт, что этот подход приводит к посторяющимся пересылкам отдельных записей на сервер и обратно, забивает трафик, сужает полосу пропускания, жрет ресурсы машин
[3] 1978 год, Herve Gallaire и Jack Minker провели семинар, посвященный этой теме; 1980 год, David Maier ввел термин "даталог", datalog (DATAbase + proLOG, очевидно)
[4] Желательно через какой-нибудь много меньший буквы, чтобы свободное пространство естественным образом разделяло названия таблиц, например через точку
[6] Но ничего не стоит соединить два дерева (BTT), как это показано на с.25
Тюрин Дмитрий, dmitryturin@yandex.ru