- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
当你学习关系理论时,外键当然是强制性的。但实际上,在我工作的每个地方,表产品和连接总是通过在查询中明确指定键来完成,而不是依赖 DBMS 中的外键。
这样,您当然可以通过不是外键的字段连接两个表,从而产生意想不到的结果。
你认为这是为什么? DBMS 不应该强制仅通过外键创建连接和产品吗?
编辑:感谢您的所有回答。现在我很清楚 FK 的主要原因是引用完整性。但是如果你设计一个数据库,模型中的所有关系(即 ERD 中的箭头)都会变成外键,至少在理论上,无论你是否在你的 DBMS 中这样定义它们,它们在语义上都是外键。我无法想象需要按不是 FK 的字段连接表。 谁能举个有意义的例子?
PS:我知道 N:M 关系成为单独的表而不是外键这一事实,只是为了简单起见而将其省略。
最佳答案
存在外键约束的原因是保证引用的行存在。
“外键标识一个表中的一列或一组列引用另一个表中的一列或一组列。引用列的一行中的值必须出现在被引用表的单个行中.
因此,引用表中的行不能包含引用表中不存在的值(除非可能为 NULL)。通过这种方式,可以通过引用将信息链接在一起,这是数据库规范化的重要组成部分。”( Wikipedia )
回复:您的问题:“我无法想象需要按非 FK 的字段连接表”:
定义外键约束时,引用表中的列必须是引用表的主键,或者至少是候选键。
在进行连接时,不需要使用主键或候选键进行连接。
下面是一个可能有意义的例子:
CREATE TABLE clients (
client_id uniqueidentifier NOT NULL,
client_name nvarchar(250) NOT NULL,
client_country char(2) NOT NULL
);
CREATE TABLE suppliers (
supplier_id uniqueidentifier NOT NULL,
supplier_name nvarchar(250) NOT NULL,
supplier_country char(2) NOT NULL
);
然后查询如下:
SELECT
client_name, supplier_name, client_country
FROM
clients
INNER JOIN
suppliers ON (clients.client_country = suppliers.supplier_country)
ORDER BY
client_country;
这些连接有意义的另一种情况是在提供地理空间功能的数据库中,例如 SQL Server 2008 或带有 PostGIS 的 Postgres。您将能够执行如下查询:
SELECT
state, electorate
FROM
electorates
INNER JOIN
postcodes on (postcodes.Location.STIntersects(electorates.Location) = 1);
来源:ConceptDev - SQL Server 2008 Geography: STIntersects, STArea
您可以在帖子“Sql 2008 query problem - which LatLong’s exists in a geography polygon?”的已接受答案中看到另一个类似的地理空间示例:
SELECT
G.Name, COUNT(CL.Id)
FROM
GeoShapes G
INNER JOIN
CrimeLocations CL ON G.ShapeFile.STIntersects(CL.LatLong) = 1
GROUP BY
G.Name;
这些都是有效的 SQL 连接,与外键和候选键无关,在实践中仍然有用。
关于sql - 为什么外键在理论上比在实践中更多地使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1876013/
只是要清楚我没有一个具体的例子,因为使用的方式 到目前为止,建议使用各种“如何”来实现适合我的需求,并且我还没有遇到关于锁的任何问题,但是在python中使用锁确实引发了以下问题 似乎调用lock.a
这是一个理论问题;作为一名计算机科学爱好者,我一直在思考这个问题,并且正在尝试理解可能(或正在)用于解决这个问题的逻辑和方法。 问题:假设您有一个数字空间可以在其中漫游以获取某种 ID 值。您需要在此
查看这段代码: public async Task ConsumeAsync() { await a(); await b(); a
以下产生死锁错误消息(* 异常:线程在 MVar 操作中无限期阻塞)。我一步一步想通了,没看出问题。 在主线程上,创建一个 MVar,并将其提供给生产者,在新线程上运行 生产者启动,并在 listen
我想嵌入 3 个 NP-Complete 问题(其中 2 个已知是 NP-Complete,其中 1 个是我自己的想法)。我看到了“this question”并得到了关于从理论上重新解释嵌入问题的想
我刚刚测试了这段代码。 主要。 public class Main { /** * @param args */ public static void main(S
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我目前正在研究 open-std proposal为我正在处理的项目带来并行功能,但我遇到了 find_end 的障碍。 现在find_end可以描述为: An algorithm that sear
我正在编写看起来与此类似的代码: public IEnumerable Unfold(this T seed) { while (true) { yield retur
给定以下函数调用: f(g(), h()) 由于未指定函数参数的评估顺序(据我所知,在 C++11 中仍然如此),理论上是否可以执行 g() 和 h() 并行? 这种并行化只能在 g 和 h 已知相当
我在 C 中有两个项目: 第一个: include windows.h include stdio.h include tchar.h int main() { HANDLE hFile =
我在碰撞检测中有一个关于类似问题的问题,但它并不完全相同。我遇到了一个新游戏项目的问题(我正在尝试了解有关 HTML5 Canvases 和 Socket.io 的更多信息),其中我的碰撞不起作用。我
这个问题在这里已经有了答案: Why `alert()` after `setTimeout()` is not called as expected? (1 个回答) 关闭 8 年前。 为什么 s
在某些情况下,需要一种高效的内存来存储大量对象。要在 Java 中做到这一点,您不得不使用几个原始数组(请参阅下面的原因)或一个大字节数组,这会产生一些 CPU 开销以进行转换。 例子:你有一个 cl
我熟悉 PHP 函数如何映射到 PHP 下面的 C 代码中的 C 函数。我知道 C 中函数的含义以及 MACRO() 的含义。 我不明白什么是语言构造,例如 echo,在 PHP 中是什么意思。 最佳
刚刚将 libevent(1.4.8)、memcached(1.4.5)、pear 和 libmemcached(0.40) 安装到我的 lamp 服务器(运行 PHP 5.2.10 和 Centos
当谈到扩展方法时,类名似乎什么都不做,但提供了一个分组,这正是 namespace 所做的。一旦包含命名空间,我就会在命名空间中获得所有扩展方法。所以我的问题归结为:我可以从静态类中的扩展方法中获得一
我在我拥有的存储库(实际上是 fork 的)上使用 VS2015 GitHub 扩展。在 .gitignore 文件中的某些时候我有这个(从 fork 中获取,我没有添加 ignore ): ...
大家好。我会尽力解释我的问题,以便您能理解我。 在几个地方我发现它认为 Scala 比 Python 更快: https://www.quora.com/Which-one-is-faster-Sca
我是一名优秀的程序员,十分优秀!