我目前有以下PostgreSQL DB(图片仅包含必要组件):
基本上: 每个TX都有一些TXIN和一些TXOUT,每个TXIN包含一个TXOUT的RING(Monero事务)
如果我使用ring
表加入txin
表,我使用select * from ring natural join txin
并使用inid
进行加入。
ring
和txout
相同,但它加入outid
。
txin
和txout
也可以使用自然联接tx
加入,以获得合理的输出。
(预期)唯一不起作用的是:
select * from txout natural join ring natural join txin;
因为它会加入ring(inid) = txin(inid)
和ring(outid) = txout(outid)
(这是所需的),但也加入txin(txid) = txout(txid)
这是不可取的。
我有一些想法如何解决这个问题:
使用显式连接(在我看来,使一些查询非常麻烦),例如以上将是:select * from txout join ring using (outid) join txin using (inid);
重命名txin或txout中的两个txid列之一,并放弃使用tx的自然连接
使用省略txid的txin / txout视图进行这些操作
还有其他(更好)的方式吗?如果不是 - 哪种方法最佳实践? 我的数据库设计是否缺乏,整个问题可以以某种方式被规避?
答案 0 :(得分:2)
自然连接被明确定义为连接所有具有相同名称的列。这就是它的实际情况,它与(如果此语法有效)JOIN table USING (*)
实际上相同。 详细SQL 没有任何问题。在你的加入条件下非常清楚它是更好,更易于维护的,并且它意味着如果你将来在这些表中添加一列它不会弄乱历史数据。在这种情况下,我建议使用显式语法加入,因为这样可以清楚地显示数据的来源:
SELECT *
FROM txout to
INNER JOIN ring r ON (to.outid = r.outid)
INNER JOIN txin ti ON (r.inid = ti.inid)
这里要清楚。自然连接不是一个可维护的解决方案,它们非常适合将视图混合在一起,但模式更改,如果您在显式连接上使用自然连接,则会遇到问题。
我不确定您为什么设计数据库的方式,看起来数据有意重叠,可以全部放在(txid, inid, outid, txhash)
的单个表中,但也许我缺乏完整的背景。
答案 1 :(得分:0)
我建议使用简化的Oracle语法:
SELECT *
FROM ring
JOIN txout USING(outid)
JOIN txin USING(inid)