【问题标题】:relationship and build database关系和建立数据库
【发布时间】:2013-01-26 14:31:58
【问题描述】:

对于一个练习,我需要构建类似的东西:

对于一门课程,我需要创建一个由某些评论线和反馈分数组成的评论。

此评论对象(唯一实例)需要填写客户列表。

根据审查所针对的课程,审查会发生变化(例如,对于一门课程,审查行数和反馈分数会发生变化)。每个客户可以注册不止一门课程,每条评论都是针对他的。

现在,如果我想使用 JPA 将这一切保存到数据库,我需要如何查看“review”对象(唯一实例)和“customer”之间的关系?

  • 客户可以有多个需要填写的评论。
  • 某个评论对象需要许多客户填写(但这是一个具有特定构建 [reviewlines and feedbackscores] 的评论对象)并且对他来说是独一无二的。

也许我认为它很复杂,但构建它的最佳方法是什么?

【问题讨论】:

    标签: java mysql jpa entity-relationship


    【解决方案1】:

    尝试以下方法:

    我认为它涵盖了您所有的设计要点。

    我正在尝试阅读您的 cmets 的字里行间,并且我认为您想要实现一个系统,您可以在其中为 Review 捕获许多“规则”(我猜,但示例可能是评论最多可以有 n 行,必须至少有 mCustomerReviews 才能使Review 获得一定程度的质量)。如果确实如此,我创建了一个ReviewTemplate 类:

    • ReviewTemplate 将为您需要的每个值提供属性/列。这些属性/列在Review重复
    • 用多行填充ReviewTemplate,然后在Course 中创建一行并将其链接到一个ReviewTemplate
    • Course 需要Review 时,复制字段从ReviewTemplateReview
    • 在 Java 中,使用 复制的值实现 Review 的业务规则,而不是 ReviewTemplate 上的值。

    为什么要复制这些值?好吧,我敢打赌,在某些时候,用户想要编辑ReviewTemplate 表。如果是这样,使用编辑的ReviewTemplatesReview 对象会发生什么? ReviewTemplate 上的修改值是否会以某种方式使过去的 Reviews 无效并破坏您的业务逻辑?不,因为您将规则值复制到了Review,所以过去的Reviews 不会改变。

    编辑:特定问题的答案

    您如何看待重复?我可以创建一个具有指定属性的实体 ReviewTemplate。在这个实体中,将有与审查线和反馈分数的关系。

    我认为每个ReviewTemplate 都包含Review 的特定“类型”的原型值,其中可能包括默认的reviewLine(但这可能没有意义)和默认的feedbackScore。创建Review 时,您将执行以下操作:

    1. 实例化 Review 并使用来自 ReviewTemplate 的值填充
    2. 根据需要实例化尽可能多的 CustomerReview 对象,将它们链接到相关的 Customer 对象(我从您之前的 cmets 推断出这一步。省略这一步也可能有意义,直到 Customer 自愿选择查看Course)

      1. (如果适用)使用来自ReviewTemplate 的默认值填充CustomerReview 属性feedbackScore
      2. 酌情实例化CustomerReviewLine 记录

    如果您遵循此方法,则无需在ReviewTemplateCustomerReviewLines 之间添加关系。

    当我例如说明客户 1 到 4 需要填写评论 需要创建 4 个特定的“对象”来保存信息,还需要创建 4 组所需的评论线和反馈分数,以便他们都可以保存信息。

    绝对的。

    我只是不知道如何实现这是一个 JPA 结构,所以信息保存在数据库中......?

    JPA 允许您以多种方式解决问题,但最佳实践是手动创建 DB 模式和 Java 类(例如,请参阅https://stackoverflow.com/a/2585763/1395668)。因此,对于图中的每个实体,您需要:

    1. 编写 SQL DDL 语句来创建表、列、主键和外键,以及
    2. 编写一个用@entity 注解表示的Java 类。在类中,您还需要使用 @id 注释 id(主键)和使用 @OneToMany@ManyToOne 的关系(注释中的附加参数也需要设置)。

    现在,在 JPA 方面,您可以执行以下操作:

    ReviewTemplate template = course.getReviewTemplate(); //assuming the variable course
    Review review = new Review();
    review.setCourse(course);
    review.setRuleOne(template.getRuleOne());
    // Copy other properties here
    
    EntityManager em = // get the entity manager here
    em.persist(review);
    
    // Assume a set or list of customers
    for (Customer customer : customers) {
        CustomerReview cr = new CustomerReview();
        cr.setReview(review);
        cr.setCustomer(customer); 
        cr.setFeedbackScore(template.getDefaultFeedbackScore());
        // set other CustomerReview properties here
    
        em.persist(cr);
    
        // You can create CustomerReviewLine here as well
    

    如果在标准 EJB 会话 Bean 中编写,这一切都将得到很好的处理,并且您会将所有新记录提交到数据库中。

    编辑 2:附加问题

    (我假设第二条评论完全取代了第一条)

    因此,当我创建一个评论模板并将其链接到一群客户时,我将模板写入数据库并基于模板创建一堆评论,但链接到特定客户并使用他自己独特的评论线和反馈分数。就像我现在看到的一样,每条评论(模板)的评论线(更多是问题或描述)都是相同的,只是客户之间的分数会发生变化

    我终于想明白了ReviewLine。我原以为这是Customer 输入包含CustomerReview 的文本行的地方。我现在相信ReviewLineCustomer 被问到的一个特定问题,Customer 提供了一个反馈分数。

    有了这个理解,这里是一个更新的 ER/Class 图。

    请注意,有一些重大变化 - 还有几个表格:

    1. ReviewLineTemplate 为模板问题提供了一个存储位置,ReviewTemplate
    2. Review 被实例化/插入(它是特定ReviewTemplate 的副本)时,ReviewLineTemplates 被复制为ReviewLines。复制操作允许两个重要功能:

      1. 在创建时,可以自定义Review 及其ReviewLines,而不会影响ReviewTemplateReviewLineTemplate
      2. 随着时间的推移,ReviewTemplateReviewLineTemplate 可以更新、编辑和不断改进,不会更改 Customer 已经回答的问题。如果CustomerFeedbackScore 直接链接到ReviewLineTemplate,那么编辑ReviewLineTemplate 将改变Customer 已回答的问题,默默地使feedbackScore 无效。
    3. FeedbackScore 已移至 ReviewLineCustomerReview 之间的连接表。

    请注意,此模型是完全非规范化的,这使得它更“正确”,但更难为其构建 GUI。一个常见的“优化”可能是引入:

    • ReviewTemplateReview 上的 10 个(比如说)列称为 reviewLine1reviewLine10
    • CustomerReview 上的 10 个(比如说)列称为 feedbackScore1feedbackScore10
    • 删除ReviewTemplateLineReviewLineCustomerReviewLine

    这样做没有标准化,并且可能会引入一系列其他问题。 YMMV

    【讨论】:

    • 您如何看待重复?我可以创建一个具有指定属性的实体 ReviewTemplate。在这个实体中,将有与审查线和反馈分数的关系。当我例如声明客户 1 到 4 需要填写评论 需要创建 4 个特定的“对象”来保存信息,还需要创建 4 组所需的评论线和反馈分数,这样他们都可以保存我刚刚不知道的信息'不知道如何实现这是一个 JPA 结构,所以信息保存在数据库中......?
    • 首先感谢您的回复。我还没和你在一起。我创建了一个类/实体reviewTemplate。模板之间的区别在于reviewlines 和feedbackscores 的数量和值。根据行数,我可以使用指定的行数和模板的值(例如名称、开始日期、..)创建评论。为什么我不需要在评论和行之间创建关系。这些行不在评论中并且对于每个对象都是唯一的,所以我确实需要链接这些并将它们写入数据库以便我可以检索它们?我希望这有任何意义
    • 因此,当我创建一个评论模板并将其链接到一堆客户时,我将模板写入数据库并根据模板创建一堆评论,但链接到特定客户并使用他自己的独特的评论和反馈分数。就像我现在看到的那样,每条评论(模板)的评论线(更多的是问题或描述)都是相同的,只是客户之间的分数会发生变化。
    • 首先,再次感谢所有的努力。没错,你没看错!我现在将评论线视为模板中的一些问题,客户需要为其设置反馈分数。因为所有客户的所有评论都相同,只有反馈分数不同,所以这个解决方案是可用的。我同意标准化是一个完全不同的问题......但首先,我会尝试让这个工作,因为练习更多的是从 JPA、servlet、jsp 的角度......
    【解决方案2】:

    数据的结构总是取决于需求,永远不存在“一劳永逸”的解决方案。那么,您需要最大化的原子性还是高性能的数据系统?

    最快和最简单的解决方案不是使用数据库,而是使用哈希表。在您的情况下,您可能有 3 个用于客户、评论的哈希表,可能还有另一个用于 n:n 关系的哈希表。或者,如果您使用的是数据库,则可以将一组 review-primary-keys 存储在 customer 表的一个字段中。

    但是,我们都在学校学习做原子性,所以让我们这样做(我只写主键/外键!):

    • 客户(unique_ID,...)
    • 审核(唯一 ID,...)
    • Customer_Review (customer_ID, review_ID, ...) --> n:n-relationship

    Customer_Review 描述了客户和评论之间的 n:n 关系。但如果每条评论可能只有一位客户,您可以这样做:

    • 客户(unique_ID,...)
    • 评论(pk:unique_ID,fk:customer_ID,...)--> 1:n-relationship

    但是,我建议你需要学习 ERM 作为一个好的起点:http://en.wikipedia.org/wiki/Entity_relationship_model

    【讨论】:

      【解决方案3】:

      你需要一个多对多关系:

      • 一位客户 -> 多条评论。
      • 一条评论 -> 多个客户。

      因此,您的数据库架构中将有 3 个表:客户、评论和一个带有客户 ID 和评论 ID 的联结表。

      Wikipedia : Many to Many

      【讨论】:

      • 这个问题是,如果我用reviewuwlines 和feedbackscores 建立一个评论。此评论对象需要客户填写。但是每个客户都需要填写自己的点评对象。
      • 你的问题在哪里?联结表将允许 2 种操作:获取与特定客户相关的评论,以及获取需要填写特定评论的客户。
      • 例如:我创建了一个包含 5 条评论线和反馈分数的评论对象。此评论需要由客户 1 到 4 填写。我创建了另一个包含 3 个评论线和反馈分数的评论对象。此评论需要由客户 1 至 3 填写。对于每个客户,具体评论都是唯一的。这不像一本书可以有很多作者,而一个作者有很多书(这里的书保持不变)。在这种情况下,具体的评论需要由特定的客户填写。这不是与许多客户相关的评论
      • 好的,您是说评论行是客户填写评论时创建的内容吗?如果没问题,reviewline 表应该与客户具有多对一关系。这是为了找回作者。客户和评论之间的多对多链接不提供“作者”信息,而是“必须填写”信息。对不起,我的英语不是很好,但我会尽力理解你。
      • 我的意思是,如果您在 Book 和 author 之间有一个多对多(一本书可以有 1 个或多个作者,而一个作者可以有零个或多个他写的书),那么您就在同一本书上发言和这种关系的同一作者。在这种情况下,如果我进行评论(使用他收集的评论线和分数),这更像是一种评论类型。然后,此评论类型必须与您希望拥有的客户列表需要填写的客户数量重复。每个客户都有一个特定的评论,只有他需要填写。另一个客户与他的评论无关跨度>
      猜你喜欢
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多