Articles

마이크로소프트 쿼터 서버의 그래프–(지금은)부족했던 시도)

Posted by admin
트란 응옥 타흐
트란 응옥 타크

팔로우

2020 년 6 월 29 일·9 분 읽기

면책 조항:이 문서의 의견은 혼자 내입니다. 나는 어떤 식으로든 서버 전문가가 아니다. 나는 네오 4 에 편향 될 수있다.

이 틈새 시장에서 그래프 데이터베이스의 사용 증가와 네오포제이의 지배력,그리고 고도로 연결된 데이터를 쿼리하는 데있어 상당한 성능 향상으로 인해 마이크로 소프트는 이러한 메가 트렌드에서 벗어나고 싶지 않다는 것을 이해할 수있다.

2017 년부터MATCH키워드를 도입하여 그래프 기능을 제공했다. 2019 버전에서는 에지 제약 조건과MATCH쿼리에서 파생 테이블 사용이라는 두 가지 새로운 주목할만한 기능이 추가되었습니다. 이 기술에서 충분히 다이빙,나는 인상을 가지고,지금 현재로:

  • 기능 추가는 천천히 증분됩니다.
  • 그래프 기능은 관계형 데이터베이스 사고 방식에 마지 못해 맞습니다.

의 세부 사항에 들어가 보자!

장점&단점

MATCH키워드는 제 생각에는 구문 설탕 일뿐입니다. 보다는 오히려:

SELECT *
FROM NodeTable1 nt1 JOIN EdgeTable et ON nt1.$node_id = et.$from_id JOIN NodeTable2 nt2 ON nt2.$node_id = et.$to_id

… 사용자는 쿼리를 다음과 같이 거의 단축 할 수 있습니다:

SELECT *
FROM NodeTable1 nt1, EdgeTable et, NodeTable2 nt2
WHERE MATCH(nt1-(et)->nt2)

단축 된 쿼리는 의심 할 여지없이 눈에 즐겁습니다. 그러나 세계에서 엔터티 프레임워크는 데이터 지향 소프트웨어 응용 프로그램에 대 한 선호 될 수 있습니다. 개발자는 프레임 워크가 높은 수준의 추상화에 초점을 맞추는 동안 최적의 쿼리를 생성 할 수 있습니다. 이 논리에 의해MATCH의 즐거운 효과는 갑자기 무의미합니다. 더 나쁜 것은 엔티티 프레임 워크(코어)에서 이러한 그래프 기능을 지원하는 로드맵이 없다는 것입니다.

네오포제이와 비교해 보면,위의 쿼리를 다시 살펴보면,사용자들이 그래프 사고 방식을 관계형 데이터베이스 세계로 구부리는 것은 불가피하다. 우리는 여전히 일치를 수행하기 위해FROM절에서 어떤 테이블을 미리 선언해야합니다(오히려’통과 가능한 모든 것’으로 간주되는 그래프이어야하며 상세한 데이터 조직에 신경 쓸 필요가 없습니까?). MATCH에서 화살표 방향을 아는 것이 필수 일 때,사용자는 소스 노드와 대상 노드를 구별해야한다는 의미에서MATCH절과 원래JOIN절 사이의 1-1 매핑을 깨닫게됩니다. 이 구문은 다음과 같습니다. 모든 사람들은 반드시 게임 체인저 아니다;단순히 편리함과 개발의 기쁨의 문제. (나중에,첫 번째 연구 사례에서,우리는 이것 때문에UNION ALL을해야한다는 것을 알게 될 것입니다.)

연결된 데이터를 순회할 때 네이티브 그래프 데이터베이스의 고성능의 핵심 중 하나는 인덱스가 없는 인접성입니다. 이 기능은 다음과 같습니다:

우리는 모든 노드에서 인접 목록을 유지하지 않고 대신 테이블에 에지 데이터를 저장하고 있습니다. 관계형 데이터베이스이기 때문에 테이블 형태로 데이터를 저장하는 것은 우리에게 더 자연스러운 선택이었습니다

또 다른 성가신 문제는 스키마와 데이터 모두에 대해 그래프에 맞게 조정 된 시각화 도구가 없다는 것입니다. 그러나 이러한 노드 및 에지 테이블은 에지 제약 조건이 있는 경우에도 개별 연결이 끊어진 테이블로 끝납니다. 무엇보다도 그래프 기술은 시각적 호소력을 가져와 사용자가 올바른 쿼리를 구성 할 수 있도록해야합니다. 이러한 도구가 부족한 것은 실망스럽고 개발자의 생산성에 해 롭습니다.

그래프 테이블 다이어그램

그래프 스키마를 얻으려면 어떻게해야합니까? 각 가장자리 테이블을 열어 제약 조건을 수동으로 확인한 다음 종이 조각을 사용하여 전체 그래프 스키마를 파악합니다.

