标题有点长此问题率先由 antoniusguo 提出 http://topic.csdn.net/u/20090729/21/2f156018-0dd0-4207-a556-f8c56b50057b.html要求设计一个表:
1, 有一列是自动增长的主键列 identity(1,1) not null;
2, 还有一列类似于自动增长的主键列 identity(1,1) not null, 默认时,值与上面的主键列的值相同,但可以修改,修改后已修改后的值为准;
3,不能使用触发器,可以使用诸如计算列,自定义函数等;4,重要!需考虑多用户并发操作时的数据准确,千万级数据量时的查询效率问题,不满足这条要求的设计不是合格的设计;提示:其实这问题一点也不难,就是看你是否思维灵活. 

解决方案 »

  1.   

    其实这个问题很简单,关键是你要转变思路。
    --看来楼主对触发器了解的不多,以为用触发器就是效率低下的,楼主敢说用计算列,自定义函数特别是自定义函数
    --效率就比触发器高?
    --其实一个小小的触发器就搞定,这个触发器也是效率非常高的。
    --每次你插入多少数据,就更新多少数据。
    --假设ID为自增字段,ID1为另一个字段
    create trigger tri_insert_tb on tb
    for insert as
    update tb set id1=tb.id from inserted where tb.id=inserted.id
      

  2.   

    楼主可以参考一下这个:
    http://blog.csdn.net/sdhdy/archive/2009/06/07/4249668.aspx
      

  3.   

    create table ask(
    id int identity(1,1) not null,
    id2 int ,
    c int
    )
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(@@identity,0)+1),1
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(@@identity,0)+1),2
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(@@identity,0)+1),7
    select * from ask
    DELETE FROM ASK WHERE ID=3
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(@@identity,0)+1),0
    SELECT * FROM ASK
    drop table ask
    /*
    id          id2         c
    ----------- ----------- -----------
    1           5           1
    2           2           2
    4           4           0*/
    --or
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(SCOPE_IDENTITY(),0)+1),1
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(SCOPE_IDENTITY(),0)+1),2
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(SCOPE_IDENTITY(),0)+1),7
    select * from ask
    DELETE FROM ASK WHERE ID=3
    INSERT  INTO ask(id2,C)  SELECT (SELECT isnull(SCOPE_IDENTITY(),,0)+1),0
    SELECT * FROM ASK
    drop table ask
    try
      

  4.   

    --函数
    create function ks3()
    returns int
    as 
    begin 
    return(select case when max(id) is null then 1 else max(id)+1 end from ask)
    end
    create table ask(
    id int identity(1,1) not null,
    id2 int default dbo.ks3(),
    c int
    )
    insert ask(c) values(1)
    insert ask(c) values(2)
    insert ask(c) values(6)
    select * from ask
    drop table ask
    /*
    id          id2         c
    ----------- ----------- -----------
    1           1           1
    2           2           2
    3           3           6(3 行受影响)
    --计算列create table ak(
    id int identity(1,1) not null,
    id2 as id,
    c int
    )
    insert ak(c)
    select 1 union all
    select 2 union all
    select 3 
    select * from akid          id2         c
    ----------- ----------- -----------
    1           1           1
    2           2           2
    3           3           3
    不过这2个 都有缺陷
      

  5.   

    用个表保存最大单号,一行一列,不建任何索引,每个进程算号时,先update单号+1, 再取出来, 这样update的锁定时间是很短的。
    不要把update的操作和后面插新单的操作放在一个事务中, 这样造成的对单号保存表的占用时间极短,就算后面的单号插入操作不成功,唯一造成的问题就是造成单号断号,并不影响实际使用。
      

  6.   

    你这样无法满足第2点,就是默认情况下,那一列的值和主键列相等,除非UPDATE了
      

  7.   

    考虑使用ROWVERSION数据类型。使用乐观并发不知道算不算高效的。
      

  8.   

    就知道钻牛角尖
    create table tmp(
    id int identity(1,1) not null,
    id2 int,
    c int
    )
    insert tmp (c) values (1)
    update tmp set id2=(select @@Identity) where id2 is null
    insert tmp (id2,c) values (5,2)
    update tmp set id2=(select @@Identity) where id2 is null
    select * from tmp
    1 1 1
    2 5 2
      

  9.   


    知道使用 @@Identity 会存在什么问题吗?
      

  10.   

    另外,要求是要设计一个表,而不是要你用UPDATE,用UPDATE 直接 SET ID1= ID 就可以了
      

  11.   

    insert tmp (id2,c) values (5,2) 
    update tmp set id2=(select @@Identity) where id2 is null 以一个事务提交,或加个锁什么的,不会有问题
      

  12.   


    是要设计一个表,实现ID1=ID,而不是要你UPDATE
      

  13.   


    怎么会不一样请问?最初,这个表一行一列值为0, 你的业务表,id没有。
    先update + 1,得到1, 业务表的 id也是1只是说断号发生后,确实会不一致
      

  14.   


    假设,字段, ID, ID1... FULLNAME
    一条INSERT .. values('name')就可以搞定..还用存储过程?