【问题标题】:Rails database structure and optimisation adviceRails 数据库结构和优化建议
【发布时间】:2012-08-12 05:35:19
【问题描述】:

我的 Rails 应用程序是一个用户在彼此之间交易项目的系统。用户对项目出价,然后所有者批准创建交易的出价。然后,用户可以在事务上编写 cmets(消息)来组织应用程序之外的事物。到目前为止,我的结构是这样的:

User
    has_many :items
    has_many :bids

Item 
    belongs_to :user
    has_many :bids

Bid
    belongs_to :item
    belongs_to :user
    has_one :transaction

Transaction
    belongs_to :bid
    has_many :messages

Message
    belongs_to :transaction
    belongs_to :from, :class_name => "User"
    belongs_to :to, :class_name => "User"

我认为这在减少冗余方面效果很好,但我在有效地获取数据方面遇到了一些问题。例如,要检索user 的“给定项目”(即其中一个投标存在交易的用户项目),我正在做:

user.items.joins(:bids).where("bids.id" => Transaction.select("bid_id"))

或收到的物品:

Item.joins(:bids).where("bids.user_id" => user.id).where("bids.id" => Transaction.select("bid_id"))

这对于我想要的信息来说似乎相当昂贵。

更重要的是,我想汇总用户的交易并显示给定物品与收到物品的比率,这可能会显示在任何给定页面上的用户名旁边。目前我正在做的是获取并计算所有用户在上面给出和接收的项目,然后除以(这是非常昂贵的......)。我想在 User 表上设置一个带有 received_count 和 given_count 的列,每次创建或销毁事务时都会更新,但这似乎不可靠。

我的问题是,有没有更好的方法来构建我的数据,以便更简单地获取用户交易等信息,同时保持标准化?

谢谢!

【问题讨论】:

    标签: mysql ruby-on-rails database postgresql activerecord


    【解决方案1】:

    通常,规范化和性能是一种权衡。在您的情况下,我认为将额外的列添加到 Users 表以有效地缓存结果是有意义的。您还可以在项目中添加一个额外的列,以显示它们是否有交易出价。

    规范化确实是一个基本原则,而不是您认为需要坚持以确保正确性的东西,缓存常用结果即使它会产生冗余也是一个非常好的方法。

    唯一的其他选择是实际使用缓存(例如,memcached)。这可以让您将计数存储在实际缓存中,并在该用户发生新事务时“销毁”它们。

    【讨论】:

    • 感谢您的建议——这让我对现在添加额外的缓存列更有信心。也许我会研究一下 memcached(我正在 Heroku 上部署,所以直接添加额外的进程有点多..)
    • 时机成熟时,heroku 让 memcached 的使用变得非常简单(当然要多花一点钱)。
    【解决方案2】:

    放弃严格的标准化。对于像Transaction 这样的档案模型,您至少应该在其上存储两个^user_ids(sender_id,receiver_id)和item_id。出价不会更改其项目或用户,因此您在这里非常省钱。如果您经常显示这些用户名,您甚至可能希望在其上存储这些用户名。

    非规范化数据库还不错,一旦你开始使用像 mongodb 或 couchdb 这样的数据库,你会更频繁地使用它。

    【讨论】:

    • 谢谢,我想我也会采用这种方法。可能我对最终正常化的渴望仍然从大学教授那里根深蒂固。
    猜你喜欢
    • 2011-07-03
    • 2011-11-30
    • 1970-01-01
    • 2018-04-21
    • 2011-05-02
    • 2012-01-06
    • 1970-01-01
    • 2011-02-09
    相关资源
    最近更新 更多