Значения DateTime не работают (или, по крайней мере, очень маловероятно) работают как уникальные идентификаторы. Для достижения уникальности рассмотрите возможность использования интегрального значения со свойством идентичности.
Ожидание даты / времени вставки / обновления для предоставления уникального значения даты / времени для каждой строки - это путь к печали по нескольким причинам.
Во-первых, точность значения даты и времени SQL Server равна 1 мс. Внутренне значение даты и времени в SQL Server - это кортеж, содержащий два 32-разрядных целых числа. Первое целое число - количество дней с начала эпохи (для SQL Server, то есть 1 января 1900 года). Второе - это смещение в миллисекундах от начала дня (00: 00: 00.000 или 12:00). В мире современных компьютерных процессоров 1 миллисекунда - это долгое время . Вы, вероятно, получите столкновения, просто по этой причине.
Во-вторых, гранулярность значения SQL DateTime составляет приблизительно 3 мс (в действительности значение datetime «округляется» в сегменты 3 мс или 4 мс, что еще больше увеличивает вероятность коллизии.
- Наконец (и я не знаю, что это на самом деле так), я считаю, что если вы вставляете несколько строк в одну транзакцию (например,
insert foo select * from bar
) и используете свойство по умолчанию для установки текущей даты / time, вы можете получить все, что помечено тем же значением даты и времени, поскольку транзакция считается завершенной одновременно.
«Округленное» значение также будет кратно 0, 3 или 7 миллисекундам. Рассмотрим следующий скрипт. Он создает временную таблицу, вставляет некоторую строку даты / времени и преобразует их в значения даты и времени:
drop table #temp
go
create table #temp
(
value varchar(32) not null primary key clustered ,
dtConverted as convert(datetime,value,121)
)
go
set nocount on
insert #temp (value) values( '2011-01-31 23:59:59.000' )
insert #temp (value) values( '2011-01-31 23:59:59.001' )
insert #temp (value) values( '2011-01-31 23:59:59.002' )
insert #temp (value) values( '2011-01-31 23:59:59.003' )
insert #temp (value) values( '2011-01-31 23:59:59.004' )
insert #temp (value) values( '2011-01-31 23:59:59.005' )
insert #temp (value) values( '2011-01-31 23:59:59.006' )
insert #temp (value) values( '2011-01-31 23:59:59.007' )
insert #temp (value) values( '2011-01-31 23:59:59.008' )
insert #temp (value) values( '2011-01-31 23:59:59.009' )
insert #temp (value) values( '2011-01-31 23:59:59.010' )
insert #temp (value) values( '2011-01-31 23:59:59.990' )
insert #temp (value) values( '2011-01-31 23:59:59.991' )
insert #temp (value) values( '2011-01-31 23:59:59.992' )
insert #temp (value) values( '2011-01-31 23:59:59.993' )
insert #temp (value) values( '2011-01-31 23:59:59.994' )
insert #temp (value) values( '2011-01-31 23:59:59.995' )
insert #temp (value) values( '2011-01-31 23:59:59.996' )
insert #temp (value) values( '2011-01-31 23:59:59.997' )
insert #temp (value) values( '2011-01-31 23:59:59.998' )
insert #temp (value) values( '2011-01-31 23:59:59.999' )
set nocount off
go
select * from #temp
go
Когда вы запускаете вышеуказанный скрипт, результаты, вероятно, не соответствуют ожидаемым. Мало того, что значения округляются до интервалов 3 мс или 4 мс, но любое значение даты-времени с миллисекундным значением, превышающим 997, округляется до следующего дня (и месяца, в данном случае). Это граничное условие, которое будет кусать вас в сценариях реального мира (не спрашивайте меня, откуда я это знаю). Вот результаты, которые вы получите:
value dtConverted
----------------------- -----------------------
2011-01-31 23:59:59.000 2011-01-31 23:59:59.000
2011-01-31 23:59:59.001 2011-01-31 23:59:59.000
2011-01-31 23:59:59.002 2011-01-31 23:59:59.003
2011-01-31 23:59:59.003 2011-01-31 23:59:59.003
2011-01-31 23:59:59.004 2011-01-31 23:59:59.003
2011-01-31 23:59:59.005 2011-01-31 23:59:59.007
2011-01-31 23:59:59.006 2011-01-31 23:59:59.007
2011-01-31 23:59:59.007 2011-01-31 23:59:59.007
2011-01-31 23:59:59.008 2011-01-31 23:59:59.007
2011-01-31 23:59:59.009 2011-01-31 23:59:59.010
2011-01-31 23:59:59.010 2011-01-31 23:59:59.010
2011-01-31 23:59:59.990 2011-01-31 23:59:59.990
2011-01-31 23:59:59.991 2011-01-31 23:59:59.990
2011-01-31 23:59:59.992 2011-01-31 23:59:59.993
2011-01-31 23:59:59.993 2011-01-31 23:59:59.993
2011-01-31 23:59:59.994 2011-01-31 23:59:59.993
2011-01-31 23:59:59.995 2011-01-31 23:59:59.997
2011-01-31 23:59:59.996 2011-01-31 23:59:59.997
2011-01-31 23:59:59.997 2011-01-31 23:59:59.997
2011-01-31 23:59:59.998 2011-01-31 23:59:59.997
2011-01-31 23:59:59.999 2011-02-01 00:00:00.000
(21 row(s) affected)
Удачи!