来自两个不同表中的任一个的参考密钥

Rao*_*har 5 sql database-design reference


我有以下两个表:

employees(id, name, address, designation, salary, phone, email...)

business_men(id, business_type, business_name, turn_over, phone, email,...)
Run Code Online (Sandbox Code Playgroud)

现在我有另一张桌子clients.我的客户可以是类型employeebusiness_man.所以我有如下的客户端表:

Clients(id, code_number, type, reference_id)
Run Code Online (Sandbox Code Playgroud)

类型字段可以存储'employee'或'business_man',而reference_id是Type字段中提到的表的id.客户端的ID在许多地方的整个应用程序中使用.

我的问题是:

  1. 我做得对吗?
  2. 有更好/更有效的方法吗?
  3. 如何使用单个SQL查询获取客户端的完整详细信息(给定客户端ID)?

bil*_*nkc 2

我们使用的稍微不同的方法是创建一个抽象实体表。其目的是为所有具体实体提供唯一的序列号。一个简化的例子如下 实体结构

--CREATE SCHEMA user893847

CREATE TABLE user893847.BASE_ENTITY
(
    entity_id int identity(1,1) NOT NULL PRIMARY KEY
)

CREATE TABLE user893847.EMPLOYEE
(
    entity_id int NOT NULL PRIMARY KEY
,   name_first varchar(30) NOT NULL
,   name_last varchar(30) NOT NULL
)

CREATE TABLE user893847.BUSINESS_PERSON
(
    entity_id int NOT NULL PRIMARY KEY
,   company_name varchar(30) NOT NULL
)

CREATE TABLE user893847.ADDRESS
(
    entity_id int NOT NULL
,   address_line1 varchar(70) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

我们的插入方法将插入到 BASE_ENTITY 表中并捕获结果 id 值。具体表(employee、business_person)将存储结果 id 作为他们的 PK。造成这种情况的主要原因之一是我们的业务、营销可能会让我们在了解更多信息或对个人进行重新分类时移动实体表。我们发现,如果实体 478 在整个域中都是“相同的”,则逻辑会得到简化。由于在每个表中重新定义了一个数字,因此您不必根据设计中的类型进行查询,只需连接到表即可进行查询,如果行返回,则它就是该类型。

-- your query
SELECT 
    C.*
,   E.*
    -- build out a null set of colums for business men
,   NULL AS id
,   NULL AS business_type
FROM
    Clients C 
    INNER JOIN 
        Employees E 
        ON E.id = C.reference_id 
WHERE 
    C.type = 'employees'
UNION ALL

SELECT 
    C.*
    -- repeat the build out for faking the employee columns
,   NULL AS id
,   NULL AS name
,   ...
,   BM.* 
FROM 
    Clients C 
    INNER JOIN 
        business_men BM 
        ON BM.id = C.reference_id 
WHERE 
    C.type = 'employees'



-- my aproach
SELECT 
    C.*
,   E.*
    -- build out a null set of colums for business men
,   NULL AS id
,   NULL AS business_type
,   ...
FROM
    Clients C 
    INNER JOIN 
        Employees E 
        ON E.id = C.reference_id 
UNION ALL

SELECT 
    C.*
    -- repeat the build out for faking the employee columns
,   NULL AS id
,   NULL AS name
,   ...
,   BM.* 
FROM 
    Clients C 
    INNER JOIN 
        business_men BM 
        ON BM.id = C.reference_id 
Run Code Online (Sandbox Code Playgroud)

如果您对设计有疑问,请告诉我