我有以下两个表:
employees(id, name, address, designation, salary, phone, email...)
business_men(id, business_type, business_name, turn_over, phone, email,...)
现在我有另一张桌子clients
。我的客户可以是employee
或business_man
类型。
所以我有如下的客户端表:
Clients(id, code_number, type, reference_id)
类型字段可以存储'employee'或'business_man',而reference_id是Type字段中提到的表的id。在许多地方,整个应用程序都使用客户端的ID。
我的问题是:
答案 0 :(得分:3)
请注意,ClientID
只是PersonID
的角色名称(ClientID = PersonID)。
有了这个,你现在可以创建几个视图,让生活更轻松,这里有一些你可以使用的视图:
答案 1 :(得分: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
)
我们的插入方法将插入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
如果您对设计有疑问,请与我们联系
答案 2 :(得分:1)
在单个查询中执行此操作不应该是主要目标,您应该考虑正确的设计和适当的规范化级别的表。
基本上 - 查询应该适合设计但不能相反。
尝试这种方式,创建以下表格:
-- all common fields for any user (user can be in one group in one time)
USERS(Id, GroupId, Name, Phone, Address)
--User groups like Employee, BusinessMan
USER_GROUPS(Id, Name)
-- The Permanent employees accounting information
ACCOUNTING_PERMANENT(Id, UserId, Designation, Salary)
-- The Business man accounting information
-- Perhaps you can use PE ('private employment') instead 'Business Man'
ACCOUNTING_BUSINESS(Id, UserId, Name, TurnOwer, BusinessType)
如果某个企业可以由许多PE(业务人员)拥有,则再创建一个表并从UserId
表中删除ACCOUNTING_BUSINESS
-- Relation between USERS and ACCOUNTING_BUSINESS tables
USERS_BUSINESS(Id, UserId, BusinessId)
答案 3 :(得分:-1)
你的设计很好。
如果employee
和business_man
之间存在许多共同元素,那么您可能需要引入sllev所暗示的超类型/子类型模型。如果没有很多共性,那么超类型/子类型模型可能对概念模型有用,但对于物理模型则不切实际。
您在设计中所做的是隐式使用一种超类型/子类型,其中除了您调用的code_number
和集成标识符({{1}之外,员工和商务人员之间没有共同属性。 }})。您的分区属性为Clients.id
。
要简化单个查询中的信息检索,请定义一个视图,该视图提供Clients.type
和Employees
之间的联接的UNION以及Clients
和Business_Men
之间的联接
这将为您提供看起来像一个扁平的表,同时包含两种类型的客户端。