如何为支持回复的私人消息系统构建表?

Ali*_*Ali 4 database-design database-recommendation hierarchy

我正在用 PHP 编写一个私人消息传递 Web 应用程序,该应用程序允许回复,这样当您查看消息时,您还可以看到回复的是什么,回复的是什么以及回复的是什么回复等等等等。

我正在尝试找到一个可以避免冗余的正确数据库结构,所以我想知道如何将单个消息链接到它正在回复的所有其他消息?

我想基本上有一个名为 reply_id 的字段,它是一个序列化的数组,其中包含要作为回复呈现的所有消息的 ID

有没有人有关于如何有效地做到这一点的建议?我的想法是一个好习惯吗?

Eva*_*oll 9

分层自引用数据

使用免费开源数据库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)