【问题标题】:SQL guaranteed start/end index?SQL保证开始/结束索引?
【发布时间】:2009-09-27 11:32:11
【问题描述】:

我(将)有数十万条记录,我插入一次,永远不会更新许多行包含相同的previousId。我可以保证一个开始/结束索引吗?我用事务在 table_c 中插入 X 行,并将开始和结束(或开始和长度或结束和长度)写入 table_b,而不是让每一行都保存 table_b ID?

如果是这样,我该如何编写 SQL?我在想

begin transaction
insert XYZ rows into tbl_c
c_rowId = last_insert_rowid
insert table_b with data + start=c_rowId-lengthOfInsert, end=c_rowId;
commit; end transaction

这会像我预期的那样工作吗?

【问题讨论】:

    标签: sql transactions bulkinsert


    【解决方案1】:

    看起来你想要的是一个自动编号列。在大多数 DBMS 中,您可以将此列定义为表定义的一部分,它会自动对行进行编号。您可以使用函数来获取插入的最后一行的 ID;在 SQL Server (T-SQL) 中,您可以使用 SCOPE_IDENTITY() 函数。如果 ID 必须是某个值或值范围,您可能需要手动执行此操作并使用锁定提示来防止另一个并发事务修改您的标识符信息。

    【讨论】:

    • 一些 dbs(例如 SQL Server)允许您为自动编号列播种,因此它会从您想要的任何地方开始。
    【解决方案2】:

    你可以使用tablockx锁定sql server中的全表。

    所以:

    begin the transaction, 
    select max(txnid) from table with (tablockx)  -- now the table is locked
    
    --figure out how many more you are going to insert 
    lastId = maxNum + numToInsert
    
    set allow insert auto_increment on insert -- not sure what this is
    
    while (moreToInsert)
      insert int table (id,x,y) values (id+1,'xx','yy')
    
    commit transaction
    

    这个问题是它完全锁定了表。自动递增列(auto_increment (mysql) 或标识 mssql)可能是您真正想要的,并且不会限制对整个表的访问。 (这在另一个答案中注明)

    【讨论】:

      猜你喜欢
      • 2013-12-11
      • 1970-01-01
      • 2021-10-15
      • 2021-11-10
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      相关资源
      最近更新 更多