Обход дерева для поиска наиболее "логичных" 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 существует множество возможных решений, и идеальное решение основано на некотором ограничении системы. Я не думаю, что вы получите большую выгоду от своего решения, так как чаще всего вы обнаружите, что это всего лишь одна комбинация объединений таблиц, которая предоставит вам необходимые данные.