为不同的关联提供相同的N:M表

时间:2018-06-08 15:34:21

标签: mysql sql database sequelize.js

在Node + MySQL项目中,我得到了4个表:

  • Users描述了注册用户
  • InvitedUsers原型用户,包含非注册用户的一些信息,
  • Projects描述了一个项目,
  • ProjectMembers ProjectsUsers
  • 的N:M关联

现在我得到了N:M的联想:

Users.belongsToMany(Projects, { through: ProjectMembers });
Projects.belongsToMany(Users, { through: ProjectMembers });

我需要使用相同的ProjectMembers表作为N {M表示InvitedUsersProjects

这可能吗?我想这不是因为N:M表上的外键约束无法选择哪个表(UsersInvitedUsers)必须应用

我尝试添加(省略选项):

InvitedUsers.belongsToMany(Projects, { through: ProjectMembers });
Projects.belongsToMany(InvitedUsers, { through: ProjectMembers });

在关联定义期间没有显示错误,但是当我尝试在ProjectMembers表中添加InvitedUsers的id作为FK的条目时,我得到了外键约束错误。

所以我的问题是我是否可以将N:M表用于不同的N:M关系。

3 个答案:

答案 0 :(得分:4)

从MySQL的角度讲......

很多:许多数据库表基本上是2列(project_idperson_id),有两个索引((project_id, person_id)(person_id, project_id))。如果合理地添加第3列来限定(“成员”与“受邀用户”)之间的关系类型。

对表格的更多讨论:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

答案 1 :(得分:1)

是的,只要您指定关联应该用于加入表的foreignKey,就可以这样做。您可以指定两个不同的键,一个用于user,另一个用于InvitedUser,Sequelize将选择正确的键。

User.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'user_id' });
Project.belongsToMany(User, { through: ProjectMembers, foreignKey: 'project_id' });
Invited.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'invited_id' });
Project.belongsToMany(Invited, { through: ProjectMembers, foreignKey: 'project_id' });

这就是project_members的架构看起来像

的样子

Schema for n:m relation

以下是完整的工作代码

const User = sequelize.define('user', {
  username: Sequelize.STRING,
});

const Invited = sequelize.define('invited', {
  username: Sequelize.STRING,
});

const Project = sequelize.define('project', {
  name: Sequelize.STRING,
});

const ProjectMembers = sequelize.define('project_members', {
  id: {
    allowNull: false,
    autoIncrement: true,
    primaryKey: true,
    type: Sequelize.INTEGER,
  },
  user_id: {
    type: Sequelize.INTEGER,
  },
  project_id: Sequelize.INTEGER,
  invited_id: Sequelize.INTEGER,
});

User.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'user_id' });
Project.belongsToMany(User, { through: ProjectMembers, foreignKey: 'project_id' });
Invited.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'invited_id' });
Project.belongsToMany(Invited, { through: ProjectMembers, foreignKey: 'project_id' });

sequelize.sync({ force: true })
  .then(() => {
    User.create({
      username: 'UserOne',
      projects: {
        projectName: 'projectOne'
      }
    }, { include: [Project] }).then((result) => {
      Invited.create({
        username: 'InvitedOne',
        projects: {
          projectName: 'projectTwo'
        }
      }, { include: [Project] }).then((result2) => {
        console.log(result2);

      })
    })
  })

答案 2 :(得分:0)

您是否尝试使用as中的belongsToMany选项创建不同的别名 所以,你的联想可能看起来像这样 -

//User-projects via ProjectMembers
Users.belongsToMany(Projects, { through: ProjectMembers, as: 'ProjectMembers' });
Projects.belongsToMany(Users, { through: ProjectMembers, as: 'ProjectMembers' });

//InvitedUsers-Projects via ProjectMembers
InvitedUsers.belongsToMany(Projects, { through: ProjectMembers, as: 'ProjectInvitedMembers' });
Projects.belongsToMany(InvitedUsers, { through: ProjectMembers, as: 'ProjectInvitedMembers' });