Обход дерева для поиска наиболее "логичных" SQL-соединений между двумя таблицами

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

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

Я также хочу добавить функциональность, которая не требует модели отчета. Мое приложение сканирует целевую базу данных SQL и создает виртуальную модель со всеми сопоставленными объединениями и полями.

После этого мне нужно будет создать наиболее "логичный" или эффективный путь между таблицами, например, с минимальным количеством объединений. Вроде как сценарий коммивояжера.

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

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

 public Node<T> findClosestObjToNode(Node<T> node, T obj)
    {
        Boolean matchFound = false;
        List<Node<T>> toSearch = new List<Node<T>>();
        List<Node<T>> toSearchNext = new List<Node<T>>();
        toSearchNext.Add(node); //add proimary node to search list

        while(!matchFound){
            toSearch.AddRange(toSearchNext); //copy the searchnext list to search
            toSearchNext.Clear();

            foreach(Node<T> _node in toSearch){
                if (node.contains(obj)) //check for existance of object in the nodes children
                    return node.getChild(obj); //return the child node that contains the object
                else
                    foreach (Node<T> cNode in node.getChildren()) //no matching object found in child nodes
                        toSearchNext.Add(cNode); //so add each child node to the list of nodes to search
            }
            if(toSearchNext.Count == 0) //no match found
                return null;
        }
        return null;
    }

Мой вопрос действительно Похоже ли то, что я запланировал выше, на приличное решение всей проблемы, или есть лучший способ сделать это, чтобы получить более точные объединения таблиц.

1 ответ

Решение

Если я правильно понял ваши требования, то я ставлю под сомнение ваш подход к этой проблеме. Как правило, способов получения определенного фрагмента данных из базы данных не так много, как правило, существует один и только один способ получить этот конкретный фрагмент данных. С проблемами типа TSP существует множество возможных решений, и идеальное решение основано на некотором ограничении системы. Я не думаю, что вы получите большую выгоду от своего решения, так как чаще всего вы обнаружите, что это всего лишь одна комбинация объединений таблиц, которая предоставит вам необходимые данные.

Другие вопросы по тегам