我有分层的父子数据。我希望有一个嵌套的视图,我可以查询该数据。似乎将这个嵌套集视图保存到表中最安全的方法是它实际上是原始数据的postgresql视图。
raw_data (
id INTEGER PRIMARY KEY,
parent INTEGER NULL
)
我正在寻找一种方法来转换raw_data
nested_set_view
作为视图创建语句的一部分。
nested_set_view (
id INTEGER PRIMARY KEY,
lft INTEGER NOT NULL,
rgt INTEGER NOT NULL
)
出于某种原因,我想象如果nested_set_view
就像
nested_set_view (
id INTEGER PRIMARY KEY,
lft INTEGER NOT NULL,
rgt INTEGER NOT NULL,
root INTEGER NOT NULL
)
答案 0 :(得分:0)
CAVEAT(S)
这就是我们如何实现一个与你提议的结构非常相似的结构
以下代码块创建实体化视图:
WITH
RECURSIVE cell_paths
(
id_cell ,
id_parent,
id_path ,
name_path
) AS
(
SELECT
tbl_cell.pkid ,
tbl_cell.fk_parent ,
ARRAY[tbl_cell.pkid] AS "array",
ARRAY[tbl_cell.cell_name] AS "array"
FROM
tbl_cell
WHERE
(
tbl_cell.fk_parent IS NULL)
UNION ALL
SELECT
tbl_cell.pkid ,
tbl_cell.fk_parent ,
(cell_paths_1.id_path || tbl_cell.pkid),
(cell_paths_1.name_path || tbl_cell.cell_name)
FROM
(cell_paths cell_paths_1
JOIN
tbl_cell
ON
((
tbl_cell.fk_parent = cell_paths_1.id_cell)))
WHERE
(
NOT (
tbl_cell.pkid = ANY (cell_paths_1.id_path)))
)
SELECT
cell_paths.id_cell ,
cell_paths.id_parent,
(
SELECT
COUNT(*) AS COUNT
FROM
tbl_cell x
WHERE
((
cell_paths.id_cell = x.pkid)
AND (
EXISTS
(
SELECT
1
FROM
tbl_cell y
WHERE
(
x.pkid = y.fk_parent))))) AS has_child,
cell_paths.id_path ,
cell_paths.name_path ,
array_to_string(cell_paths.name_path, ' -> '::text) AS string_path
FROM
cell_paths
ORDER BY
cell_paths.id_path;
每当我们需要更新视图时,都会调用以下函数
CREATE OR REPLACE FUNCTION "public"."fn_refresh_mvw_cellpath" () RETURNS trigger
VOLATILE
AS $dbvis$
BEGIN
REFRESH MATERIALIZED VIEW mvw_cellpath;
RETURN NEW;
END;
$dbvis$ LANGUAGE plpgsql
从功能定义可以看出,我们决定每当对表进行更改时都必须更新视图。在这种情况下我们的表tbl_cell
CREATE TRIGGER "tr_refresh_mvw_cellpath"
AFTER INSERT OR DELETE OR UPDATE ON tbl_cell
FOR EACH STATEMENT
EXECUTE PROCEDURE fn_refresh_mvw_cellpath()
此触发器将在每次更新或插入tbl_cell时执行刷新视图调用。这样我们可以保证物化视图是最新的。当然,您需要决定运行刷新的成本是否值得。可能你只需要每天更新一次视图或....
希望这有帮助。
(激动人心:我的第一篇文章是stackoverflow。希望我以正确的方式做到了。)