从自然连接中排除列
Exclude column from natural join
我目前有以下 PostgreSQL 数据库(图片仅包含基本组件):
基本上:
每个 TX 都有一定数量的 TXIN 和一定数量的 TXOUT,每个 TXIN 由一个 TXOUT 环组成(Monero 交易)
如果我加入 ring
table 与 txin
table 我使用 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 的自然连接
使用 txin/txout 的视图,为这些操作省略 txid
还有其他(更好)的方法吗?如果不是 - 哪种方法是最佳实践?
是不是我的数据库设计有问题,整个问题是否可以通过某种方式规避?
自然连接明确定义为连接所有同名的列。就是这样,它实际上与(如果此语法有效)JOIN table USING (*)
相同。 冗长SQL没有错。非常清楚您的连接条件会更好,也更易于维护,这意味着如果您将来向这些 table 添加一列,它不会弄乱历史数据。在这种情况下,我建议使用显式语法加入,因为这可以清楚地表明数据的来源:
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)
中的单个 table 中但是也许我缺乏完整的上下文。
我会推荐简化的 Oracle 语法:
SELECT *
FROM ring
JOIN txout USING(outid)
JOIN txin USING(inid)
我目前有以下 PostgreSQL 数据库(图片仅包含基本组件):
基本上: 每个 TX 都有一定数量的 TXIN 和一定数量的 TXOUT,每个 TXIN 由一个 TXOUT 环组成(Monero 交易)
如果我加入 ring
table 与 txin
table 我使用 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 的自然连接
使用 txin/txout 的视图,为这些操作省略 txid
还有其他(更好)的方法吗?如果不是 - 哪种方法是最佳实践? 是不是我的数据库设计有问题,整个问题是否可以通过某种方式规避?
自然连接明确定义为连接所有同名的列。就是这样,它实际上与(如果此语法有效)JOIN table USING (*)
相同。 冗长SQL没有错。非常清楚您的连接条件会更好,也更易于维护,这意味着如果您将来向这些 table 添加一列,它不会弄乱历史数据。在这种情况下,我建议使用显式语法加入,因为这可以清楚地表明数据的来源:
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)
中的单个 table 中但是也许我缺乏完整的上下文。
我会推荐简化的 Oracle 语法:
SELECT *
FROM ring
JOIN txout USING(outid)
JOIN txin USING(inid)