如何防止 Postgresql 链表中的循环引用?
How to prevent circular references in a linked list in Postgresql?
table有效数据是这样的:
| id | after_id |
| -- | -------- |
| a | null |
| b | a |
| c | b |
| d | c |
目标是防止类似的事情发生:
| id | after_id |
| -- | -------- |
| a | d | <- 'a' now follows 'd', creating a loop.
| b | a |
| c | b |
| d | c |
如果不存储一些有助于创建约束的附加信息,似乎无法解决此问题。但我无法弄清楚哪些信息会有所帮助。 Postgresql 有 EXCLUDE
约束,我想也许可以以某种方式使用重叠运算符。不知道如何解决这个问题,但我觉得它需要更新太多行,这将破坏在链表中存储序列的全部意义。
更新:
这个想法是确保列表在数据库级别而不是应用程序级别的完整性。无效状态的另一个示例:
| id | after_id |
| -- | -------- |
| a | null |
| b | d | <- updated
| c | b |
| d | c |
或另一个:
| id | after_id |
| -- | -------- |
| a | null |
| b | d | <- updated: followed 'a', now follows 'd'
| c | b |
| d | c |
| e | a | <- updated: followed 'd', now follows 'a', unique constraint on after_id will not be violated this way
This article 似乎与您的问题有关。它谈到避免圈子并设置一个触发器来这样做。
此外,如果您正在查看 PostgreSQL 14,可能会有 native query to detect cycles
table有效数据是这样的:
| id | after_id |
| -- | -------- |
| a | null |
| b | a |
| c | b |
| d | c |
目标是防止类似的事情发生:
| id | after_id |
| -- | -------- |
| a | d | <- 'a' now follows 'd', creating a loop.
| b | a |
| c | b |
| d | c |
如果不存储一些有助于创建约束的附加信息,似乎无法解决此问题。但我无法弄清楚哪些信息会有所帮助。 Postgresql 有 EXCLUDE
约束,我想也许可以以某种方式使用重叠运算符。不知道如何解决这个问题,但我觉得它需要更新太多行,这将破坏在链表中存储序列的全部意义。
更新: 这个想法是确保列表在数据库级别而不是应用程序级别的完整性。无效状态的另一个示例:
| id | after_id |
| -- | -------- |
| a | null |
| b | d | <- updated
| c | b |
| d | c |
或另一个:
| id | after_id |
| -- | -------- |
| a | null |
| b | d | <- updated: followed 'a', now follows 'd'
| c | b |
| d | c |
| e | a | <- updated: followed 'd', now follows 'a', unique constraint on after_id will not be violated this way
This article 似乎与您的问题有关。它谈到避免圈子并设置一个触发器来这样做。
此外,如果您正在查看 PostgreSQL 14,可能会有 native query to detect cycles