什么是 SQL 服务器数据结构来表示链接在一起的几个对象?

What is a SQL Server data structure to represent several objects chained together?

假设我在 SQL 服务器数据库中有两个 table:dbo.Companiesdbo.Contracts

假设我想表示公司和合同之间的一对一关系,以表明合同已授予公司。我会简单地创建一个连接 table,外键指向 dbo.Companiesdbo.Contracts.

上述场景对于任何有经验的 SQL 开发人员来说都很容易。

然后假设我想做类似的事情,但是每家获得合同的公司都可以分包给另一家公司,另一家公司可以进一步分包出去。

我可能有一家名为 "Acme" 的公司,它可能会转包给 "Evil Geniuses",它可能会转包给 "Evil on a Budget"。

或者,我 "Acme" 可能会转包给 "Evil Geniuses",后者会转包给“Evil on a Budget”,但 "Acme" 可能会同时将同一合同的另一部分转包给 "Falling Anvils".

必须记住,一家公司可能涉及许多不同级别的不同合同,或者系统中可能有公司根本没有获得任何合同。

哪种数据结构允许我在 SQL 中描述这些关系?

编辑:我正在使用 MS SQL 服务器。

我会使用 contracts table 比如:

contract_id primary key,
company_id foreign key (companies.company_id),
parent_id foreign key (contracts.contract_id),
*** contract_level,
*** contract details

contract_level这里是可选的,根据业务需求。此查询的最大缺点是无法在一次查询中找到合同的顶级所有者。这可以通过在顶级合约中添加一个像 contract_family 等于 contract_id 的列来解决。查看所有链的查询如下:

select * from contracts
    left join companies on contracts.company_id = companies.company_id
    where contract_family = ...
    order by contract_level

同上一对一(或一对多)关系即可。

SQL 允许递归遍历这种关系。

我没有测试过以下查询,但它应该给你一个基本的想法。

WITH RECURSIVE ContractHolders AS (
    SELECT * FROM dbo.Companies AS m 
    JOIN dbo.Contracts AS n ON m.id = n.ContractHolderId
    WHERE m.name = 'Acme'
    UNION ALL
    SELECT m.* FROM ContractHolders AS h
    JOIN dbo.Companies AS m ON m.id = h.ContractRecipientId
    JOIN dbo.Contracts AS n ON m.id = n.ContractHolderId
)
SELECT * FROM ContractHolders;

根据您对 dbo. 的使用,我猜您使用的是 Microsoft SQL 服务器 阅读 Recursive Queries Using Common Table Expressions 了解更多信息。