简体   繁体   English

基础数据库设计方案

[英]Fundamental database design scenario

Problem definition: a company wants to measure customers satisfaction of their products by asking some questions. 问题定义:公司希望通过提出一些问题来衡量客户对其产品的满意度。 company's prducts data stores in "products" table, customers data of each product stores in "customers" table and questions of each product stores in questions table. 公司在“产品”表中的产品数据存储,在“客户”表中的每个产品存储的客户数据,在问题表中的每个产品存储的问题。 As simple as below: 如下所示:

products: [ id, name ] 产品:[ID,名称]

customers: [ id, product_id(fk), name ] 客户:[id,product_id(fk),名称]

questions: [ id, product_id(fk), text ] 问题:[id,product_id(fk),文本]

the question is, how can we design a table to store answers of each customer by considering that each customer can only answer its product's question. 问题是,如何通过考虑每个客户只能回答其产品的问题来设计一个表来存储每个客户的答案。 For example, if your answer is something like this: 例如,如果您的答案是这样的:

customer_answer:[ id, customer_id(fk), question_id(fk), answer ] customer_answer:[id,customer_id(fk),question_id(fk),答案]

then its wrong because if our table's sample data is like the following: 这是错误的,因为如果表的样本数据如下所示:

products: [ 1, "Chair" ], [ 2, "Table" ] 产品:[1,“主席”],[2,“桌子”]

customers:[ 1, 1, "Anthony Quinn" ], [ 2, 2, "Marilyn Monroe" ] 客户:[1,1,“安东尼·奎因”],[2,2,“玛丽莲·梦露”]

question: [ 1, 1, "Any suggestion for this product ?" 问题:[1,1,“对这个产品有什么建议吗?” ], [ 2, 1, "How do you estimate this chair ?" ],[2,1,“您如何估计这把椅子?” ] ]

then there might be a possible row with below data: 那么可能会有一行包含以下数据的行:

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

that is wrong, because the customer with id #2 don't have the product_id #1, so it can be wrong table for this problem. 这是错误的,因为ID为#2的客户没有product_id#1,因此针对此问题的表可能是错误的。

What can we do in such situations ? 在这种情况下我们该怎么办?

it doesn't matter but BTW I'm using mysql for solving this problem. 没关系,但是顺便说一句,我正在使用mysql解决此问题。

You should define a foreign key constraint on customer_id and product_id in the customer_answer table referencing the id and product_id columns in the customer table to enforce storing answers to only customer's questions. 您应该在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)

This is a case of surrogate keys hurting, rather than helping, your database design. 这是代理键损害而不是帮助数据库设计的一种情况。 Also, you should probably have a separate Customers table to uniquely list customers. 另外,您可能应该有一个单独的“客户”表来唯一列出客户。

Here's a quick design that removes the surrogate keys from the tables in which the existence of the surrogate keys makes it harder to enforce referential integrity. 这是一个快速设计,可以从表中删除代理键,其中代理键的存在使执行引用完整性变得更加困难。 The critical change is that CustomerProducts (what I've renamed your Customers table) now uses CustomerID, ProductID as the PRIMARY KEY, making it possible to enforce the integrity of the relationship between answers and products owned. 关键的变化是,CustomerProducts(我已经将您的Customer表重新命名了)现在使用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)

Note: If you feel uncomfortable using the large VARCHAR field QuestionText as part of the PK on Questions and the FK on Answers (especially since the contents may change), you can reintroduce a surrogate key here or, perhaps better, add a column QuestionNo to provide ordering of questions within a single product; 注意:如果您不满意使用较大的VARCHAR字段QuestionText作为“问题PK”和“答案FK”的一部分(特别是因为内容可能会更改),则可以在此处重新引入替代键,或者最好在其上添加一列QuestionNo在单个产品中提供问题的排序; then make ProductID, QuestionNo the primary and foreign key. 然后将ProductID,QuestionNo作为主键和外键。

Note 2 FKs on CustomerQuestion table: FK1 {CustomerID, ProductID} and FK2 {ProductID, QuestionID} 注意2 CustomerQuestion表上的FK:FK1 {CustomerID, ProductID}和FK2 {ProductID, QuestionID}

在此处输入图片说明

我认为这应该是应用程序数据层(例如MVC体系结构中的模型)在插入数据之前进行必要检查的工作。

或者,您可以尝试在插入“ customer_answer”时编写MySQL触发器,该触发器将检查是否要在客户表中找到要添加的新组合(产品ID和客户ID),如果是,则继续操作,如果不,你可以还原。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM