🔵SQL X Cypher/Neo4j: какие друзья моих друзей являются моими врагами?

В этом посте мы сравним запрос, сделанный с помощью SQL, и тот же запрос, сделанный с помощью CYPHER — языка Neo4j. Мы будем искать, какие друзья моих друзей являются моими врагами. Мы будем использовать персонажей из аниме «Наруто».

  • Neo4j
    • Neo4j — Создание символов
    • Neo4j — Создание дружеских отношений
    • Neo4j — Создание отношений вражды
    • Neo4j — Создание запроса
  • SQL
    • SQL — Создание символов
    • SQL — Создание дружеских отношений
    • SQL — Создание отношений вражды
    • SQL — Выполнение запроса
  • Заключение

Neo4j — Создание символов

CREATE (:Ninja {name: 'Naruto Uzumaki'})
CREATE (:Ninja {name: 'Sasuke Uchiha'})
CREATE (:Ninja {name: 'Sakura Haruno'})
CREATE (:Ninja {name: 'Gaara'})
CREATE (:Ninja {name: 'Rock Lee'})
CREATE (:Ninja {name: 'Orochimaru'})
Войдите в полноэкранный режим Выход из полноэкранного режима

Neo4j — Создание дружеских отношений

Друзья Наруто

MATCH (naruto :Ninja),(sakura :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  sakura.name = 'Sakura Haruno'
CREATE (naruto)-[:FRIEND_OF]->(sakura)
RETURN naruto, sakura
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (naruto :Ninja),(rock :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  rock.name = 'Rock Lee'
CREATE (naruto)-[:FRIEND_OF]->(rock)
RETURN naruto, rock
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (naruto :Ninja),(gaara :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  gaara.name = 'Gaara'
CREATE (naruto)-[:FRIEND_OF]->(gaara)
RETURN naruto, gaara
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (n) RETURN n
Войдите в полноэкранный режим Выход из полноэкранного режима

Друзья Сакуры

MATCH (sakura :Ninja),(sasuke :Ninja)
WHERE sakura.name = 'Sakura Haruno' AND  sasuke.name = 'Sasuke Uchiha'
CREATE (sakura)-[:FRIEND_OF]->(sasuke)
RETURN sakura, sasuke
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (sakura :Ninja),(rock :Ninja)
WHERE sakura.name = 'Sakura Haruno' AND  rock.name = 'Rock Lee'
CREATE (sakura)-[:FRIEND_OF]->(rock)
RETURN sakura, rock
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (n) RETURN n
Войдите в полноэкранный режим Выход из полноэкранного режима

Neo4j — Создание отношений вражды

Враги Наруто

MATCH (naruto :Ninja),(sasuke :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  sasuke.name = 'Sasuke Uchiha'
CREATE (naruto)-[:ENEMY_OF]->(sasuke)
RETURN naruto, sasuke
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (naruto :Ninja),(orochimaru :Ninja)
WHERE naruto.name = 'Naruto Uzumaki' AND  orochimaru.name = 'Orochimaru'
CREATE (naruto)-[:ENEMY_OF]->(orochimaru)
RETURN naruto, orochimaru
Войдите в полноэкранный режим Выход из полноэкранного режима
MATCH (n) RETURN n
Войдите в полноэкранный режим Выход из полноэкранного режима

Neo4j — Создание запроса

Друзья Наруто

MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
RETURN friends
Войдите в полноэкранный режим Выход из полноэкранного режима

Друзья друзей Наруто:

MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
MATCH (friends)-[:FRIEND_OF]->(friends_of_friends)
RETURN friends_of_friends
Войдите в полноэкранный режим Выход из полноэкранного режима

Друзья друзей Наруто, которые являются врагами Наруто:

MATCH (naruto :Ninja {name:'Naruto Uzumaki'})-[:FRIEND_OF]->(friends)
MATCH (friends)-[:FRIEND_OF]->(friends_of_friends)
MATCH (naruto)-[:ENEMY_OF]->(friends_of_friends)
RETURN naruto,friends_of_friends
Войдите в полноэкранный режим Выход из полноэкранного режима

SQL — Создание символов

CREATE TABLE ninjas(
    id SERIAL PRIMARY KEY,
    name VARCHAR(255)
);

INSERT INTO 
    ninjas (name) 
VALUES
    ('Naruto Uzumaki'),
    ('Sasuke Uchiha'),
    ('Sakura Haruno'),
    ('Gaara'),
    ('Rock Lee'),
    ('Orochimaru');

SELECT * FROM ninjas;
Войдите в полноэкранный режим Выход из полноэкранного режима

SQL — Создание дружеских отношений

CREATE TABLE friends(
    id SERIAL PRIMARY KEY,
    ninja_1 INTEGER,
    ninja_2 INTEGER,
    FOREIGN KEY (ninja_1) REFERENCES ninjas (id),
    FOREIGN KEY (ninja_2) REFERENCES ninjas (id),
    UNIQUE(ninja_1, ninja_2)
);

-- Amigos do Naruto:
INSERT INTO 
    friends (ninja_1, ninja_2) 
VALUES
    (1, 3),
    (1, 4),
    (1, 5);

-- Amigos da Sakura:
INSERT INTO 
    friends (ninja_1, ninja_2) 
VALUES
    (3, 2),
    (3, 5);

SELECT * FROM friends;
Войдите в полноэкранный режим Выход из полноэкранного режима

SQL — Создание отношений вражды

CREATE TABLE enemies(
    id SERIAL PRIMARY KEY,
    ninja_1 INTEGER,
    ninja_2 INTEGER,
    FOREIGN KEY (ninja_1) REFERENCES ninjas (id),
    FOREIGN KEY (ninja_2) REFERENCES ninjas (id),
    UNIQUE(ninja_1, ninja_2)
);

-- Inimigos do Naruto:
INSERT INTO 
    enemies (ninja_1, ninja_2) 
VALUES
    (1, 2),
    (1, 6);

SELECT * FROM enemies;
Войдите в полноэкранный режим Выход из полноэкранного режима

SQL — составление запроса

Друзья Наруто

SELECT DISTINCT
  f.ninja_2,
  (SELECT name FROM ninjas WHERE id = f.ninja_2)
FROM 
  ninjas n,
  friends f
WHERE 
  f.ninja_1 = 1;
Войдите в полноэкранный режим Выход из полноэкранного режима

Друзья Сакуры:

SELECT DISTINCT
  f.ninja_2,
  (SELECT name FROM ninjas WHERE id = f.ninja_2)
FROM 
  ninjas n,
  friends f
WHERE 
  f.ninja_1 = 3;
Войдите в полноэкранный режим Выход из полноэкранного режима

Друзья друзей Наруто:

SELECT DISTINCT
  f.ninja_2,
  (SELECT name FROM ninjas WHERE id = f.ninja_2)
FROM 
  ninjas n,
  friends f
WHERE 
  f.ninja_1
IN
(
    SELECT DISTINCT
      f.ninja_2
    FROM 
      ninjas n,
      friends f
    WHERE 
      f.ninja_1 = 1
);
Войдите в полноэкранный режим Выход из полноэкранного режима

Друзья друзей Наруто, которые являются врагами Наруто:

SELECT 
    e.ninja_2,
    (SELECT name FROM ninjas WHERE id = e.ninja_2)
FROM 
    enemies e
WHERE
    ninja_2 
IN
(
    SELECT DISTINCT
      f.ninja_2
    FROM 
      ninjas n,
      friends f
    WHERE 
      f.ninja_1
    IN
    (
        SELECT DISTINCT
          f.ninja_2
        FROM 
          ninjas n,
          friends f
        WHERE 
          f.ninja_1 = 1
    )
);
Войдите в полноэкранный режим Выход из полноэкранного режима

Заключение

Мы можем сделать вывод, что этот запрос гораздо проще выполнить с помощью языка Cypher. В таких случаях хорошо использовать базу данных графов, например Neo4j. Если у кого-то есть более простой способ выполнить этот запрос с помощью SQL, пожалуйста, оставьте свой комментарий 🙂

Оцените статью
Procodings.ru
Добавить комментарий