Mysql 在为Rails模型创建对象之前获取下一个对象Id
我有一个Mysql 在为Rails模型创建对象之前获取下一个对象Id,mysql,ruby-on-rails,ruby,information-schema,Mysql,Ruby On Rails,Ruby,Information Schema,我有一个模型在我的模型中创建该对象之前,我需要获取要创建的下一个记录id,如: MyModel.last.id #=> 10 MyModel.last.destroy MyModel.last.id #=> 9, so (Model.last.id + 1) would be 10... but... MyModel.create #=> 11, my next id was actually 11 你能建议一个更好的方法来解决我的问题吗 谢谢您正在查找表的自动增量值。My
模型
在我的模型中创建该对象之前,我需要获取要创建的下一个记录id,如:
MyModel.last.id #=> 10
MyModel.last.destroy
MyModel.last.id #=> 9, so (Model.last.id + 1) would be 10... but...
MyModel.create #=> 11, my next id was actually 11
你能建议一个更好的方法来解决我的问题吗
谢谢您正在查找表的自动增量值。MySQL将这些元数据存储在数据库中。自动增量值可在表中找到。该表包含每个数据库和表的一个条目 我认为Rails或MySQL gem没有提供任何内置的获取方法 我在以前的一个项目中使用过类似的方法:
# config/initializers/auto_increment.rb
module AutoIncrement
def auto_increment_value
connection.execute(<<-SQL.squish).first[0]
SELECT `AUTO_INCREMENT`
FROM `INFORMATION_SCHEMA`.`TABLES`
WHERE `TABLE_SCHEMA` = '#{connection.current_database}'
AND `TABLE_NAME` = '#{table_name}'
SQL
end
end
ActiveRecord::Base.extend(AutoIncrement)
它将返回表的自动增量值的当前值,例如11
请注意,将该值用作记录的显式ID是不安全的。您应该让MySQL处理新ID的分配——这就是AUTO_INCREMENT的作用。您正在寻找表的AUTO_INCREMENT值。MySQL将这些元数据存储在数据库中。自动增量值可在表中找到。该表包含每个数据库和表的一个条目 我认为Rails或MySQL gem没有提供任何内置的获取方法 我在以前的一个项目中使用过类似的方法:
# config/initializers/auto_increment.rb
module AutoIncrement
def auto_increment_value
connection.execute(<<-SQL.squish).first[0]
SELECT `AUTO_INCREMENT`
FROM `INFORMATION_SCHEMA`.`TABLES`
WHERE `TABLE_SCHEMA` = '#{connection.current_database}'
AND `TABLE_NAME` = '#{table_name}'
SQL
end
end
ActiveRecord::Base.extend(AutoIncrement)
它将返回表的自动增量值的当前值,例如11
请注意,将该值用作记录的显式ID是不安全的。您应该让MySQL处理新id的分配——这就是自动增量的作用。为什么要担心id?如果您对一个连续的数字有其他原因,请在创建之前使用另一个字段并在上执行一些select max操作
FWIW、MySQL和Mariadb auto increment仅在数据库重新启动时重置,这避免了争用情况。为什么要担心id?如果您对一个连续的数字有其他原因,请在创建之前使用另一个字段并在上执行一些select max操作
FWIW、MySQL和Mariadb auto increment仅在数据库重新启动时重置,这避免了竞争情况。您使用的是什么数据库?我使用的是MySQL我想您需要一个新的数据库。坏消息是,这在rails中并不常见。事实上,我还没有在我的实践中看到它的一个用法。但是这个想法是可靠的,我想不出任何好的使用案例。正如@SergioTulentsev所指出的,实际使用这些信息的大多数方法都会包含竞争条件。@MoMolog:有原子/安全的方法来获取下一个id(例如PG中的序列)。至于如何使用它:准备一个互连对象的图形,然后一次插入所有对象。你在使用什么数据库?我在使用MySQLI。我想你需要一个数据库。坏消息是,这在rails中并不常见。事实上,我还没有在我的实践中看到它的一个用法。但是这个想法是可靠的,我想不出任何好的使用案例。正如@SergioTulentsev所指出的,实际使用这些信息的大多数方法都会包含竞争条件。@MoMolog:有原子/安全的方法来获取下一个id(例如PG中的序列)。至于如何使用它:准备一个互连对象的图,然后一次将它们全部插入。这不是很容易出现竞争条件吗?@SergioTulentsev它只是从数据库表中获取一个值。你是什么意思?两个线程获取相同的值并尝试将其用作id。或者简单地执行此选择也会神奇地更新计数器?这很公平。不管怎样,我想警告不会有什么坏处:)@SergioTulentsev你的权利,我添加了一个警告。我使用该代码检查最高id是否与自动增量值匹配,以确定是否删除了最新记录–用户当时可以选择重新使用该id。这不是非常容易出现争用情况吗?@SergioTulentsev它只是从数据库表中获取一个值。你是什么意思?两个线程获取相同的值并尝试将其用作id。或者简单地执行此选择也会神奇地更新计数器?这很公平。不管怎样,我想警告不会有什么坏处:)@SergioTulentsev你的权利,我添加了一个警告。我使用该代码检查最高id是否与自动增量值匹配,以确定是否删除了最新记录–然后用户可以选择重新使用该id。