0

我有一个这种结构的表

(int)id | (text)title | (text)description | (int)related

和一个将表与自身连接起来的查询

SELECT t1.*, t2.title as relatedTitle
FROM mytable t1 LEFT JOIN mytable t2 ON t2.related=t1.id

像这样在一个 SELECT 列表中生成

title:你好,description:非正式的问候,see also:你好

当一条新记录存入表时,只能引用另一条记录

单向参考

我试图实现的是交叉引用

交叉引用

可以在 2-5 个对象中

多交叉参考

所有对象都应在每个组合中交叉引用。我想要这个功能:如果related设置,脚本应该自动在相关记录中创建交叉引用。如果记录被删除,脚本应该更新相关记录中的引用。

对于 3+ 交叉引用的记录,我正在考虑这个连接表

(int)id | (int)related

但 5 个交叉引用的对象将是 20 条记录。我也可以创建单列表

(varchar)relatedList

但是如何创建左连接以及如何删除此结构中的关系?或者我应该尝试其他方法,如触发器、视图或临时表?我想避免冗余并使其尽可能简单,只是想不通。

4

3 回答 3

1

如果您的组通常大于 2,那么您应该创建一个组列表 - 如果 A 连接到 B 和 C,它将创建一个组 A、B、C。

因此,一旦插入关系,您就会检查相关项目是否已经在组中。如果已设置,则“新”相关条目也在该组中。

如果没有,您刚刚创建了一个包含这两个项目的新组。

因此,如果在您的示例中“Hi”是单独的,并且“Ho”连接到“Hi”,那么两者都会形成一个新组。当“Ahoi”也连接到“Hi”时,它只需要从 Hi 复制 group_id。

编辑:根据要求选择的评论:

结构:

table groups: group_id int not null primary key auto_increment, created_tmstmp timestamp
table items: item_id int, group_id int default null

选择:

select * from items i1 
inner join items i2 on i2.item_id != i1.item_id 
      and i2.group_id = i1.group_id 
where i1.id = <given item>.

关系的插入可能会连接到其中一个项目的插入,这取决于线程所有者的场景。如果它是两个条目的新关系,则插入一个新组。

其他问题是:一个项目是否只在一个组中?否则需要一个 item_group 表来将一个项目连接到一个以上的组。

没有加入字符串,很抱歉可能被如此残酷地理解。;-)

于 2013-05-26T18:45:28.647 回答
0

和这个一起去:

(int)id | (int)related

这是一种非常常见的方法。

如果您使用列表方法,您的 SQL 查询将非常复杂。

通常,SQL 引擎非常擅长针对具有大量行的表优化查询,因此在最合理的硬件条件下,您不必担心此类表中的数百万行。(当然,这取决于您要使用它的目的。)

要对无向边建模,请始终在id列中插入最低的 id(您可以添加CHECK约束来强制执行此操作)。通过这样做,您将消除一半的元组。

如果您因为要对完整图建模而遇到性能问题,请考虑仅将上表用于“邻居”连接,计算图的完成并将其插入到包含所有项目分区的表中,每个分区一个完整子图:

(int)partition | (int)id

让我们看一个例子。给定项目 (1 .. 8) 和边 (1, 2), (1, 3), (4, 3), (6, 5), (6, 7) - 不包括所需的边完成图表,你得到

(int)id | (int)related
      1 |            2
      1 |            3
      3 |            4
      5 |            6
      6 |            7

(并且没有第 8 项的记录。)

然后在分区表中:

(int)partition | (int)id
             1 |       1
             1 |       2
             1 |       3
             1 |       4
             2 |       5
             2 |       6
             2 |       7
             3 |       8

要检查一个项目是否与另一个项目相关,只需在分区表上进行自连接,但更改图形需要对两个表进行操作。

于 2013-05-26T18:27:15.507 回答
0

正如 mzedeler 所说,通常使用连接表来实现多对多关系。请考虑使用单独的 id 列,以便您获得

Id,rel1,rel2

这样,像 hibernate 这样的框架就会知道该做什么。考虑到您正在谈论传递和对称关系这一事实,这更有意义。因此,对于 4 个相关项目,如果您的脚本进行一些基本推理,则 3 个条目就足够了。当然,如果删除了连接条目,您将需要填补给定关系链中的空白。

于 2013-05-26T18:34:39.470 回答