4

大きなExcelから新しいテーブルにデータをインポートするときに、1つのレコードが失敗した場合、何もインポートされません。Atomicityのルールを満たしているので大丈夫だと思います。ただし、ソースデータエラーを修正して再度インポートすると、ID列が1から始まるのではなく、大きな値から始まります。

例えば

create table #test (id int identity(1,1), name varchar(4) default '')

insert into #test (name) values('1 insert will failed');
select ident_current('#test') as ident_current
insert into #test (name) values('2 insert will failed');
select ident_current('#test') as ident_current

insert into #test (name) values('3 OK');
select ident_current('#test') as ident_current

select * from #test

drop table #test

結果

id          name 
----------- ---- 
3           3 OK

ウィキペディアはACIDを次のように説明しています

アトミシティ

Atomicityでは、各トランザクションが「オールオアナッシング」である必要があります。トランザクションの一部が失敗すると、トランザクション全体が失敗し、データベースの状態は変更されません。アトミックシステムは、停電、エラー、クラッシュなど、あらゆる状況で原子性を保証する必要があります。

つまり、SQL Serverは、挿入が失敗した場合にデータベースの状態(ID値)を変更しないように見えます。それで、これはACIDルールに違反しますか?

ところで、PostgreSQLは、挿入が失敗したときにidentity(serial)値を大きくしません。(更新:たまにのみ、コメントを参照してください。これに依存しないでください。)

test=# create table AutoIncrementTest (id serial not null, name varchar(4));
NOTICE:  CREATE TABLE will create implicit sequence "autoincrementtest_id_seq" for serial column "autoincrementtest.id"
CREATE TABLE
test=# insert into autoincrementtest(name) values('12345');
ERROR:  value too long for type character varying(4)
test=# insert into autoincrementtest(name) values('12345');
ERROR:  value too long for type character varying(4)
test=# insert into autoincrementtest(name) values('1234');
INSERT 0 1
test=# select * from autoincrementtest;
 id | name
----+------
  1 | 1234
4

3 に答える 3

5

ID値は、アクセスできるデータベースのどの部分にも物理的に格納されているものではないため、これが原子性を損なうことに同意しません。「アトミック性を壊す」ことを望まない場合、またはギャップを気にする場合(すべきではない)、これを行う他の方法があります(たとえば、シリアル化可能なトランザクションを使用し、新しい行にMAX(col)+1を使用します) )。

于 2012-07-19T15:39:31.610 に答える
3

はい、そうです。したがって、MSSQLServerで連続する値に依存しないでください。

どのエンジンでも、連続したID値自体に依存することは、脆弱で素朴なアプローチであることをお勧めします。これは、その後の削除の結果として常に発生する可能性があります。

純粋なACIDコンプライアンスからのこの逸脱により、MSSQLServerのパフォーマンスを最適化できると思います。

于 2012-07-19T15:32:37.507 に答える
1

Atomicityは、この定式化に従って、データベースの状態が変更されないままであることを保証します。問題は、データベースの状態が何を意味するかです。

ID列がシーケンシャルであることを主張も保証もしない「ID挿入」のSQLの概念を理解している限り、問題はありません。ID挿入を検討する場合、SQLが何を保証するかを再考する必要がありますが、前述の場合は失敗する可能性があることがわかっているため、NEXT値であることが実際に保証されるわけではありません。

挿入前は、ID列の「次の」値は現在の値よりも大きいことが保証されているだけであり、次の値であるとは限りません。これはその後もまだ状態です。

于 2012-07-19T15:58:17.783 に答える