在Node + MySQL项目中,我得到了4个表:
Users
描述了注册用户InvitedUsers
原型用户,包含非注册用户的一些信息,Projects
描述了一个项目,ProjectMembers
Projects
和Users
现在我得到了N:M的联想:
Users.belongsToMany(Projects, { through: ProjectMembers });
Projects.belongsToMany(Users, { through: ProjectMembers });
我需要使用相同的ProjectMembers
表作为N {M表示InvitedUsers
和Projects
这可能吗?我想这不是因为N:M表上的外键约束无法选择哪个表(Users
或InvitedUsers
)必须应用
我尝试添加(省略选项):
InvitedUsers.belongsToMany(Projects, { through: ProjectMembers });
Projects.belongsToMany(InvitedUsers, { through: ProjectMembers });
在关联定义期间没有显示错误,但是当我尝试在ProjectMembers
表中添加InvitedUsers
的id作为FK的条目时,我得到了外键约束错误。
所以我的问题是我是否可以将N:M表用于不同的N:M关系。
答案 0 :(得分:4)
从MySQL的角度讲......
很多:许多数据库表基本上是2列(project_id
,person_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
的架构看起来像
以下是完整的工作代码
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' });