Ali*_*Ali 4 database-design database-recommendation hierarchy
我正在用 PHP 编写一个私人消息传递 Web 应用程序,该应用程序允许回复,这样当您查看消息时,您还可以看到回复的是什么,回复的是什么以及回复的是什么回复等等等等。
我正在尝试找到一个可以避免冗余的正确数据库结构,所以我想知道如何将单个消息链接到它正在回复的所有其他消息?
我想基本上有一个名为 reply_id 的字段,它是一个序列化的数组,其中包含要作为回复呈现的所有消息的 ID
有没有人有关于如何有效地做到这一点的建议?我的想法是一个好习惯吗?
使用免费开源数据库PostgreSQL显示的语法
您需要一个自引用表,它在数据库中创建层次结构。这是它的样子。
CREATE TABLE messages (
ts_entered timestamp DEFAULT now(),
reply_to int REFERENCES messages,
id int PRIMARY KEY
GENERATED BY DEFAULT AS IDENTITY,
content text
);
CREATE INDEX ON messages (reply_to, id);
Run Code Online (Sandbox Code Playgroud)
请注意,reply_id在非常表上引用了一个 id。在一个更企业化的示例中,我们可能会使其EXCLUDE相同id。
然后我们像这样输入测试数据。
INSERT INTO messages ( reply_to, id, content )
VALUES
( null, 1, 'SYN'),
( 1, 2, 'SYN-ACK'),
( 2, 3, 'ACK'),
( null, 4, 'We should give free advertising to PLAN EXPLORER'),
( 4, 5, 'Admins should disclose their affiliations with products'),
( 5, 6, 'BANNNN'),
( 4, 7, 'Plan Explorer only works on one database'),
( 7, 8, 'BANNNN'),
( 4, 9, 'Plan Explorer does not support Linux'),
( 9, 10, 'BANNNN'),
( 4, 11, 'Plan Explorer only does what decent databases already do'),
( 11, 12, 'BANNNN')
;
Run Code Online (Sandbox Code Playgroud)
现在为了查询这个,我们需要一个RECURSIVE CTE.
WITH RECURSIVE t(reply_to, id, content, root, level)
AS (
SELECT reply_to, id, content, ARRAY[id], 0
FROM messages
WHERE reply_to IS NULL
UNION ALL
SELECT messages.reply_to, messages.id, messages.content, root + ARRAY[messages.id], t.level+1
FROM t
JOIN messages
ON (messages.reply_to = t.id)
)
SELECT * FROM t
ORDER BY root;
Run Code Online (Sandbox Code Playgroud)
你已经完成了..
reply_to | id | content | root | level
----------+----+----------------------------------------------------------+-----------+-------
| 1 | SYN | {1} | 0
1 | 2 | SYN-ACK | {1,2} | 1
2 | 3 | ACK | {1,2,3} | 2
| 4 | We should give free advertising to PLAN EXPLORER | {4} | 0
4 | 5 | Admins should disclose their affiliations with products | {4,5} | 1
5 | 6 | BANNNN | {4,5,6} | 2
4 | 7 | Plan Explorer only works on one database | {4,7} | 1
7 | 8 | BANNNN | {4,7,8} | 2
4 | 9 | Plan Explorer does not support Linux | {4,9} | 1
9 | 10 | BANNNN | {4,9,10} | 2
4 | 11 | Plan Explorer only does what decent databases already do | {4,11} | 1
11 | 12 | BANNNN | {4,11,12} | 2
(12 rows)
Run Code Online (Sandbox Code Playgroud)