最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

Postgres的自动增量时重复键错误发生

IT培训 admin 5浏览 0评论

Postgres的自动增量时重复键错误发生

我有一个模型和迁移定义:

module.exports = (sequelize, DataTypes) => {
const user = sequelize.define('user', {
    name: DataTypes.STRING,
    username: DataTypes.STRING,
    email: DataTypes.STRING,
    password: DataTypes.STRING,
},
    {})

user.associate = function (models) {
    // associations can be defined here
}

return user

}

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        allowNull: false,
        type: Sequelize.STRING
      },
      username: {
        unique: true,
        allowNull: false,
        type: Sequelize.STRING
      },
      email: {
        allowNull: false,
        type: Sequelize.STRING
      },
      password: {
        allowNull: false,
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('users');
  }
};

当我试图创建一个具有重复的键值(电子邮件或用户名在这种情况下)的新用户user.create({...}) sequelizes throwns一个错误预期,即便如此,它增加了德主键自动递增值。

例如:我创建具有id 1一个新的用户,那么我尝试创建具有重复的唯一密钥(用户名或电子邮件)的新用户的5倍,则当我成功创建用户,主键id变为6。

为什么出现这种情况?正确的将是按照顺序,如果错误则不会增加,只有当用户被成功插入递增。

回答如下:

我应该由一个序列生成的值。

那么这是所有DBMS序列的正常行为。

想象一下以下情形。

  1. User 1要求一个新的ID。他得到id = 1
  2. User 2要求一个新的ID。他得到id = 2
  3. User 1未能在从属表中插入一条记录。他执行rollback
  4. User 2成功插入每一个他所需要的。他执行commit

现在想象一下,需要何种重用id = 1与序列,因为它没有提交。

  • 滚动序列回1?复杂,因为它需要记住它返回id = 2给其他用户。
  • 替代哪些用户2已经通过插入id=1?昂贵,由于外键和风险(User 2可以使用id=2映射到内存的对象软件,它是来不及更改DB的ID)
  • 使用户2等到用户1已经提交或回滚了他的事务知道该怎么回报?每个人都在等待所有的时间。

最重要的是,在id连续值插入记录仍然不足以为它连续入住。上表中的第delete将打破了这一切。

结论:确保IDS是连续的成本是疯狂的DB的性能和价值是不存在的,因为它可以在任何时候打破。

Postgres的自动增量时重复键错误发生

我有一个模型和迁移定义:

module.exports = (sequelize, DataTypes) => {
const user = sequelize.define('user', {
    name: DataTypes.STRING,
    username: DataTypes.STRING,
    email: DataTypes.STRING,
    password: DataTypes.STRING,
},
    {})

user.associate = function (models) {
    // associations can be defined here
}

return user

}

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        allowNull: false,
        type: Sequelize.STRING
      },
      username: {
        unique: true,
        allowNull: false,
        type: Sequelize.STRING
      },
      email: {
        allowNull: false,
        type: Sequelize.STRING
      },
      password: {
        allowNull: false,
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('users');
  }
};

当我试图创建一个具有重复的键值(电子邮件或用户名在这种情况下)的新用户user.create({...}) sequelizes throwns一个错误预期,即便如此,它增加了德主键自动递增值。

例如:我创建具有id 1一个新的用户,那么我尝试创建具有重复的唯一密钥(用户名或电子邮件)的新用户的5倍,则当我成功创建用户,主键id变为6。

为什么出现这种情况?正确的将是按照顺序,如果错误则不会增加,只有当用户被成功插入递增。

回答如下:

我应该由一个序列生成的值。

那么这是所有DBMS序列的正常行为。

想象一下以下情形。

  1. User 1要求一个新的ID。他得到id = 1
  2. User 2要求一个新的ID。他得到id = 2
  3. User 1未能在从属表中插入一条记录。他执行rollback
  4. User 2成功插入每一个他所需要的。他执行commit

现在想象一下,需要何种重用id = 1与序列,因为它没有提交。

  • 滚动序列回1?复杂,因为它需要记住它返回id = 2给其他用户。
  • 替代哪些用户2已经通过插入id=1?昂贵,由于外键和风险(User 2可以使用id=2映射到内存的对象软件,它是来不及更改DB的ID)
  • 使用户2等到用户1已经提交或回滚了他的事务知道该怎么回报?每个人都在等待所有的时间。

最重要的是,在id连续值插入记录仍然不足以为它连续入住。上表中的第delete将打破了这一切。

结论:确保IDS是连续的成本是疯狂的DB的性能和价值是不存在的,因为它可以在任何时候打破。

发布评论

评论列表 (0)

  1. 暂无评论