loading..
Русский    English
08:46
листать

Графовые базы данных SQL Server

Кардинальным отличием графовых баз данных в SQL Server от графовых баз данных направления NoSQL является то, что для моделирования графа в SQL Server используются таблицы. Это таблицы двух специальных видов. Один вид таблиц используется для создания узлов, и другой – для создания ребер (связей). Отметим, что табличное представление узлов и ребер дает возможность писать запросы к этим таблицам на языке SQL.

Таблица типа узла описывает некую сущность. Экземпляры этой сущности представлены строками таблицы и характеризуются одинаковым набором свойств (столбцами таблицы). Таблица типа ребра определяет характер и направление связи между узлами. Скажем, таблица ToBeFriends (дружить) могла бы описывать дружественную связь между экземплярами одной или разных сущностей.

Вероятно, пора переходить к примерам. Предлагаю взять учебную базу «Окраска», и отобразить реляционную структуру этой базы на структуру графа без потери информации. Это позволит нам писать запросы и сравнивать результаты на двух моделях, представляющих в разной форме одну и ту же информацию.

Итак, у нас есть два типа узлов, представляющих сущности квадрата и баллона, и одна связь между ними, которую можно выразить так: баллон окрашивает квадрат. Направление связи – от баллона к квадрату.

Создадим таблицы узлов:

  1. --Квадраты
  2. CREATE TABLE utqG (
  3.     q_id INT PRIMARY KEY,
  4.     q_name VARCHAR(35) NOT NULL,
  5. ) AS NODE;
  6. --Баллончики
  7. CREATE TABLE utvG (
  8.     v_id INT PRIMARY KEY,
  9.     v_name VARCHAR(35) NOT NULL,
  10.     v_color char(1) NOT NULL
  11. ) AS NODE;

Как видите, таблицы создаются аналогично обычным реляционным за исключением указания типа – AS NODE (т.е. узел). Теперь посмотрим на структуру созданных таблиц:

  1. SELECT table_name, column_name, data_type
  2. FROM information_schema.COLUMNS
  3. WHERE table_name='utqG';

table_name    column_name    data_type
utqG    graph_id_AA21DCF7CB44457BB308B21482806B87    bigint
utqG    $node_id_EEFDE0FB86F243E4A6667A5CE470F4F6    nvarchar
utqG    q_id   int
utqG    q_name    varchar

При создании таблицы узлов, помимо пользовательских, автоматически создаются еще два псевдостолбца – graph_id и $node_id. Давайте наполним таблицу данными и посмотрим, что находится в этих столбцах.

  1. INSERT INTO utqG(q_id, q_name)
  2. SELECT * FROM [sql-ex]..utq;

Здесь мы просто берем готовые данные, которые находятся в учебной базе данных с именем sql-ex.

  1. SELECT TOP 2 * FROM utqG;

$node_id_EEFDE0FB86F243E4A6667A5CE470F4F6    q_id    q_name
{"type":"node","schema":"dbo","table":"utqG","id":0}    1    Square # 01
{"type":"node","schema":"dbo","table":"utqG","id":1}    2    Square # 02

Столбец graph_id отсутствует в выборке. Причиной является то, что этот столбец используется ядром СУБД и недоступен пользователю напрямую. Действительно, если выполнить запрос

  1. SELECT graph_id FROM utqG;
то мы получим сообщение об ошибке:

Недопустимое имя столбца "graph_id".

Столбец $node_id является уникальным идентификатором узла, представленным в формате JSON. Шестнадцатеричный суффикс в имени столбца делает имя столбца глобально уникальным, однако для доступа к столбцу он не используется. Например,

  1. SELECT TOP 2 $node_id, q_id FROM utqG;

$node_id_EEFDE0FB86F243E4A6667A5CE470F4F6    q_id
{"type":"node","schema":"dbo","table":"utqG","id":0}    1
{"type":"node","schema":"dbo","table":"utqG","id":1}    2

Таблица utvG выглядит аналогично таблице utqG, и поэтому мы не будем представлять тут её содержимое.

Теперь создадим таблицу ребра.

  1. CREATE TABLE utbG (
  2.     b_datetime datetime NOT NULL,
  3.     b_vol tinyint NOT NULL,
  4. ) AS EDGE;

Эта таблица содержит столбцы свойств – время окраски (B_datetime) и количество нанесенной из баллончика краски (b_vol). Она отличается от таблиц узлов типом – теперь это EDGE, а не NODE. Рассмотрим структуру этой таблицы:

  1. SELECT column_name, data_type
  2. FROM information_schema.COLUMNS WHERE table_name='utbG';

column_name    data_type
graph_id_9D6121CFD14948A5B03BBD6A4BDB4774    bigint
$edge_id_EAB5B85BC07649ED89435D6F2A2ACE83    nvarchar
from_obj_id_D0D5B23329B5409895672D5C32283E51    int
from_id_526FECFDEBB84E86B2F7440FF625BCF1    bigint
$from_id_BF1E69FB306E4225A58F4DAFAA8FBE94    nvarchar
to_obj_id_14C309807A224F7BA7BD8F88425A15AB    int
to_id_295F2F2BD42A425CAAD6ACC9F2174BC7    bigint
$to_id_79504454FC184B7F849B1AB28BCCC670    nvarchar
b_datetime    datetime
b_vol    tinyint

Как и для узлов, автоматически были созданы несколько псевдостолбцов, среди которых доступными пользователю являются:

  • $edge_id – идентификатор ребра, формируется автоматически;
  • $from_id – идентификатор узла, откуда исходит ребро;
  • $to_id – идентификатор узла, куда входит ребро.

Заполним и эту таблицу данными. Если мы вспомним структуру исходной таблицы utb, то для каждой строки в столбец $from_id мы должны поместить идентификатор того узла из таблицы utvG, для которого v_id равен b_v_id таблицы utb. Тогда столбец $to_id должен содержать идентификатор того узла из таблицы utqG, для которого q_id равен, соответственно, b_q_id из той же строки таблицы utb. Читателю, наверное, будет проще понять оператор, который вставит описанные данные:

  1. INSERT INTO utbG(b_datetime, b_vol, $from_id, $to_id)
  2. SELECT b_datetime, b_vol,
  3. (SELECT $node_id FROM utvG WHERE v_id = orig.b_v_id),
  4. (SELECT $node_id FROM utqG WHERE q_id = orig.b_q_id)
  5. FROM [sql-ex]..utb orig

Теперь мы можем посмотреть на данные в таблице ребра, которая устанавливает связь между двумя узлами – баллончиком с краской и окрашиваемым квадратом.

  1. SELECT TOP 1 * FROM utbG;

Поскольку ширина результирующей таблицы значительно превышает ширину страницы, представим результат в формате «ключ: значение»

$edge_id_EAB5B85BC07649ED89435D6F2A2ACE83: {"type":"edge","schema":"dbo","table":"utbG","id":0}
$from_id_BF1E69FB306E4225A58F4DAFAA8FBE94: {"type":"node","schema":"dbo","table":"utvG","id":49}
$to_id_79504454FC184B7F849B1AB28BCCC670: {"type":"node","schema":"dbo","table":"utqG","id":21}
b_datetime: "2000-01-01 01:13:36.000"
b_vol: 50

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 Больше тэгов
Учебник обновлялся
несколько дней назад
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.
Rambler's Top100