gpt4 book ai didi

google-app-engine - 数据库设计 - 谷歌应用引擎

转载 作者:太空宇宙 更新时间:2023-11-03 15:21:16 25 4
gpt4 key购买 nike

我正在使用谷歌应用引擎并使用低级 java api 访问大表。我正在构建一个具有 4 层的 SAAS 应用程序:

  • 客户端网页浏览器
  • RESTful 资源层
  • 业务层
  • 数据访问层

  • 我正在构建一个应用程序来帮助管理我的移动汽车美容公司(以及其他类似公司)。我必须代表这四个独立的概念,但不确定我目前的计划是否合适:
  • 约会
  • 行项目
  • 发票
  • 付款

  • 预约: “约会”是指员工在提供服务时应在的地点和时间。

    行项目: “行项目”是服务、费用或折扣及其相关信息。可能进入约会的订单项示例:
    Name:                          Price: Commission: Time estimate   Full Detail, Regular Size:        160       75       3.5 hours $10 Off Full Detail Coupon:       -10        0         0 hours Premium Detail:                   220      110       4.5 hours Derived totals(not a line item): $370     $185       8.0 hours

    Invoice: An "Invoice" is a record of one or more line items that a customer has committed to pay for.

    Payment: A "Payment" is a record of what payments have come in.

    In a previous implementation of this application, life was simpler and I treated all four of these concepts as one table in a SQL database: "Appointment." One "Appointment" could have multiple line items, multiple payments, and one invoice. The invoice was just an e-mail or print out that was produced from the line items and customer record.

    9 out of 10 times, this worked fine. When one customer made one appointment for one or a few vehicles and paid for it themselves, all was grand. But this system didn't work under a lot of conditions. For example:

    • When one customer made one appointment, but the appointment got rained out halfway through resulting in the detailer had to come back the next day, I needed two appointments, but only one line item, one invoice and one payment.
    • When a group of customers at an office all decided to have their cars done the same day in order to get a discount, I needed one appointment, but multiple invoices and multiple payments.
    • When one customer paid for two appointments with one check, I needed two appointments, but only one invoice and one payment.

    I was able to handle all of these outliers by fudging things a little. For example, if a detailer had to come back the next day, i'd just make another appointment on the second day with a line item that said "Finish Up" and the cost would be $0. Or if I had one customer pay for two appointments with one check, I'd put split payment records in each appointment. The problem with this is that it creates a huge opportunity for data in-congruency. Data in-congruency can be a serious problem especially for cases involving financial information such as the third exmaple where the customer paid for two appointments with one check. Payments must be matched up directly with goods and services rendered in order to properly keep track of accounts receivable.

    Proposed structure:

    Below, is a normalized structure for organizing and storing this data. Perhaps because of my inexperience, I place a lot of emphasis on data normalization because it seems like a great way to avoid data incongruity errors. With this structure, changes to the data can be done with one operation without having to worry about updating other tables. Reads, however, can require multiple reads coupled with in-memory organization of data. I figure later on, if there are performance issues, I can add some denormalized fields to "Appointment" for faster querying while keeping the "safe" normalized structure intact. Denormalization could potentially slow down writes, but I was thinking that I might be able to make asynchronous calls to other resources or add to the task que so that the client does not have to wait for the extra writes that update the denormalized portions of the data.

    Tables:

    Appointment
    start_time
    etc...

    Invoice
    due_date
    etc...

    Payment
    invoice_Key_List
    amount_paid
    etc...

    Line_Item
    appointment_Key_List
    invoice_Key
    name
    price
    etc...

    以下是将给定约会列表的所有四个实体(表)联系在一起所需的一系列查询和操作。这将包括有关为每次约会安排的服务、每次约会的总费用以及天气或每次约会未收到付款的信息。在加载日历以进行约会安排或让经理获得操作的整体 View 时,这将是一个常见的查询。
  • 查询“开始时间”字段位于给定范围之间的“约会”列表。
  • 将返回的约会中的每个键添加到列表中。
  • QUERY 对所有“Line_Items”的约会_key_List 字段包括任何退货约会
  • 将所有行项目中的每个 invoice_key 添加到 Set 集合中。
  • 查询发票集合中的所有“发票”(这可以使用应用引擎在一个异步操作中完成)
  • 将返回发票中的每个键添加到列表中
  • QUERY for all "Payments"who's invoice_key_list 字段包含匹配任何返回发票的键
  • 在内存中重新组织,以便每个约会都反射(reflect)为其安排的 line_items、总价格、总估计时间和天气是否已付款。

  • ...如您所见,此操作需要 4 个数据存储查询以及一些内存中组织(希望内存中会很快)

    任何人都可以评论这个设计吗?这是我能想到的最好的,但我怀疑可能有更好的选择或完全不同的设计,我没有想到这些可能在一般情况下或特别是在 GAE(谷歌应用程序引擎)的优势、劣势和能力下工作得更好.

    谢谢!

    用法说明

    大多数应用程序的读取密集程度更高,有些应用程序的写入密集程度更高。下面,我将描述一个典型的用例并分解用户想要执行的操作:

    经理接到客户电话:
  • 阅读 - 经理加载日历并查找可用时间
  • 写信 - 经理向客户查询他们的信息,我想象这是在经理输入每条信息(如电话号码、姓名、电子邮件、地址等)时的一系列异步读取...在客户端应用程序收集所有信息并提交之后。
  • 写信 - 经理删除客户的信用卡信息并将其作为单独的操作添加到他们的记录中
  • 写信 - 经理向信用卡收费并验证付款是否通过

  • 经理拨出电话:
  • 阅读 经理加载日历
  • 阅读 经理为他要调用的客户加载预约
  • 写信 经理点击“调用”按钮,发起调用并写入一个新的 CallReacord 实体
  • 阅读 调用服务器响应调用请求并读取CallRecord 以了解如何处理调用
  • 写信 调用服务器将更新的信息写入 CallRecord
  • 写信 当调用关闭时,调用服务器向服务器发出另一个请求以更新 CallRecord 资源(注意:此请求不是时间紧迫的)

  • 接受的答案::
    前两个答案都非常周到和赞赏。为了尽可能地不完全平衡他们的曝光率,我接受了票数很少的那个。

    最佳答案

    您指定了您的网站需要提供的两个特定“ View ”:

  • 安排约会。您当前的方案应该可以正常工作 - 您只需要执行您提到的第一个查询。
  • 操作的整体 View 。我不太确定这意味着什么,但是如果您需要执行上面提到的四个查询的字符串来获得它,那么您的设计可以使用一些改进。详情如下。

  • 四个数据存储查询本身并不一定是过分的。您的情况的问题是其中两个查询很昂贵,甚至可能是不可能的。我将通过每个查询:
  • 获取约会列表 - 没问题。此查询将能够扫描索引以有效地检索您指定的日期范围内的约会。
  • 从 #1 中获取每个约会的所有行项目 - 这是一个问题。此查询要求您执行 IN询问。 IN查询转换为 N sub-queries behind the scenes - 所以你最终会得到一个来自 #1 的约会键的查询!这些将并行执行,所以还不错。主要问题是IN查询仅限于一小部分值(最多只有 30 个值)。如果#1 返回的约会键超过 30 个,则此查询将无法执行!
  • 获取行项目引用的所有发票 - 没问题。您是正确的,此查询很便宜,因为您可以直接通过键获取所有相关发票。 (注意:这个查询仍然是同步的——我认为异步不是你要找的词)。
  • 获取 #3 返回的所有发票的所有付款 - 这是一个问题。与#2 一样,此查询将是 IN查询并且如果 #3 返回您需要获取付款的中等数量的发票,则会失败。

  • 如果#1 和#3 返回的项目数量足够小,那么GAE 几乎肯定能够在允许的范围内做到这一点。这应该足以满足您的个人需求 - 听起来您最需要它来工作,并且不需要它来扩展到大量用户(它不会)。

    改进建议:
  • 非规范化! 尝试存储 Line_Item 的 key , Invoice , 和 Payment与约会本身的列表中的给定约会相关的实体。然后你可以消除你的IN查询。确保这些新 ListProperty不是 已编入索引以避免 exploding indices 出现问题

  • 其他不太具体的改进想法:
  • 根据您的“整体操作 View ”将显示什么,您可能能够拆分所有这些信息的检索。例如,也许您首先显示约会列表,然后当经理想要有关特定约会的更多信息时,您可以继续获取与该约会相关的信息。如果此交互发生在单个页面上,您甚至可以通过 AJAX 执行此操作。
  • Memcache 是您的 friend - 使用它来缓存数据存储查询的结果(甚至更高级别的结果),这样您就不必在每次访问时从头开始重新计算它。
  • 关于google-app-engine - 数据库设计 - 谷歌应用引擎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3120192/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com