如何使用多个电话号码设置客户表? - 关系数据库设计

use*_*509 4 sql database normalization

CREATE TABLE Phone
(
phoneID - PK
.
.
.
);

CREATE TABLE PhoneDetail
(
phoneDetailID - PK
phoneID - FK points to Phone
phoneTypeID ...
phoneNumber ...
.
.
.
);

CREATE TABLE Customer
(
customerID - PK
firstName
phoneID - Unique FK points to Phone
.
.
.
);
Run Code Online (Sandbox Code Playgroud)

客户可以拥有多个电话号码,例如Cell,Work等.Customer表中的phoneID是唯一的,并指向Phone表中的PhoneID.如果删除客户记录,则还应删除Phone表中的phoneID.

你对我的设计有任何顾虑吗?这个设计得当吗?我的问题是Customer表中的phoneID是一个孩子,如果删除了子记录,那么我无法自动删除父(电话)记录.

cod*_*eim 11

我认为你已经过度设计了它.我认为没有用于单独的Phone + PhoneDetail表.通常有两种实用方法.

1)简单性 -将客户中的所有电话记录下来.是的,它打破了规范化规则,但它在实践中非常简单,并且通常只要您提供(工作,家庭,移动,传真,紧急).上行代码只是编写,实现时间更短.检索具有客户记录的所有电话很简单,因此使用特定类型的电话(Customer.Fax).

缺点:后添加额外的手机类型是多了几分痛苦,寻找电话号码是缺憾.你必须像编写SQL一样"select * from customer where cell = ? or home = ? or work = ? or emergency = ?".预先评估您的设计.如果这些问题中的任何一个是一个问题,或者您不知道它是否可能是一个问题,请使用标准化方法.

2)可扩展性 - 走你要去的路线.电话类型可以在以后添加,不会更改DDL.客户 - > CustomerPhone

Customer (
   customerId
)

CustomerPhone (
   customerId references Customer(customerId)
   phoneType references PhoneTypes(phoneTypeId)
   phoneNumber
)

PhoneTypes (
   phoneTypeId   (H, W, M, F, etc.)
   phoneTypeDescription
)
Run Code Online (Sandbox Code Playgroud)


Unr*_*son 1

由于 mrjoltcola 已经解决了标准化问题,我将解决电话中有记录和电话详细信息没有记录的问题。

如果这是您唯一的问题,可以使用三种方法:

1) 不要从明细表中删除,而是使用 CASCADE DELETE 从手机中删除 - 使用单个 SQL 语句从两个表中删除并保持数据一致

2)在详细信息表上有触发器,当从子项中删除父项的最后一条记录时,该触发器将自动删除父项(这不会很好地执行,并且会减慢表上的所有删除速度。而且它很丑陋。仍然是可能的去做吧)

3)在应用程序的业务逻辑层中执行此操作 - 如果该层正确分离并且用户(应用程序)仅通过该层修改数据,您可能会达到所需的一致性保证级别