MySQL中具有匹配列的自然连接

MySQL中具有匹配列的自然连接,mysql,sql,select,natural-join,Mysql,Sql,Select,Natural Join,如果我有两个具有主键联接的表,即两个列具有相同的名称和相同的数据,然后我有一个列名时间戳,这两个表具有相同的名称,但根据它们的表具有不同的数据,该怎么办。我还能用自然连接吗?或者是否有一种变通方法考虑到我需要在两个表中都使用SELECT*,而不使用别名?不要使用自然联接!这是一件令人憎恶的事。它甚至不考虑正确声明的外键关系 您可能会发现USING子句非常有用: select . . . from a join b using (pk); 自然联接的另一个问题是联接键未列出。

如果我有两个具有主键联接的表,即两个列具有相同的名称和相同的数据,然后我有一个列名时间戳,这两个表具有相同的名称,但根据它们的表具有不同的数据,该怎么办。我还能用自然连接吗?或者是否有一种变通方法考虑到我需要在两个表中都使用SELECT*,而不使用别名?

不要使用
自然联接
!这是一件令人憎恶的事。它甚至不考虑正确声明的外键关系

您可能会发现
USING
子句非常有用:

select . . .
from a join
     b
     using (pk);
自然联接的另一个问题是联接键未列出。如果出现问题,这会使调试代码变得非常困难。您遇到了
时间戳
列的问题


如果确实使用了
USING
,则可以使用
SELECT*
,并且
USING
键在
SELECT
中只出现一次。有时,这会很方便。

有许多修复程序,可以组合使用:

•确保每个数据元素名称在其架构中是unqiue。例如,与其依赖
updated\u date
属性通过其出现在
companys
表中的上下文来获得意义,不如将其命名为
company\u name\u updated\u date

•将实体属性和审计属性分离到不同的基表中,例如
公司
表中的
公司名称
,以及公司审计表中的
公司名称更新日期
。将它们放在不同的模式中也可能有意义

•使用视图进行防御性编码:这可能是您无论如何都应该做的事情。考虑给定用户(用例、应用程序等)的可用性,创建一组视图来公开这些属性并根据需要授予特权。不要向不需要查看的用户公开审核列

•在查询中进行防御性编码(“动态”):使用驱动表仅投影查询所需的列,因此,如果将新列添加到现有列中,则不会对该查询进行“突破性更改”。Exmaple:

WITH c AS ( SELECT company_id, company_name FROM Companies ),
p AS ( SELECT employee_id, company_name FROM Payroll )
SELECT * FROM c NATURAL JOIN p;

如果我将其作为子查询运行,是否会出现重复的列错误?@Ari7。虽然我建议显式列出列,但在子查询中使用
SELECT*
可能会很有用。这在您的情况下不起作用,因为您有重复的
TIMESTAMP
列。但是,连接密钥不会重复。感谢@Gordon Linoff给出的答案。我需要在子查询中运行类似的操作,因此有没有一种方法可以避免遇到重复列错误,而不会产生别名。如果有别的办法,如果你能告诉我怎么做就太好了。@AntC。经过几十年的经验,我非常仔细地选择了列和表的名称。几乎我所有的表都有名为
createdAt
createdBy
createdOn
的列,这就排除了自然联接的使用。这是一个独立的问题,因为它们没有使用正确声明的外键关系,并且使查询比备选方案更不稳定和更容易出错。查询在设计时没有考虑外键约束。这完全取决于是否需要时间戳列中的值来匹配。是吗?@DourHighArch不,我时间戳中的值将不相同。。