loading..
Русский    English
01:48
листать

Запросы к графовой базе данных

Восстановить вид исходной таблицы Utb можно с помощью обычного SQL-запроса:

  1. SELECT B.b_datetime, Q.q_id b_q_id, V.v_id b_v_id, B.b_vol 
  2. FROM utbG B JOIN utqG Q ON B.$to_id = Q.$node_id
  3. JOIN utvG V ON B.$from_id = V.$node_id;

Однако для облегчения навигации по графу в SQL Server добавлена функция MATCH, которая задает шаблон для поиска узлов в соответствии со связями. Синтаксис шаблона напоминает образцы, используемые в языке Cypher, графовой базы данных Neo4j.

В упрощенной форме шаблон имеет вид:

  1. <узел, откуда исходит ребро> - (<ребро>) -> <узел, в который входит ребро>

Узел представляется именем таблицы или алиасом (псевдонимом). Алиас необходим, когда одна таблица используется в образце несколько раз, например, в случае самосоединений.  Шаблоны в функции MATCH можно соединять при помощи оператора AND. Перейдем к примерам. Для начала перепишем предыдущий запрос в «графовом» стиле:

  1. SELECT B.b_datetime, Q.q_id b_q_id, V.v_id b_v_id, B.b_vol 
  2. FROM utbG B, utqG Q, utvG V
  3. WHERE match(V-(B)->Q);

Здесь мы используем алиасы только для сокращения записи. Мы можем поменять местами узлы, но направление связи должно сохраниться (от баллончика к квадрату):

  1. SELECT B.b_datetime, Q.q_id b_q_id, V.v_id b_v_id, B.b_vol 
  2. FROM utbG B, utqG Q, utvG V
  3. WHERE match(Q<-(B)-V);

В отличие от Cypher направление связи является обязательным, т.е. использование функции

  1. match(V-(B)-Q);
будет вызывать ошибку. Cypher более гибок в этом отношении; направление можно не указывать, если оно может быть однозначно определено, например, если связь данного типа есть в одном направлении, но нет в другом.

Найти квадраты, которые окрашивались красной краской. Вывести идентификатор квадрата и объем красной краски.

Реляционная схема

Консоль
Выполнить
  1. SELECT b_q_id, SUM(b_vol) qty
  2. FROM utB JOIN utV ON B_V_ID =V_ID
  3. WHERE V_COLOR ='R'
  4. GROUP BY b_q_id;

Графовая схема

  1. SELECT q_id, SUM(b_vol) qty
  2. FROM utbG B, utvG V, utqG Q
  3. WHERE match(V-(B)->Q) AND V_COLOR ='R'
  4. GROUP BY q_id;

Найти квадраты, которые окрашивались как красной, так и синей краской. Вывести: название квадрата.

Реляционная схема

Консоль
Выполнить
  1. SELECT q_name FROM utQ JOIN (
  2. SELECT b_q_id FROM utB JOIN utV ON B_V_ID =V_ID
  3. WHERE V_COLOR ='R'
  4. INTERSECT
  5. SELECT b_q_id FROM utB JOIN utV ON B_V_ID =V_ID
  6. WHERE V_COLOR ='B'
  7. ) X ON Q_ID=b_q_id;

Графовая схема

  1. SELECT DISTINCT q_name
  2. FROM utbG B1,utbG B2, utvG VR, utvG VB, utqG Q
  3. WHERE
  4. match(VR-(B1)->Q<-(B2)-VB) AND VR.V_COLOR ='R' AND VB.V_COLOR ='B';

Обратите внимание, что для в общем случае разных узлов, используемых в шаблоне, требуется добавлять соответствующую таблицу в предложение FROM (как и таблицу связи). Если же подразумевается один и тот же узел, как в нашем случае с квадратом, то мы можем использовать этот узел для двусторонней связи. Предикат

  1. match(VR-(B1)->Q<-(B2)-VB)
можно было также записать в таком виде

  1. match(VR-(B1)->Q) AND match(VB-(B2)->Q)
или в таком

  1. match(VR-(B1)->Q AND VB-(B2)->Q)

DISTINCT в этих запросах необходим, поскольку возможны дубликаты, если квадрат окрашивался несколькими красными (и/или синими) баллончиками.

Найти квадраты, которые окрашивались всеми тремя цветами.

Реляционная схема

Можно было бы добавить еще один запрос к предыдущему решению с помощью INTERSECT, однако давайте представим здесь более эффективное решение, опирающееся на тот факт, что количество уникальных цветов, которыми окрашивался квадрат, равно 3:

Консоль
Выполнить
  1. SELECT q_name FROM utQ JOIN (
  2. SELECT b_q_id
  3. FROM utB JOIN utV ON B_V_ID =V_ID
  4. GROUP BY b_q_id
  5. HAVING COUNT(DISTINCT v_color)=3
  6. ) X ON q_id=b_q_id;

Графовая схема

  1. SELECT DISTINCT Q.q_name
  2. FROM utbG B1,utbG B2,utbG B3, utvG VR, utvG VB, utvG VG, utqG Q
  3. WHERE
  4. match(VR-(B1)->Q<-(B2)-VB AND VG-(B3)->Q)
  5. AND VG.V_COLOR ='G' AND VR.V_COLOR ='R' AND VB.V_COLOR ='B';

Найти баллончики, которыми окрашивали более одного квадрата.

Реляционная схема

Консоль
Выполнить
  1. SELECT v_name FROM
  2. utB JOIN utV ON B_V_ID =V_ID
  3. GROUP BY b_v_id,v_name
  4. HAVING COUNT(DISTINCT b_q_id)>1;

Графовая схема

  1. SELECT DISTINCT v_name
  2. FROM utbG B1,utbG B2, utvG V, utqG Q,utqG Q2
  3. WHERE
  4. match(Q2<-(B2)-V-(B1)->Q) AND Q.q_id <> Q2.q_id;

Условие match(Q2<-(B2)-V-(B1)->Q) утверждает, что один баллон участвовал в двух окрасках, в то время как условие Q.q_id <> Q2.q_id говорит о том, что при этом окрашивались разные квадраты.

Предварительные выводы

На первый взгляд, запросы к реляционной и графовой схемам не так уж радикально отличаются. Более того, синтаксиса графовой базы данных можно не придерживаться, оставаясь в рамках языка SQL. Однако не стоит судить по рассмотренным примерам, поскольку преимущество графовых баз данных проявляется для тех предметных областей, которые характеризуются сложными связями между данными.

Bookmark and Share
Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE CONSTRAINT Convert COUNT CROSS APPLY CTE DATEADD DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FOREIGN KEY FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INFORMATION_SCHEMA INNER JOIN insert INTERSECT IS NOT NULL IS NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker Больше тэгов
Учебник обновлялся
несколько дней назад
продать qiwi
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.
Rambler's Top100