代码之家  ›  专栏  ›  技术社区  ›  Vivian River

什么是表示链接在一起的多个对象的SQL Server数据结构?

  •  1
  • Vivian River  · 技术社区  · 8 年前

    假设我在SQL Server数据库中有两个表: dbo.Companies dbo.Contracts .

    假设我想表示公司和合同之间的一对一关系,以表明合同已授予公司。我只需创建一个带有外键的联接表 dbo.公司 DBO.合同 .

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

    那么,假设我想做一些类似的事情,但是每个被授予合同的公司都可以分包给另一家公司,后者可以进一步分包出去。

    我可能有一个叫“Acme”的公司,它可以分包给“邪恶的天才”,也可以分包给“预算中的邪恶”。

    或者,我“acme”可能会转包给“邪恶的天才”,后者会转包给“预算中的邪恶”,但“acme”可能会同时将同一合同的另一部分转包给“坠落的铁砧”。

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

    什么样的数据结构允许我用SQL描述这些关系?

    编辑: 我正在使用MS SQL Server。

    2 回复  |  直到 8 年前
        1
  •  0
  •   Sianur    8 年前

    我会用 contracts

    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

    select * from contracts
        left join companies on contracts.company_id = companies.company_id
        where contract_family = ...
        order by contract_level
    
        2
  •  1
  •   Bill Karwin    8 年前

    一对一(或一对多)关系就足够了。

    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. 阅读 Recursive Queries Using Common Table Expressions

    推荐文章