我有一个包含Client
表的关系数据库,其中包含id
,name
和address
,其中包含许多电话号码
我有一个Employee
表格,其中还包含id
,name
,address
等,还有许多电话号码。
创建一个“电话号码”表并链接客户和员工,或创建两个单独的“电话号码”表,一个用于客户,一个用于员工,是否更合乎逻辑?
如果我选择创建一个表,我可以为客户端和员工使用一个外键,还是必须制作两个外键?
如果我选择创建一个外键,我是否必须使客户端id
从1开始并以5递增,而员工id
从2开始并以5递增,以便两个id
s会不一样?
如果我创建两个外键,一个有值,另一个允许空值?
答案 0 :(得分:1)
"正确的方式",允许你使用外键进行一切,将有第四个表phoneNumberOwner(id),并有字段client.phoneNumberOwnerId和employee.phoneNumberOwnerId;因此,每个客户和每个员工在phoneNumberOwner表中都有自己的记录。然后,您的phoneNumbers表变为(phoneNumberOwnerId,phoneNumber),允许您将多个电话号码附加到每个phoneNumberOwner记录。
答案 1 :(得分:1)
也许你可以以某种方式证明这一点,但以我的方式思考,将员工和客户放在同一张桌子上是不合逻辑的。您似乎只想这样做,以便您的外键(在电话号码表中)都指向同一个表。这不是将员工和客户结合起来的好理由。
使用三个表:员工,客户和电话号码。在电话表中,您可以有一个表示员工或客户的字段。顺便说一句,我不明白为什么电话号码需要成为一个外键:这只会增加复杂性而且收益很少,imo。
答案 2 :(得分:1)
我将采用的解决方案是:
CREATE TABLE Employees (
employee_id INT NOT NULL,
first_name VARCHAR(30) NOT NULL,
...
CONSTRAINT PK_Employees PRIMARY KEY (employee_id)
)
CREATE TABLE Customers (
customer_id INT NOT NULL,
customer_name VARCHAR(50) NOT NULL,
...
CONSTRAINT PK_Customers PRIMARY KEY (customer_id)
)
-- This is basic, only supports U.S. numbers, and would need to be changed to
-- support international phone numbers
CREATE TABLE Phone_Numbers (
phone_number_id INT NOT NULL,
area_code CHAR(3) NOT NULL,
prefix CHAR(3) NOT NULL,
line_number CHAR(4) NOT NULL,
extension VARCHAR(10) NULL,
CONSTRAINT PK_Phone_Numbers PRIMARY KEY (phone_number_id),
CONSTRAINT UI_Phone_Numbers UNIQUE (area_code, prefix, line_number, extension)
)
CREATE TABLE Employee_Phone_Numbers (
employee_id INT NOT NULL,
phone_number_id INT NOT NULL,
CONSTRAINT PK_Employee_Phone_Numbers PRIMARY KEY (employee_id, phone_number_id)
)
CREATE TABLE Customer_Phone_Numbers (
customer_id INT NOT NULL,
phone_number_id INT NOT NULL,
CONSTRAINT PK_Customer_Phone_Numbers PRIMARY KEY (customer_id, phone_number_id)
)
当然,模型可能会根据很多不同的东西而改变。员工也可以成为客户吗?如果两名员工共用一个电话号码,当一名员工的电话号码发生变化时,您将如何处理前端?它会改变另一名员工的人数吗?警告用户并询问他们想做什么?
最后几个问题并不一定会影响数据的最终建模方式,但肯定会影响前端的编码方式以及支持数据所需的存储过程类型。
答案 3 :(得分:0)
除非有特殊的业务要求,否则我希望电话号码是员工或客户实体的属性,而不是自身的实体。
如果它本身被认为是一个实体,它将是“所有密钥”,即它的标识符是其属性的复合,并且除了其标识符之外没有其他属性。如果子属性没有分开存储,那么它只有一个属性,即电话号码本身!因此,通常“有趣”不足以成为一个独立的实体,电话号码表,无论是超类还是子类,通常都是矫枉过正(正如我所说,除非有特殊的业务要求)。