sql - Rails - 多个模型之间的公共(public)字段/报告数据 - STI、hstore 或拆分表?

标签 sql ruby-on-rails postgresql database-design

我有一个 Rails 应用程序,其中有一组模型(我们称它们为 Events),它们有一些共同的字段(datetitle, user_id), 但是我需要一些“子类型”。 SalesEvent 可能有一个 article_id 和一个 amountInterviewEvent 可能有一个 comments 字段。等等。

我知道我需要满足的 3 个业务要求:

  1. 在某些情况下,我想将 Events 作为一个整体来构建(即“获取该用户的所有 Events,并按时间顺序对它们进行排序,以月为单位进行分组")
  2. 在其他情况下,我只需要“子类型”(“获取该用户出售的所有商品”)。
  3. 子类型的数量可能会比较多(仍待定,但我们估计大约有 20 个,具体取决于用户反馈)

我正在考虑如何构建表格以支持此模型。我提出了 5 种可能的建模方法,但每种方法都有其自身的缺点。

  • 选项 A:单独的表 - sales_eventsinterview_events。这将使 2) 非常简单,并且 3) 可行,但是 1) 实现起来非常麻烦。
  • 选项 B:单表继承。这将或多或少地解决 1) 和 2),但是会出现需要越来越多的可空字段的问题,这与 3) 不兼容
  • 选项 C:使用 hstore - 由于我们在生产中使用 Postgres,我们可以使用 hstore - 我们将有一个由“类型”字符串字段管理的“数据”字段。这将解决 1)、2) 和 3),但将我们与 postgresql 联系在一起,并且我们将在我们不太熟悉的技术中实现关键业务对象。如果可能的话,我宁愿避免这种情况。
  • 选项 D:具有指向 ***_event_data 的多态链接的事件表。我们基本上会有一个带有类型和 event_data_id 的事件表,然后我们会有 sale_event_datainterview_event_data 等。这很好地满足了 1) 和 3),但是 2)与其他方法相比有点弱,因为在将事件与其数据链接起来时会涉及很多连接。
  • 选项 E:销售 has_one :event。这与选项 D 相同,除了“到另一个的链接”在“数据”部分。它还解决了1)和3),并且还涉及到2)中的一些连接,但看起来更“干净”一点;这里没有多态关联,只有“常规”sql 关联。

现在我倾向于使用选项 E。但我想知道是否有人看到它的明显缺点,或者其他选项之一的更大好处,或者我没有看到的更好的选项想到。

最佳答案

我几乎使用了您建议的所有选项。虽然我会出于以下原因排除选项 A、B 和 D,但我不能谈论 C,因为我不知道 hstore 并且不使用 Postgres:

  • 选项 A:如您所说,单独的表将很难维护。每次您想要更改events 的结构时,您都必须对所有sub_events 表进行更改。
  • 选项B:单表继承,我用了很多,放弃了。我觉得你在数据库中看到的和你的模型看起来像之间存在很大的设计缺陷。还有很多 nil 字段。
  • 选项 D:具有指向 *_event_data 的多态链接的事件表。多态表不是为了这个目的。它们是一种在模型中拥有不同 type 字段的方法,因此您可以在不明确指定类型的情况下引用它。

选项E 似乎可以,但是外键应该存储在哪里?很难说,可能会导致难以维护的情况。

就我个人而言,我会选择我想编写的代码,这样可以更轻松地使用和阅读它。我喜欢更具体的东西。我会简单地改变我命名我的模型的方式,以满足我的需要。你必须要有创意!

我宁愿写这样的东西:

conference.event_information.users OR
sales_event.settings.title OR
interview.shared_information.comments OR
event.interview_details.starting_at

对于所有这些示例,我将使用经典的 has_manybelongs_to 关系。

我认为数据类型和继承的整个概念可能会使您陷入无法解决问题或使事情更清晰的境地。有时您只需要以不同的方式看待事物。

希望对你有帮助。

关于sql - Rails - 多个模型之间的公共(public)字段/报告数据 - STI、hstore 或拆分表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10994514/

相关文章:

MySQL如何从另一个表更新表数据?表 A 中的 1 行映射到表 B 中的 2 行

mysql - 我怎样才能根据N得出一个近似的数字并接近现实?

ruby-on-rails - Rails 3.1:ECONNRESET(对等方重置连接

java - 如何通过与 hibernate 的多对多关系级联保存?

sql - 为具有自定义日期/时间格式的数据库实现 LINQ to SQL 表达式

mysql - 外键列的唯一约束

ruby-on-rails - Heroku 上出现 "invalid multibyte escape:/^\xFF\xFE/(SyntaxError)"错误

ruby-on-rails - 在 Rails 中处理 View 和仅助手常量的最佳方法

postgresql - 使用数据库备份文件安装 Openbravo

javascript - 通过一次 API 调用在多个表中创建多条记录的最有效方法是什么(sequelize/postgres/node.js)