나는 매우 초보자 친화적 인 프론트 엔드를 만들기위한 의도로 보고서 빌더와 유사한 애플리케이션을 작성합니다.두 테이블 간의 가장 논리적 인 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;
}
내 질문은 정말입니다. 내가 위에서 계획 한 방식이 전체적인 문제에 대한 적절한 해결책처럼 보이는지, 아니면 더 정확한 테이블 조인을 위해 위의 작업을 수행하는 더 좋은 방법인지 알 수 있습니다.
그럴 수도 있습니다. 그렇다면 내 솔루션을 통해 여전히 동적으로 가입 할 수 있습니까? 정적 인접 목록을 만들 필요가 없습니다. –
예, 이론적으로 그렇습니다. 그러나 당신은 당신의 접근 방식에 대한 단점을 고려 해본 적이 있습니까? 데이터베이스 스키마가 변경되면 가상 모델을 새로 고칠시기를 알아야합니다. 매번 모델을 만들려고한다면 테이블과 필드의 수가 증가 할 때 장기간에 어떤 일이 발생합니까? 솔루션에 성능 문제가 발생할 수 있습니다. –
예, 이것에 대해 생각해 보았습니다. 내 솔루션은 해당 데이터베이스의 구조를 캐싱하고 응용 프로그램로드시 대상 데이터베이스를 다시 검색하는 것입니다. 나는 짧은 시간에 상당한 데이터베이스를 스캔 할 수있는 쿼리를 만들었습니다. 나는 이것을 기존 모델과 비교할 수있다. 다시로드해야합니다. 그러나 나는 인접성 목록을 생성하고 탐색하는 것과 비교하여 이것의 성능을 측정해야 할 것입니다. –