【问题标题】:Postgres and Ruby - Is there a better way to structure my database?Postgres 和 Ruby - 有没有更好的方法来构建我的数据库?
【发布时间】:2021-01-03 17:20:32
【问题描述】:

我现在正在计划我的数据库。在将我的 ERD 放在一起的过程中,我很快注意到所有表都与我的 shops 表和我的 amazon_credentials 表相关。是否有更好/更有效的设计或关系可以让我的数据库更高效和易于使用?

Here is a link to my current ERD in Whimsical

还有一个警告,我不想通过我的amazon_credentials 表进行所有查询。例如..我希望能够同时执行此Shop.find(1).packing_slips 并获得所有packing_slips 以获得shop 以及能够执行此Shop.find(1).amazon_credentials.packing_slips 以获得特定市场的packing_slips .

考虑到这一点,我几乎使用我的amazon_credentials 表作为marketplace 的替代品,因为凭据本质上是marketplace

这是一个好的设计还是有更好的方法?

【问题讨论】:

  • 您拥有它,因此商店可以拥有 0 个或多个 Amazon 凭证。这就是你想要的吗?
  • 你在使用 Rails 吗? “我不想通过我的 amazon_credentials 表进行所有查询” 为什么不呢?
  • @Schwern hi.. 是的,使用 Rails.. 是的,shop 可以是 0 个或多个 amazon_credentials
  • 如果一个商店可以有多个 AmazonCredentials,你怎么知道使用哪个?
  • @Schwern 它基于 order 中的客户地址。 amazon_credentials 中的 marketplace 涵盖特定国家/地区。并根据客户地址使用正确的凭据集..

标签: ruby-on-rails


【解决方案1】:

与分散在数据库中的 Shops 和 AmazonCredentials 的重复关系可以替换为间接关系。幸运的是,Rails 提供了使间接关系看起来直接的方法:has_many :through

而且您不需要第一次就完美,也不需要预测所有可能的用途。 Migrations 帮助您安全地更改设计以满足不断变化的需求。

让我们建立基本的关系。我做了一些假设,例如运输方式与市场相关。

  • 一个产品有关于它自己的信息。

  • 商店拥有产品、营销方式(市场)、这些市场的凭据和订单。

  • 订单包含下订单的人、来自哪个商店、通过哪个市场、订购了哪些产品、以什么价格订购了多少、如何发货以及如何跟踪。

  • 市场有 ShippingMethods。

我们马上遇到了一个问题:凭据。商店需要每个 Marketplace 的凭据。这可以通过一个中间模型来解决:MarketplaceAccount,它将 Shop 和 Marketplace 与 Shop 的凭据结合在一起。凭证可以做成键/值对的行。

订单需要记住有关订购了哪些产品、数量和价格的详细信息。这需要另一个中间模型:ProductOrder。

基本模型如下所示:

class Product < ApplicationRecord
  belongs_to :shop

  has_many :product_orders
  has_many :orders, through: :product_orders
  has_many :customers, through: :orders

  # name
  # description
  # sku
end

class Shop < ApplicationRecord
  has_many :products

  has_many :marketplace_accounts
  has_many :marketplaces, through: :marketplace_accounts
  
  has_many :orders
  has_many :customers, through: :orders

  # name
  # country
end

class Order < ApplicationRecord
  belongs_to :customer

  # Remember which MarketplaceAccount this was done with
  belongs_to :marketplace_account
  has_one :shop, through: :marketplace_account
  has_one :marketplace, through: :marketplace_account

  # How is it being shipped?
  belongs_to :shipping_method
  
  has_many :product_orders
  has_many :products, through: :product_orders

  # tracking number
  # status
end

class ProductOrder < ApplicationRecord
  belongs_to :order
  belongs_to :product

  # price
  # quantity
end

# Holds the Shop's credentials for a Marketplace.
class MarketplaceAccount < ApplicationRecord
  belongs_to :shop
  belongs_to :marketplace
  has_many :credentials
end

# Each row is simply a key and value.
# Consider encrypting this table.
class Credentials < ApplicationRecord
  belongs_to :marketplace_account

  # key
  # value
end

class Marketplace < ApplicationRecord
  has_many :shipping_methods

  has_many :marketplace_accounts
  has_many :shops, through: :marketplace_accounts

  # name
end

class ShippingMethod < ApplicationRecord
  belongs_to :marketplace
  has_many :shops, through: :marketplace

  # speed
  # rate
  # name
end

class Customer < ApplicationRecord
  has_many :orders
  has_many :product_orders, through: :orders
  has_many :products, through: :product_orders
end

通过使用has_many :throughhas_one :through,我们可以避免重复,同时使间接关系看起来很直接。一个 Shop has_many MarketplaceAccounts,一个 MarketplaceAccount 属于一个 Marketplace;使用has_many :marketplaces, through: :marketplace_accounts,商店可以直接访问其市场。 shop.marketplaces.

键/值凭据表避免了公司特定凭据表的激增。


可以充实更多的关系。一个产品可以被许多商店出售,所以我们可以有一个 ShopProduct 将通用产品与商店的销售方式联系起来。这样可以避免重复的产品信息,并让您可以看到许多商店如何销售单个产品。

class Product < ApplicationRecord
  has_many :shop_products

  # sku
  # generic name
  # generic description
  # manufacturer's recommended price
end

class ShopProduct < ApplicationRecord
  belongs_to :shop
  belongs_to :product

  delegate :sku, to: :product

  # shop specific name
  # shop specific description
  # shop price
end

class Shop
  has_many :shop_products
  has_many :products, through: :shop_products
end

大多数事情都与 ShopProduct 而不是 Product 相关。


您有一家使用单一货币的商店。该设计可以扩展为允许商店使用多种货币。

class Currency < ApplicationRecord
  # symbol
  # conversion rate
end

class ShopCurrencies < ApplicationRecord
  belongs_to :shop
  belongs_to :currency
end

class Shop < ApplicationRecord
  has_many :shop_currencies
  has_many :currencies, through: :shop_currencies
end

has_many :currencies, through: :shop_currenciesshop.currencies 工作。


这就是基础。有了这些,您就可以根据自己的需要来确定基本布局。

【讨论】:

  • 非常感谢您的深入解答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
相关资源
最近更新 更多