如何设计员工也是客户的 erd?
How to design erd where employee is a customer too?
我有一个电影院的场景,在这个场景中,员工也可以是顾客(因为他们可以买票)。
我创建了两个实体,customer
和 employee
。如果我将 emp_id
的 employee
设为 customer
中的外键,那么它也会使员工成为客户:
客户:cust_id,姓名,年龄,emp_id
员工:emp_id、姓名、年龄
但是当我这样做时,employee
的数据在 customer
中重复。我该怎么办??
当我看到你的 table 时,第一件事就是你不应该真正存储 age
。存储生日或出生年份,这样你就不必每年都更新它,因为年龄是相对于当年的。
如果你想听听我的意见,请继续阅读,或者跳到 TL;DR 部分。
对于您遇到的问题,可以有多种设计选择,我发现它主要是基于从中选择哪一种的意见。
一个选择 是创建一个 table 来存储与人相关的数据,并在这个 table 中包含人的类型,这样你将有客户或员工。这样,您的员工也可以被视为客户,但您知道它是 特殊客户。这样,当 he/she 不再是雇员时,您可以将雇员的记录转换为客户。
解决此问题的另一种方法 是按照您已经拥有的方式对待它们并处理重复数据这一事实。除非你有大量员工(电影院不应该是这种情况),这也是一种有效的方法,因为显然他们可以成为客户,但我假设你想打折或出于某种原因区分这些两种类型的客户。
想保持现在的样子,但又不想为了不出错而重复数据?更改为 table 共享的列并使它们可为空。使用触发器或其他一些规则机制来检查 emp_id
是否已填充,然后保留所有其他公共列值 null
。通过这种方式,您将需要注意从其他 table 中提取数据,因此此处需要 LEFT JOIN
来提取有关同时也是员工的客户的数据。
还有更多选择 ...
TL;DR
如果你问我,我很可能会选择 第一个选项 将与人相关的数据存储在一个 table 中,然后创建一种类型的人或对员工和客户有不同的 table,这将与人 table 建立 1:1 关系。
也就是说,它可能看起来像:
- 人物(person_id,姓名,birth_year)
- 员工(person_id,...)(此处仅存储员工相关数据)
- 客户(person_id,...)(此处仅存储客户相关数据)
作为旁注,弄清楚您希望如何区分一般人可能是个好主意。您没有介绍整个系统的范围,因此很难就此提出一些建议。
如果只有customer和employee两个角色,可以用一个table来存储用户,像这样:
person(id, name, birth, is_customer, is_employee, ...)
但是如果你以后考虑更多的扩展,你可以添加一个角色table,像这样:
role(id, name, ...)
person(id, name, birth, roles, ...)
列 roles
可以存储 json 数据,如 [1,2]
或字符串,如 1,2
,这取决于你喜欢什么和 mysql 版本。
我有一个电影院的场景,在这个场景中,员工也可以是顾客(因为他们可以买票)。
我创建了两个实体,customer
和 employee
。如果我将 emp_id
的 employee
设为 customer
中的外键,那么它也会使员工成为客户:
客户:cust_id,姓名,年龄,emp_id
员工:emp_id、姓名、年龄
但是当我这样做时,employee
的数据在 customer
中重复。我该怎么办??
当我看到你的 table 时,第一件事就是你不应该真正存储 age
。存储生日或出生年份,这样你就不必每年都更新它,因为年龄是相对于当年的。
如果你想听听我的意见,请继续阅读,或者跳到 TL;DR 部分。
对于您遇到的问题,可以有多种设计选择,我发现它主要是基于从中选择哪一种的意见。
一个选择 是创建一个 table 来存储与人相关的数据,并在这个 table 中包含人的类型,这样你将有客户或员工。这样,您的员工也可以被视为客户,但您知道它是 特殊客户。这样,当 he/she 不再是雇员时,您可以将雇员的记录转换为客户。
解决此问题的另一种方法 是按照您已经拥有的方式对待它们并处理重复数据这一事实。除非你有大量员工(电影院不应该是这种情况),这也是一种有效的方法,因为显然他们可以成为客户,但我假设你想打折或出于某种原因区分这些两种类型的客户。
想保持现在的样子,但又不想为了不出错而重复数据?更改为 table 共享的列并使它们可为空。使用触发器或其他一些规则机制来检查 emp_id
是否已填充,然后保留所有其他公共列值 null
。通过这种方式,您将需要注意从其他 table 中提取数据,因此此处需要 LEFT JOIN
来提取有关同时也是员工的客户的数据。
还有更多选择 ...
TL;DR
如果你问我,我很可能会选择 第一个选项 将与人相关的数据存储在一个 table 中,然后创建一种类型的人或对员工和客户有不同的 table,这将与人 table 建立 1:1 关系。
也就是说,它可能看起来像:
- 人物(person_id,姓名,birth_year)
- 员工(person_id,...)(此处仅存储员工相关数据)
- 客户(person_id,...)(此处仅存储客户相关数据)
作为旁注,弄清楚您希望如何区分一般人可能是个好主意。您没有介绍整个系统的范围,因此很难就此提出一些建议。
如果只有customer和employee两个角色,可以用一个table来存储用户,像这样:
person(id, name, birth, is_customer, is_employee, ...)
但是如果你以后考虑更多的扩展,你可以添加一个角色table,像这样:
role(id, name, ...)
person(id, name, birth, roles, ...)
列 roles
可以存储 json 数据,如 [1,2]
或字符串,如 1,2
,这取决于你喜欢什么和 mysql 版本。