그래프의 가장자리 제약

데이터 시각화와 관련하여 힘 지향 그래프 애드온으로 마이크로 소프트 파워 바이를 시도했습니다. 즉,노드 및 에지 테이블을 일반 데이터베이스 테이블로 간주합니다. 열 목록을 자세히 살펴보면 이상한 모양의 열 이름이 있습니다(예:graph_id_...,from_obj_id...). 노드/에지 테이블을 만들 때 자동으로 생성되는 내부 열이며 외부에서 액세스 할 수 없습니다. 이러한 열에 액세스하는 경우 전원 바이의 데이터 가져 오기 기능에 의해 아래와 같이 오류가 발생합니다.

이 문제를 해결하려면 관련/도달 가능한 열만 포함하는 데이터베이스 뷰를 만들어야합니다. 에지 테이블의from_idto_id,노드 테이블의node_id. 그런 다음 전원 바이에서 해당 뷰를 통해 데이터를 추출합니다. 바라건대 나는 착각하지 않는다,힘 바이의 힘 지시 그래프는 열로 구성된 하나의 단일 테이블을 필요로하는 것 같다Source, Target, Weight, Source Type, Target Type, Link Type. 우리의 샘플 스키마는 단순하므로이 단일 테이블을 만드는 것은 간단합니다. 스키마에+20 개의 노드 테이블과+10 개의 에지 테이블이 포함 된 경우 전체 그래프를 파워 바이로 시각화하기 위해 단일 테이블로 끝낼 수 있습니까?

#04.07.2020 에 업데이트 됨: 두 번째 생각에,이 여전히 성가신 경우에도 확실히 가능하다. 모든 노드의 공유 속성(예:Name또는Id)으로 변환하기 위해 각 노드에서$from_id$to_id이 관련 노드 테이블에 조인되는 가장자리 테이블에서 시작해야합니다. 그런 다음UNION ALL모두 전원 바이에 필요한 최종 단일 테이블에 결합 할 수 있습니다.

노드와 에지를 쿼리하는 것은 그래프 기술의 가능성 중 하나입니다. 그래프 데이터베이스를 돋보이게 할 수있는 것은 페이지 랭크 및 루뱅 커뮤니티 탐지(일명)와 같은 그래프 알고리즘에 대한 내장 된 아직 확장 가능한 지원입니다. 루뱅 모듈성). 슬프게도 다시 말하지만,이러한 분석 기능은 다음과 같이 그래프에서 사용할 수 없습니다.:

일부 그래프 데이터베이스는”최단 경로”또는”페이지 순위”와 같은 전용 그래프 분석 기능을 제공합니다.”이 릴리스에서는 이러한 기능을 제공하지 않습니다. 이러한 시나리오에 대한 해결 방법을 작성하는 데 사용할 수 있습니다.

네오 4 제이에서는 그래프 데이터 과학 라이브러리 덕분에 이러한 알고리즘을 생산 등급에서 쉽게 사용할 수 있습니다. 게다가,그것은 오픈 소스입니다. 일반적으로 문서는 도움이되지만 언젠가는 충분하지 않습니다. 오픈 소스를 통해 개발자는 특정 알고리즘이 구현되는 방법을 다운로드하고 다이빙 할 수 있습니다;또는 추가 로깅 정보와 함께 라이브러리를 다시 컴파일하여 더 이해할 수 있습니다. 그러나 루뱅 모듈성과 같은 더 복잡한 알고리즘은 어려울 수 있습니다. 그럼에도 불구하고 많은 소프트웨어 엔지니어는 낮은 수준의 기술적 세부 사항으로 인해 수렁에 빠지는 대신 비즈니스 로직에 더 신경을 쓰는 것을 선호합니다.

마지막으로,내 견해로는 공통 테이블 표현식은 일종의 파생 테이블입니다. 이 기술은 공식적으로 그래프로 실행할 수 있어야합니다:

그래프 테이블과 일치 절

하지만 다음과 같은 경우 뷰 생성,그것은 할 수 있습니다:

그래프 테이블과 일치 절을 사용한 뷰 생성

나는 이것이 불일치의 표시라고 생각합니다. 두 번째 접근 방식에서는 영구적으로 만들어진 뷰가 필요합니다. 일반적으로 사용자는 이 문제를 극복할 수 있지만 위에서 보여준 것처럼 그래프에서는 작동하지 않습니다.

연구 사례

샘플 시나리오:학생 및 교사.

네오 포제이의 사이퍼:

CREATE (S1:NStudents {name: "S1"}), (S2:NStudents {name: "S2"}), (T1:NTeachers {name: "T1"}), (S3:NStudents {name: "S3"}), (T2:NTeachers {name: "T2"}), (S4:NStudents {name: "S4"}), (S1)-->(S2), (S2)-->(T1), (T1)-->(T2), (T2)-->(S4), (S3)-->(T1)

