如何使用Sequelize实现数据表仅允许写入唯一行数据
解决方案
要实现Requirement_id、Resource_id、User_id三个字段的组合唯一校验,仅需在现有Sequelize模型中添加复合唯一约束即可,两种常用实现方式如下:
方式1:字段直接绑定同名唯一约束
直接在三个字段的定义中添加unique属性,绑定到同一个自定义的约束名即可,修改后的完整代码如下:
module.exports = (sequelize, Sequelize) => { const BookmarkTbs = sequelize.define("BookmarkTbs", { Bookmark_id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, Requirement_id: { type: Sequelize.INTEGER, allowNull: true, references: { model: 'RequirementsTbs', key: 'Requirement_id' }, onUpdate: 'CASCADE', onDelete: 'CASCADE', // 绑定到同名复合唯一约束 unique: 'unique_bookmark' }, Resource_id: { type: Sequelize.INTEGER, allowNull: true, references: { model: 'ResourceTbs', key: 'Resource_id' }, onUpdate: 'CASCADE', onDelete: 'CASCADE', // 绑定到同名复合唯一约束 unique: 'unique_bookmark' } , User_id: { type: Sequelize.INTEGER, allowNull: false, references: { model: 'UsersTbs', key: 'User_id' }, onUpdate: 'CASCADE', onDelete: 'CASCADE', // 绑定到同名复合唯一约束 unique: 'unique_bookmark' } }); return BookmarkTbs; };
方式2:通过索引配置实现
如果需要对索引做额外配置,可以在模型的全局配置项中添加唯一索引,原有字段定义不需要做任何改动:
// 仅展示新增配置部分,其余字段代码保持不变 const BookmarkTbs = sequelize.define("BookmarkTbs", { // 原有字段定义完全保留 }, { indexes: [ { unique: true, fields: ['Requirement_id', 'Resource_id', 'User_id'] } ] });
注意事项
- 配置完成后需要同步表结构才会生效:开发环境可使用
sequelize.sync({alter: true})自动更新,生产环境建议手动编写迁移脚本执行变更。 - MySQL数据库的唯一约束默认不校验NULL值:如果某条记录的
Requirement_id或Resource_id为NULL,即使另外两个字段与已有记录完全一致,也不会被判定为重复。如果需要覆盖这类场景的唯一校验,可将两个关联ID字段的allowNull改为false,默认值设为0,即可实现全场景的组合重复拦截。
内容的提问来源于stack exchange,提问作者Deepak Dev
相关产品推荐
相关产品推荐

