SQL 服务器:具有软删除功能的 Graph-DB 未按预期工作
SQL Server : Graph-DB with soft delete isn't working as expected
我尝试使用 SQL 服务器中的图形功能。现在我遇到了软删除问题。
我有下图
[1] -> [2] -> [9 (deleted)] -> [4]
当我运行下面的脚本
CREATE TABLE MyNode
(
[Id] [bigint] NOT NULL,
[IsDeleted] [bit] NOT NULL,
) AS NODE;
CREATE TABLE MyEdge
(
State [int] NOT NULL
) AS EDGE;
INSERT INTO MyNode (Id, IsDeleted)
VALUES (1, 0), (2, 0), (4, 0), (9, 1);
INSERT INTO MyEdge
VALUES
( (SELECT $node_id FROM MyNode WHERE Id = 1), (SELECT $node_id FROM MyNode WHERE Id = 2), 1),
( (SELECT $node_id FROM MyNode WHERE Id = 2), (SELECT $node_id FROM MyNode WHERE Id = 9), 1),
( (SELECT $node_id FROM MyNode WHERE Id = 9), (SELECT $node_id FROM MyNode WHERE Id = 4), 1)
;
SELECT
src.Id ID_SOURCE
, LAST_VALUE(trgt.Id) WITHIN GROUP (GRAPH PATH) AS ID_TARGET
, STRING_AGG(trgt.Id, '->') WITHIN GROUP (GRAPH PATH) AS ID_CHAIN
--, STRING_AGG(compare.State, '->') WITHIN GROUP (GRAPH PATH) AS STATE_CHAIN
--, STRING_AGG(trgt.IsDeleted, '->') WITHIN GROUP (GRAPH PATH) AS DELETED_CHAIN
FROM
MyNode AS src
, ( SELECT
*
FROM
MyEdge
WHERE
State = 1
) FOR PATH AS compare
, ( SELECT
*
FROM
MyNode
WHERE
IsDeleted = 0
) FOR PATH AS trgt
WHERE
MATCH ( SHORTEST_PATH( src(-(compare)->trgt)+ ) )
AND src.Id = 1;
SELECT
src.Id AS SOURCE_ID
, ed.State AS EDGE_STATE
, trgt.Id AS TARGET_ID
FROM
MyNode AS src
, MyEdge AS ed
, MyNode AS trgt
WHERE
MATCH( src-(ed)->trgt )
AND src.Id = 2;
DROP TABLE MyNode;
DROP TABLE MyEdge;
(提示:这仅适用于 SQL-Server 2019)
我得到以下结果
ID_SOURCE
ID_TARGET
ID_CHAIN
1
2
2
1
4
2->4
没有边 2->4
但 2->9->4
。但是节点 9 被删除,因此它用于图形遍历但在输出中被抑制。
这是 SQL 服务器中的错误还是我做错了什么?
或者还有其他方法可以使用 Graph-DB 软删除吗?
您可以过滤掉边缘from/to 软删除节点
....
(
SELECT e.*
FROM MyEdge as e
WHERE
e.State = 1
and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$to_id)
--and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$from_id)
) FOR PATH AS compare
....
不知何故,以下查询 returns 出错(执行几秒后):
SELECT
src.Id ID_SOURCE
, LAST_VALUE(trgt.Id) WITHIN GROUP (GRAPH PATH) AS ID_TARGET
, STRING_AGG(trgt.Id, '->') WITHIN GROUP (GRAPH PATH) AS ID_CHAIN
--, STRING_AGG(compare.State, '->') WITHIN GROUP (GRAPH PATH) AS STATE_CHAIN
--, STRING_AGG(trgt.IsDeleted, '->') WITHIN GROUP (GRAPH PATH) AS DELETED_CHAIN
FROM
MyNode AS src
,
(
SELECT e.*
FROM MyEdge as e
WHERE
e.State = 1
and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$to_id)
--and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$from_id)
) FOR PATH AS compare
, ( SELECT
*
FROM
MyNode
WHERE
IsDeleted = 0
) FOR PATH AS trgt
WHERE
MATCH ( SHORTEST_PATH( src(-(compare)->trgt)+ ) )
...并且通过将 condition/reference 附加到 src table 来消除错误,这始终为真:
AND src.Id = src.Id --or src.IsDeleted = src.IsDeleted
肯定有问题 [Microsoft SQL Server 2019 (RTM-CU8-GDR) (KB4583459)]..
将 isDeleted 标志合并到边 table 中,并在相应的 (to/from) 节点被标记为软删除时更新该标志,并在边上使用 isDeleted table 子查询,是首选方式。我们不建议直接比较 $node_id 和 $from_id,除非通过 MATCH 函数隐式比较。
我尝试使用 SQL 服务器中的图形功能。现在我遇到了软删除问题。
我有下图
[1] -> [2] -> [9 (deleted)] -> [4]
当我运行下面的脚本
CREATE TABLE MyNode
(
[Id] [bigint] NOT NULL,
[IsDeleted] [bit] NOT NULL,
) AS NODE;
CREATE TABLE MyEdge
(
State [int] NOT NULL
) AS EDGE;
INSERT INTO MyNode (Id, IsDeleted)
VALUES (1, 0), (2, 0), (4, 0), (9, 1);
INSERT INTO MyEdge
VALUES
( (SELECT $node_id FROM MyNode WHERE Id = 1), (SELECT $node_id FROM MyNode WHERE Id = 2), 1),
( (SELECT $node_id FROM MyNode WHERE Id = 2), (SELECT $node_id FROM MyNode WHERE Id = 9), 1),
( (SELECT $node_id FROM MyNode WHERE Id = 9), (SELECT $node_id FROM MyNode WHERE Id = 4), 1)
;
SELECT
src.Id ID_SOURCE
, LAST_VALUE(trgt.Id) WITHIN GROUP (GRAPH PATH) AS ID_TARGET
, STRING_AGG(trgt.Id, '->') WITHIN GROUP (GRAPH PATH) AS ID_CHAIN
--, STRING_AGG(compare.State, '->') WITHIN GROUP (GRAPH PATH) AS STATE_CHAIN
--, STRING_AGG(trgt.IsDeleted, '->') WITHIN GROUP (GRAPH PATH) AS DELETED_CHAIN
FROM
MyNode AS src
, ( SELECT
*
FROM
MyEdge
WHERE
State = 1
) FOR PATH AS compare
, ( SELECT
*
FROM
MyNode
WHERE
IsDeleted = 0
) FOR PATH AS trgt
WHERE
MATCH ( SHORTEST_PATH( src(-(compare)->trgt)+ ) )
AND src.Id = 1;
SELECT
src.Id AS SOURCE_ID
, ed.State AS EDGE_STATE
, trgt.Id AS TARGET_ID
FROM
MyNode AS src
, MyEdge AS ed
, MyNode AS trgt
WHERE
MATCH( src-(ed)->trgt )
AND src.Id = 2;
DROP TABLE MyNode;
DROP TABLE MyEdge;
(提示:这仅适用于 SQL-Server 2019)
我得到以下结果
ID_SOURCE | ID_TARGET | ID_CHAIN |
---|---|---|
1 | 2 | 2 |
1 | 4 | 2->4 |
没有边 2->4
但 2->9->4
。但是节点 9 被删除,因此它用于图形遍历但在输出中被抑制。
这是 SQL 服务器中的错误还是我做错了什么?
或者还有其他方法可以使用 Graph-DB 软删除吗?
您可以过滤掉边缘from/to 软删除节点
....
(
SELECT e.*
FROM MyEdge as e
WHERE
e.State = 1
and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$to_id)
--and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$from_id)
) FOR PATH AS compare
....
不知何故,以下查询 returns 出错(执行几秒后):
SELECT
src.Id ID_SOURCE
, LAST_VALUE(trgt.Id) WITHIN GROUP (GRAPH PATH) AS ID_TARGET
, STRING_AGG(trgt.Id, '->') WITHIN GROUP (GRAPH PATH) AS ID_CHAIN
--, STRING_AGG(compare.State, '->') WITHIN GROUP (GRAPH PATH) AS STATE_CHAIN
--, STRING_AGG(trgt.IsDeleted, '->') WITHIN GROUP (GRAPH PATH) AS DELETED_CHAIN
FROM
MyNode AS src
,
(
SELECT e.*
FROM MyEdge as e
WHERE
e.State = 1
and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$to_id)
--and exists(select * from MyNode as x where x.IsDeleted = 0 and x.$node_id = e.$from_id)
) FOR PATH AS compare
, ( SELECT
*
FROM
MyNode
WHERE
IsDeleted = 0
) FOR PATH AS trgt
WHERE
MATCH ( SHORTEST_PATH( src(-(compare)->trgt)+ ) )
...并且通过将 condition/reference 附加到 src table 来消除错误,这始终为真:
AND src.Id = src.Id --or src.IsDeleted = src.IsDeleted
肯定有问题 [Microsoft SQL Server 2019 (RTM-CU8-GDR) (KB4583459)]..
将 isDeleted 标志合并到边 table 中,并在相应的 (to/from) 节点被标记为软删除时更新该标志,并在边上使用 isDeleted table 子查询,是首选方式。我们不建议直接比较 $node_id 和 $from_id,除非通过 MATCH 函数隐式比较。