据我所知,许多 DBMS(例如 mysql、postgres、mssql)仅使用 fk 和 pk 组合来限制对数据的更改,但它们本身很少用于自动选择要连接的列(就像自然连接与名称一样)。这是为什么?如果你已经用 pk/fk 定义了 2 个表之间的关系,为什么数据库不能弄清楚如果我加入这些表我想在 pk/fk 列上加入它们?
编辑:澄清一下:
假设我有一个 table1 和一个 table2。table1 在 a 列上有一个外键,它引用 table2 上的主键,即 b 列。现在,如果我加入这些表,我将不得不做这样的事情:
SELECT * FROM table1
JOIN table2 ON table1.a = table2.b
Run Code Online (Sandbox Code Playgroud)
但是,我已经使用我的键定义了 table1.a 引用 table2.b,所以在我看来,让 DBMS 系统自动使用 table1.a 和 table2.b 作为连接列应该不难,这样就可以简单地使用:
SELECT * FROM table1
AUTO JOIN table2
Run Code Online (Sandbox Code Playgroud)
然而,许多 DBMS 似乎并没有实现这样的东西。
小智 36
在很多情况下,连接两个表的方法不止一种;有关许多示例,请参阅其他答案。当然,可以说在这些情况下使用“自动连接”是错误的。然后只剩下少数可以使用它的简单案例。
但是,有一个严重的缺点!今天正确的查询,明天可能会因为向同一个表添加第二个 FK 而变成错误!
让我再说一遍:通过添加列,不使用这些列的查询可能会从“正确”变成“错误”!
这是一个维护噩梦,任何理智的风格指南都会禁止使用此功能。select *出于同样的原因,大多数已经禁止了!
如果性能得到提高,所有这些都是可以接受的。然而,事实并非如此。
总而言之,这个特性只能在有限的简单情况下使用,不会提高性能,而且大多数风格指南无论如何都会禁止它的使用。
因此,大多数数据库供应商选择将时间花在更重要的事情上也就不足为奇了。
小智 28
外键用于限制数据。即强制参照完整性。就是这样。没有其他的。
同一个表可以有多个外键。考虑以下货物有起点和终点的情况。
table: USA_States
StateID
StateName
table: Shipment
ShipmentID
PickupStateID Foreign key
DeliveryStateID Foreign key
Run Code Online (Sandbox Code Playgroud)
您可能希望根据取件状态加入。也许你想加入交货状态。也许您想为两者执行 2 个连接!sql 引擎无法知道您想要什么。
您经常会交叉连接标量值。尽管标量通常是中间计算的结果,但有时您会拥有一个只有 1 条记录的特殊用途表。如果引擎试图检测连接的外键......这是没有意义的,因为交叉连接永远不会匹配一列。
在某些特殊情况下,您将加入两者都不是唯一的列。因此,这些柱上不可能存在 PK/FK。
你可能会认为上面的点2和3是不相关的,因为你的问题是什么时候有IS单PK / FK表之间的关系。但是,表之间存在单个 PK/FK 并不意味着除了 PK/FK 之外,您不能加入其他字段。sql 引擎不知道您要加入哪些字段。
假设您有一个表“USA_States”,以及其他 5 个带有 FK 到各州的表。“五个”表之间也有一些外键。sql引擎是否应该自动将“五个”表与“USA_States”连接起来?还是应该将“五”连在一起?两个都?您可以设置关系,以便 sql 引擎进入一个无限循环,试图将东西连接在一起。在这种情况下,sql 引擎不可能猜测你想要什么。
总结: PK/FK 与表连接无关。它们是独立的不相关的东西。你经常加入 PK/FK 专栏只是一个自然的意外。
你想让 sql 引擎猜测它是全联接、左联接、右联接还是内联接?我不这么认为。尽管这可以说是比猜测要加入的列要少的罪过。
one*_*hen 12
“可连接性”的概念。当且仅当具有相同名称的属性属于相同类型时,关系
r1和r2是可连接的……这个概念不仅适用于连接本身,也适用于各种其他操作 [例如联合]。
SQL 和关系理论:如何按 CJ 日期编写准确的 SQL 代码
标准 SQL 已经具有这样一个特性,称为NATURAL JOIN,并且已经在 mySQL 中实现。
虽然你的建议不是很有价值,但它似乎是合理的。对于 SQL Server(缺乏对 的支持NATURAL JOIN),我在 Management Studio 中使用 SQL Prompt:在编写基于通用属性名称和外键的INNER JOINInteliSense 建议ON子句时,我发现它非常有用。不过,我不太希望看到一个新的(标准)SQL 连接类型。
小智 10
SQL 是第一位的!
外键和外键约束后来出现,本质上是对“事务”样式应用程序的优化。
关系数据库最初被认为是一种对数据集应用复杂查询的方法,这种方法可以使用关系代数进行数学证明。IE 对于给定的数据集和给定的查询,总是有一个正确的答案。
从那时起,关系数据库已经走了很长一段路,作为事务系统的持久层的主要用途并不是 CODD 等。所有设想。
然而,ANSI 标准机构针对其所有相互冲突的目标和供应商政策,一直致力于保留 SQL 的“数学上可证明”的属性。
如果您允许数据库从“隐藏的”外键数据推断连接属性,您将丢失此属性(如果定义了一组以上的外键,请考虑歧义)。
此外,阅读 SQL 的程序员不一定知道当前为两个表定义了哪些外键,并且需要检查数据库模式以找出查询正在执行的操作。
小智 7
你可能在一个错误的假设下运作。 你说“尽你所能”,但没有给出任何经验或证据。如果 pk 或 fk 是查询的最佳索引,则将使用它。我不知道你为什么会看到这个,但我的猜测是查询格式不正确。
现在编辑问题已完全重写:您所描述的情况仅适用于非常小的查询集。如果有 12 个表连接怎么办?如果没有 FK 怎么办.... 即使有一个默认连接,我仍然总是为了可读性而指定连接。(我不想查看数据然后试图弄清楚正在加入的内容)
一些查询工具实际上会为您执行自动连接,然后允许您删除或编辑连接。我认为 MS Access 的查询生成器可以做到这一点。
最后,ANSII 标准规定必须指定连接。这就是不允许的理由。
虽然您定义了外键关系,但这并不意味着您希望在所有查询中加入表。这是连接表的最可能的方法,但也有不正确的情况。
| 归档时间: |
|
| 查看次数: |
31872 次 |
| 最近记录: |