:

CREATE TABLE NStudents ( NVARCHAR(MAX) NOT NULL, INT NOT NULL) AS NODE;CREATE TABLE NTeachers ( NVARCHAR(MAX) NOT NULL, FLOAT NOT NULL) AS NODE;CREATE TABLE Talks (CONSTRAINT EC_Talk CONNECTION (NStudents TO NStudents, NStudents TO NTeachers, NTeachers TO NStudents, NTeachers TO NTeachers) ON DELETE CASCADE) AS EDGE;INSERT INTO NStudents VALUES ('S1',1),('S2',2),('S3',3),('S4',4);
INSERT INTO NTeachers VALUES ('T1',123), ('T2',456);
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S1'),
(SELECT $node_id FROM NStudents WHERE = 'S2'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S2'),
(SELECT $node_id FROM NTeachers WHERE = 'T1'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NTeachers WHERE = 'T1'),
(SELECT $node_id FROM NTeachers WHERE = 'T2'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NTeachers WHERE = 'T2'),
(SELECT $node_id FROM NStudents WHERE = 'S4'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S3'),
(SELECT $node_id FROM NTeachers WHERE = 'T1'));

사례 1:노드의 모든 들어오고 나가는 연결

동기 부여:각 노드에 대해 이러한 연결을 세는 것이 가장 중요한 연결을 찾는 한 가지 방법입니다.

:

MATCH (n)--()
RETURN n.name, COUNT(r) AS allCons
ORDER BY allCons DESC

서버 2019 의 그래프:

--Create a View first, for convenience purpose.
CREATE VIEW view_AllPeople
AS
SELECT $node_id AS ,
FROM NStudents
UNION ALL
SELECT $node_id AS ,
FROM NTeachers;--Query using the View.
WITH CTE()
AS
(
SELECT ap1.
FROM view_AllPeople ap1, Talks t, view_AllPeople ap2
WHERE MATCH(ap1-(t)->ap2)
UNION ALL
SELECT ap1.
FROM view_AllPeople ap1, Talks t, view_AllPeople ap2
WHERE MATCH(ap1<-(t)-ap2)
)
SELECT , COUNT(*) AS allConns
FROM CTE
GROUP BY
ORDER BY allConns DESC

비고: MATCH에서 화살표의 방향이 항상 고려되어야하기 때문에 더 길뿐만 아니라 더 불편합니다.

사례 2:가장 긴 경로

동기 부여:긴 의존성 체인은 깨지기 쉽습니다. 예를 들어,라이브러리 종속성.

:

// The WHERE is to filter out duplicate paths, e.g. A->B = B->A.
MATCH p=(n)--(m)
WHERE ID(n) < ID(m)
RETURN n.name, m.name, length(p) AS len, AS node_list
ORDER BY len DESC

서버 2019 의 그래프:

WITH CTE(from_id, to_id, , )
AS
(
SELECT $from_id, $to_id, 1 AS , CONVERT(NVARCHAR(MAX), $to_id) AS
FROM Talks
UNION ALL
SELECT t.$from_id, t.$to_id, +1, CONVERT(NVARCHAR(MAX), CTE. + ',' + CONVERT(NVARCHAR(MAX), $to_id))
FROM Talks t JOIN CTE ON t.$to_id = CTE.
)
SELECT vap., ,
FROM CTE JOIN (SELECT MAX(c.) AS maxLevel FROM CTE c GROUP BY c.) myMax ON CTE. = myMax.maxLevel JOIN
view_AllPeople vap ON CTE. = vap.
ORDER BY DESC

비고: 에서 서버 버전,하나는 재귀 공통 테이블 표현 기술에 의지해야합니다. 그래프 문제를 해결하기 위해 관계형 데이터베이스 사고 방식을 거의 포용합니다.

결론

이는 코드를 개발하는 데 더 많은 시간이 소요되고 나중에 유지 관리 및 확장하기가 어렵다는 것을 의미합니다. 한 달 후 동일한 코드 스 니펫을 보는 또 다른 엔지니어 또는 원래 엔지니어조차도 모든 측면을 파악하는 것이 좌절감을 느낄 것입니다. 이 상황을 설명하는 잘 알려진 용어는 기술 부채입니다.

코드 측면에서부터 기능 지원,도구/라이브러리 에코시스템에 이르기까지 앞서 언급한 모든 요점들을 결합하면,현재 데이터베이스 서버의 그래프 기능은 고무적이기는 하지만 기대에 미치지 못한다.

관계형 데이터베이스와 관련하여 매우 성숙했지만 그래프 데이터베이스의 초보자는 분명합니다. 이 그래프 지원은 관계형 데이터베이스 정신에 포함 된 것으로 간주 될 수 있습니다.

Related Post

Leave A Comment