如何在MySQL数据库中实现“收藏”关系?

时间:2013-07-26 18:24:08

标签: mysql database schema relational-database database-schema

我有一个显示表演者和场地列表的应用程序。应用程序的用户可以根据需要选择“喜欢”各种类型的“收藏”。我想知道是否有一种标准的方法可以在MySQL数据库中实现它。以下是我的选择:

  1. 只有一个表Favorite,存储UserID, Type, TypeID
    • Type可以是“演员”或“场地”
  2. 只有一个表Favorite,存储UserID, PerformerID, VenueID
    • 只允许PerformerIDVenueID中的一个拥有每个条目的值
  3. 有两个表Favorite_PerformerFavorite_Venue,每个表都存储UserID, PerformerIDUserID, VenueID
    • 我认为这是“关系性地做到这一点的最佳方式。”
  4. 每种方法有哪些优缺点,您对未来的可维护性有何建议?感谢。

1 个答案:

答案 0 :(得分:3)

选项3是最干净的。它使添加和删除最喜欢的最容易。这是ORM框架将实现的模式。

选项1是可行的,但您无法定义外键约束来强制执行完整性。在查询中添加谓词WHERE type='Venue',使得使用该表几乎就像使用单独的“Favorite_Venue”表一样。

选项2使添加收藏(如果已存在)变得复杂。 (这需要更新现有行,而不是插入。如果有人有两个最喜欢的场地,五个最喜欢的表演者,会有多少行?但至少可以定义外键。

假设我们有两个最喜欢的场地和两个最喜欢的表演者:

userID  venueID  performerID
------  ------- -----------
     1       11          177
     1     NULL          654
     1       12         NULL

删除收藏的venueID 11后,您将更新该行以将venueID设置为NULL。但是如果将sceneID 12作为收藏夹删除,您会将列设置为NULL,还是删除该行。当你去添加一个喜欢的表演者时,你会更新一个performerID为NULL的现有行,还是会插入一行。不是不可行,但它更复杂。

如果我们有一条规则表示只能填充其中一列的venueID或performerID,那么使用像WHERE venueID IS NOT NULL这样的谓词就可以使用这个表,就像使用单独的Favorite_Venue表一样。

最重要的是,我会选择选项3,除非有一些令人信服的理由不这样做。


这不是“混乱”。每个表Favorite_Venue和Favorite_Performer都有一个目的,一个“raison d'etre”,它就在那里。每个表都解决了多对多关系。

将这两个单独的“关系”表组合到一个表中实际上会产生混乱。如果我们添加一列来区分行(为了有效地回答问题,该行确实属于哪个表),该列就是“混乱”。如果我们在同一行上为两个关系使用两个单独的列,则会在处理添加或删除收藏夹的代码中产生混乱。