2012-10-15 56 views
1

问题定义:一家公司想通过询问一些问题来衡量其产品的客户满意度。公司的产品数据存储在“产品”表中,每个产品的客户数据存储在“客户”表中,并且每个产品的问题存储在问题表中。作为简单如下:基本数据库设计场景

产品:[ID,名称]

客户:[ID,PRODUCT_ID(FK),名字]

问题:[ID,PRODUCT_ID(FK),文本]

问题是,我们如何设计一个表来存储每个客户的答案,通过考虑每个客户只能回答其产品的问题。例如,如果你的答案是这样的:

customer_answer:[ID,CUSTOMER_ID(FK),question_id(FK),答案]

那么它错了,因为如果我们的表的样本数据如下所示:

产品:[1, “椅子”],[2, “表”]

客户:[1,1, “安东尼·昆”],[2,2,“玛丽莲梦露“]

问题:[1,1,“该产品的任何建议?” ],[2,1,“你估计这把椅子怎么样 ?” ]

可能一个可能的排具有低于数据:

customer_answer:[1,2,1, '不,谢谢']

这是错误的,因为id#2的客户没有product_id#1,所以对于这个问题可能是错误的表格。

在这种情况下我们能做些什么?

它没关系,但顺便说一句我正在使用mysql来解决这个问题。

+0

您验证数据录入。 –

+0

客户只能对产品提问一次吗?如果他们在一个日期订购产品,并且对此感到满意,但是稍后再订购并且遇到问题会怎么样? – LittleBobbyTables

+0

@LittleBobbyTables:在这个问题中无关紧要。 – linker

回答

2

这是一个代理键损害,而不是帮助您的数据库设计的情况。此外,您应该有一个单独的客户表来唯一列出客户。

下面是一个快速设计,用于从表中删除代理键,其中替代键的存在使得难以强制引用完整性。关键的变化是CustomerProducts(我已将您的Customers表重新命名)使用CustomerID,ProductID作为PRIMARY KEY,从而有可能强化答案与所拥有产品之间关系的完整性。

Products:   ProductID, Name 
         (PK = ProductID) 
Customers:  CustomerID, Name 
         (PK = CustomerID) 
CustomerProducts: CustomerID, ProductID 
         (PK = CustomerID, ProductID) 
         (FK = CustomerID REFERENCES Customers) 
         (FK = ProductID REFERENCES Products) 
Questions:  ProductID, QuestionText 
         (PK = ProductID, QuestionText) 
         (FK = ProductID REFERENCES Products) 
Answers: CustomerID, ProductID, QuestionText 
         (FK CustomerID, ProductID REFERENCES CustomerProducts) 
         (FK ProductID, QuestionText REFERENCES Questions) 

注:如果您使用大VARCHAR字段QuestionText作为问题的PK和FK的答案(尤其是因为内容可能会发生变化)的一部分感到不舒服,你可以在这里重新引入了代理键,或许更好地,添加专栏QuestionNo以提供单个产品中问题的排序;然后制作ProductID,QuestionNo为主键和外键。

+0

问题是,每个客户只有1个产品。这个问题呢? – linker

+0

啊,这更容易(很难相信,但更容易;-))。摆脱CustomerProducts并将ProductID及其外键移回给客户。然后,在客户(CustomerID,ProductID)上创建一个新的UNIQUE INDEX。最后,引用CustomerProducts的Answers中的FK现在应该说'REFERENCES Customers(CustomerID,ProductID)'。 –

+0

好的,很好。我想知道Vikdor的答案是什么问题?你的答案的优点是什么? (你的回答也是正确的) – linker

2

您应该在customer_answer表中引用customer_id和product_id的外键约束,引用customer表中的id和product_id列来强制存储只有客户问题的答案。

CREATE TABLE customer_answer 
(
    id INT, 
    customer_id INT, 
    product_id INT, 
    answer VARCHAR(128), 
) 
ALTER TABLE customer_answer 
ADD CONSTRAINT FK_Customer_Answer_To_Customer FOREIGN KEY (customer_id, product_id) REFERENCES customer(id, product_id) 
+0

可以请你重写customer_answer表吗? – linker

+0

请参阅alter table语句的更新以强制执行外键关系。 – Vikdor

0

我想这应该是应用数据层(在MVC架构实例模型)插入数据前进行必要的检查工作。

+0

我知道我们可以在我们的业务层进行检查,但我想知道有没有办法在我的应用程序的“数据层”中执行此操作? – linker

+1

为什么地球上会有目的地建立一个数据库,*忽略*数据库强制引用完整性的能力? –

0

或者,您可以尝试在插入“customer_answer”时尝试编写一个MySQL触发器,它将检查您试图添加的新组合(产品ID和客户ID)是否存在于客户表中,如果是,则继续,如果不是,你可以恢复。

2

注2个FKS上CustomerQuestion表:FK1 {CustomerID, ProductID}和FK2 {ProductID, QuestionID}

enter image description here

+0

在CustomerProduct表中有一个问题,即每个客户只有一个产品,我们不能为客户添加2个产品 – linker

+0

@linker - 不太明白。这是一个规格,客户只能有一个产品? –

+0

是的,我认为Larry的回答是我正在寻找的。真的非常感谢你的回答,我从你的答案中学到了新东西。你的也是对的。 (他们是一样的) – linker