Насколько предсказуемо NEWSEQUENTIALID?
Согласно документации Microsoft на NEWSEQUENTIALID
, вывод NEWSEQUENTIALID предсказуем. Но насколько предсказуемо предсказуемо? Скажем, у меня есть GUID, который был сгенерирован NEWSEQUENTIALID
как тяжело было бы:
- Рассчитать следующее значение?
- Рассчитать предыдущее значение?
- Рассчитать первое значение?
- Рассчитать первое значение, даже не зная никаких GUID?
- Рассчитать количество строк? Например, при использовании целых чисел,
/order?id=842
говорит мне, что в приложении 842 заказа.
Ниже приведена некоторая справочная информация о том, что я делаю и каковы различные компромиссы.
Одно из преимуществ безопасности использования GUID над целыми числами в качестве первичных ключей заключается в том, что GUID трудно угадать. Например, хакер видит URL-адрес как /user?id=845
он может попытаться получить доступ /user?id=0
, поскольку вполне вероятно, что первый пользователь в базе данных является администратором. Более того, хакер может перебрать /user?id=0..1..2
быстро собрать всех пользователей.
Аналогичным образом, недостатком целых является то, что они пропускают информацию. /order?id=482
говорит мне, что у интернет-магазина было 482 заказа с момента его реализации.
К сожалению, использование GUID в качестве первичных ключей имеет известные недостатки производительности. С этой целью SQL Server представил NEWSEQUENTIALID
функция. В этом вопросе я хотел бы узнать, насколько предсказуемы результаты NEWSEQUENTIALID
является.
4 ответа
Основная функция ОС UuidCreateSequential
, Значение получено из MAC-адреса одной из ваших сетевых карт и добавочного значения для каждой загрузки. См. RFC4122. SQL Server выполняет некоторую перестановку байтов для правильной сортировки результатов. Таким образом, ценность в некотором смысле очень предсказуема. В частности, если вы знаете значение, вы можете сразу же предсказать диапазон аналогичного значения.
Однако нельзя предсказать эквивалент id=0
и не может предсказать, что 52DE358F-45F1-E311-93EA-00269E58F20D
означает, что в магазине продано не менее 482 предметов.
Единственное "одобренное" случайное поколение CRYPT_GEN_RANDOM
(который оборачивает CryptGenRandom
) но это, очевидно, ужасный ключевой кандидат.
В большинстве случаев следующий newsequentialid
можно предсказать, взяв текущее значение и добавив единицу к первой шестнадцатеричной паре.
Другими словами:
1E 29E599-45F1-E311-80CA-00155D008B1C
сопровождается
1F 29E599-45F1-E311-80CA-00155D008B1C
сопровождается
20 29E599-45F1-E311-80CA-00155D008B1C
Иногда последовательность перезапускается с нового значения.
Итак, это очень предсказуемо
NewSequentialID
это обертка вокруг функции Windows UuidCreateSequential
• Рассчитать следующее значение? да
Microsoft говорит:
Если вас беспокоит конфиденциальность, не используйте эту функцию. Можно угадать значение следующего сгенерированного GUID и, следовательно, получить доступ к данным, связанным с этим GUID.
Так что это возможность получить следующее значение. Я не нахожу информацию, если можно получить предварительную.
от: http://msdn.microsoft.com/en-us/library/ms189786.aspx
редактировать: еще несколько слов о NEWSEQUENTIALID и безопасности: http://vadivel.blogspot.com/2007/09/newid-vs-newsequentialid.html
Редактировать: NewSequentialID содержит MAC-адрес сервера (или один из них), поэтому знание последовательного идентификатора дает потенциальному злоумышленнику информацию, которая может быть полезна как часть защиты или DoS-атаки. От: Есть ли недостатки использования NewSequentialID?
Вы можете попробовать этот код:
DECLARE @tbl TABLE (
PK uniqueidentifier DEFAULT NEWSEQUENTIALID(),
Num int
)
INSERT INTO @tbl(Num) values(1),(2),(3),(4),(5)
select * from @tbl
На моей машине за это время есть результат:
PK Num
52DE358F-45F1-E311-93EA-00269E58F20D 1
53DE358F-45F1-E311-93EA-00269E58F20D 2
54DE358F-45F1-E311-93EA-00269E58F20D 3
55DE358F-45F1-E311-93EA-00269E58F20D 4
56DE358F-45F1-E311-93EA-00269E58F20D 5
Вы должны попробовать это несколько раз в разное время / дату, чтобы интерполировать поведение. Я пробовал запустить его несколько раз, и первая часть меняется каждый раз (вы видите результаты: 52...,53...,54... и т. Д.). Я ждал некоторое время, чтобы проверить это, и через некоторое время вторая часть также увеличивается. Я полагаю, инцементация продолжается во всех частях. В основном это выглядит просто +=1
Incementation превращается в Guid.
РЕДАКТИРОВАТЬ:
Если вам нужен последовательный идентификатор GUID и вы хотите контролировать значения, вы можете использовать Последовательности.
Образец кода:
select cast(cast(next value for [dbo].[MySequence] as varbinary(max)) as uniqueidentifier)