【问题标题】:MySQL database structure advice needed. Two many-to-many from one table to two other that are in one-to-many relation需要 MySQL 数据库结构建议。从一个表到另外两个具有一对多关系的两个多对多
【发布时间】:2016-08-09 20:46:53
【问题描述】:

我有这个设置作为我的数据库结构,它已经运行得很好,但我觉得它可能会更好,但不知道如何。

数据库结构:-

事件可以有多个子事件。用户可以加入这些活动,也可以选择加入他们的子活动。使用这种结构,我有所有限制,但是将参加的活动与参加子活动的人联系起来的那个=>可能会留下没有参加主要活动的子活动参加者(这对于不参加的用户来说是不可能的主赛事不能参加副赛事)。

我目前正在使用 Laravel,所以它看起来像这样:

用户

  • hasMany Event(作为这些活动的组织者)
  • belongsToMany EventAttending(用户加入哪些事件)
  • belongsToMany SubEventAttending(哪些子事件是用户加入)

事件

  • 属于用户
  • hasMany 子事件
  • belongsToMany EventAttending(哪些用户正在参加此活动)

子事件

  • 属于事件
  • belongsToMany SubEventAttending(哪些用户正在参加此子活动)

在尝试管理用户的子活动参加时会出现问题。我如何在活动和子活动参加者之间建立这种约束,同时利用 Laravel 的功能保持它的清洁/您可以提供什么建议来更好地组织/你们会怎么做?

编辑

为了澄清,事件和子事件存储不同的东西,具有不同的属性。我还需要存储活动参加者的信息(就像他在现实生活中参加的那样)和子活动参加者,很可能是不同的。

编辑

Edward Haber 具有更好的结构,但由于我的两个数据透视表(User-Event 和 User-SubEvent 之间的连接)存储了其他不同类型的信息,目前选择保留初始设计。

我面临的最大问题之一(这两种结构都存在)是在使用参与的子事件获取参与的事件时查询用户。试图达到这个结果:

User[]:{  
  ...,  
    attending_events[]:{  
      ...,  
       attending_sub_events[]:{  
         ...  
       }  
    }  
}

想了好几个小时才找到一个干净的解决方案,但没有其他方法可以工作。不想手动编写整个 SQL 查询。我当前使用两个数据透视表的实现如下所示(结果未嵌套,代码混乱):

$users = User::withCount(['attendingEvents' => function($query) use($eventId){
            $query->where('event_id', $eventId);
        }])
        ->with(['attendingSubEvents' => function($query) use($eventId){
            $query->select('id')->whereHas('event', function($query) use($eventId){
                $query->where('id', $eventId);
            });
        }]);

通过这种方法,我将子事件与主要事件分开。 (只查询主要出席人数,因为我只需要确定他是否参加)。

【问题讨论】:

  • 我认为你真的只有 3 张桌子:usersevents(子事件实际上只是没有organizer 的事件)和events_users(正在参加事件的用户/子-事件。
  • 我同意本尼的观点。在这种情况下,事件和子事件之间的唯一区别似乎是 Organizer_id 和 event_id。 event: id, organizer_id, event_idevent_user: event_id, user_id 子事件查询:SELECT * FROM event WHERE event_id is NOT NULL
  • 子事件的字段类型与事件不同。基本上我需要为每个存储不同的东西,所以不能真正合并它们......我认为这不实用。

标签: mysql database laravel data-structures table-relationships


【解决方案1】:

这种解决方案的模式是使用Polymorphic Relationship。此解决方案仅关注将用户连接到事件和子事件 - 其余关系看起来正确。

<?php
class User extends Model {
    public function attending() {
        return $this->morphTo();
    }
}

<?php 
class Event extends Model {
    public function attendees() {
        return $this->morphMany('App\User', 'attending')
    }
}


<?php 
class Subevent extends Model {
    public function attendees() {
        return $this->morphMany('App\User', 'attending')
    }
}

users 表需要这些字段:

*users*
-----
id
attending_id
attending_type

这一切都未经测试 - 但基本思想。 (已编辑:将多态方法的名称更改为从参加者参加)

【讨论】:

  • 这看起来很有希望,我必须研究一下。我忘了提到,对于两个不同的主治医生,我需要存储额外的信息,你能建议一个干净的方法来实现吗(更新了关于这个的主要帖子。)
  • 是的,这正是多态行为的重点。因此 subvent 和 event 可以具有不同的功能,具体取决于连接到 User 对象的功能。在真正的多态情况下,这些类将共享一个公共接口,并且可以对每个类执行公共方法调用。但是你也可以抽象出这个问题,让它们不共享一个接口。但是是的,这个例子假设它们 Event 和 Subevent 不能组合并且是不同的表。
  • 我明白这一点,但我说的是数据透视表。对于参加主要活动的人,我需要将 X 类型信息存储在 pivot 表中,而对于参加子活动的人,我需要将 Y 类型信息存储在 pivot 中。另一个问题是如何在获取用户是否加入特定事件(按事件 ID)以及是否是他加入的子事件时查询用户。
  • 用户表结构应该是数据透视表——我的错误。 Attend_id 是对象的 id(事件或子事件),出席类型是 eloquent 模型的全名,包括命名空间(事件或子事件)。另请查看 morphMany()。
  • 是的,我想你写错了。但是,这种结构与我面临的问题相同,请检查更新的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 2019-11-07
  • 2011-08-10
相关资源
最近更新 更多