[БД] Identity-поле: автоинкремент vs. GUID

bobby

Почитал один из соседних тредов и задумался.
Хотелось бы услышать доводы (желательно поконкретнее и с примерами) в пользу использования автоинкрементальных identity или GUID в к-ве identity в таблицах БД. Рассмотрю любые соображения, даже самые нелепые/очевидные, возможно, какие-то ситуации из личного опыта пишущих в разделе и т.п.
Спасибо.

6yrop

в Book-on-line хорошо написано

The uniqueidentifier data type has several disadvantages:
The values are long and obscure. This makes them difficult for users to type correctly, and more difficult for users to remember.
The values are random and cannot accept any patterns that may make them more meaningful to users.
There is no way to determine the sequence in which uniqueidentifier values were generated. They are not suited for existing applications that depend on incrementing key values serially.
At 16 bytes, the uniqueidentifier data type is relatively large compared to other data types such as 4-byte integers. This means indexes built using uniqueidentifier keys may be relatively slower than implementing the indexes using an int key.
я почти тоже самое хотел из личного опыта написать

Dasar

Основное преимущество Guid - это его децентрализация, что позволяет использовать гибкие схемы редактирования, обработки данных и т.д.

6yrop

это да

rosali

По моему элементарно сделать децентрализацию на 4-байтном идентификаторе?

6yrop

как?

Dasar

это вопрос или что?

rosali

Ну не знаю, пишут же malloc без mutex-ов Условно говоря, первый байт номер сервера, на трех остальных автоинкремент. Не подходит?

Dasar

на стороне клиента, например, данные создавать уже все равно не получиться.
централизацию ты не убрал, ты просто ее сместил на уровень процесса:
a) отдельные процессы все также должны где-то регистрироваться,
b) код внутри процесса должен работать через единый класс раздачи id-ей.

bobby

децентрализация, что позволяет использовать гибкие схемы редактирования, обработки данных и т.д.
Вот тут можно несколько конкретных примеров?
Пока я осознал один плюс использования GUID'ов - то, что Identity становится известным ещё до внесения в базу.
Хотелось бы увидеть более-менее явное и четкое преимущество GUID в каких-то конкретных задачах. Вроде "вот тут с GUID очень удобно, а с инкрементом не очень или вообще нельзя или очень хитро нужно извернуться, чтобы можно было".
Обратным примерам тоже буду рад.

Dasar

> Пока я осознал один плюс использования GUID'ов - то, что Identity становится известным ещё до внесения в базу.
так именно это часто и используется.
1. так , например, прямо на клиенте - можно заводить/редактировать большой кусок связанных данных
2. можно делать кэши на запись
3. можно разносить прозрачно один справочник - по нескольким базам, можно потом его сливать обратно и т.д.
4. также очень удобна глобальная уникальность:
например, есть у нас толпа таблиц: машины, люди, дома и т.д., и т..п.
далее - нам надо добавить какой-то общий сервис, например, права на редактирование
и в случае guid-ов - мы при введение этого сервиса - можем использовать те же самые id-ы, которые были выданы элементам раньше, в случае - автоинкремента (придется заводить какой-то фиктивный ключ: имя таблицы + id)

bobby

Любопытно, спасибо.

KViH

1. так , например, прямо на клиенте - можно заводить/редактировать большой кусок связанных данных
2. можно делать кэши на запись
На клиенте лучше совсем ничего не делать.
3. можно разносить прозрачно один справочник - по нескольким базам, можно потом его сливать обратно и т.д.
Интересно, часто возникает необходимость делать такие странные вещи?
4. также очень удобна глобальная уникальность:
например, есть у нас толпа таблиц: машины, люди, дома и т.д., и т..п.
далее - нам надо добавить какой-то общий сервис, например, права на редактирование
и в случае guid-ов - мы при введение этого сервиса - можем использовать те же самые id-ы, которые были выданы элементам раньше, в случае - автоинкремента (придется заводить какой-то фиктивный ключ: имя таблицы + id)
Пример реален, да.
Но в общем все это как-то неубедительно звучит.

FRider

На клиенте лучше совсем ничего не делать.
поясни теперь это утверждения, помня, что в даннм случе под "клиентом" может подразумеваться business-logic tier в multitier приложениях, т.е. главное то, что ид генерит не хранилище, а бизнес логика. Хранилище то как раз должно быть тупым - его задача хранить и предоставлять данные.
Интересно, часто возникает необходимость делать такие странные вещи?
Например, мы разносим бд по нескольким физическим серверам для повышения производительности. Вполне реальная задача. О "частоте" говорить без конеткста имхо бессмысленно.

Dasar

>> 3. можно разносить прозрачно один справочник - по нескольким базам, можно потом его сливать обратно и т.д.
> Интересно, часто возникает необходимость делать такие странные вещи?
Довольно часто, если задача, например, распределенная.
Магазин - в урюпинске, склад - в москве, головной офис - в лондоне.

KViH

Ошибку понял, для распределенных приложений guid возможно предпочтительней, да.

gopnik1994

4. также очень удобна глобальная уникальность:
например, есть у нас толпа таблиц: машины, люди, дома и т.д., и т..п.
далее - нам надо добавить какой-то общий сервис, например, права на редактирование
и в случае guid-ов - мы при введение этого сервиса - можем использовать те же самые id-ы, которые были выданы элементам раньше, в случае - автоинкремента (придется заводить какой-то фиктивный ключ: имя таблицы + id)
сомнительный пример
во первых: никто и ничто вам не мешает использовать один глобальный автоинкрементый ключ на всю базу, а не для каждой таблицы отдельно.
во вторых: как, простите, в твоем примере ты при редактировании прав будешь определять, что это такое редактируется: машина или человек? а поределять это надо хотя бы для того чтобы вывести название объекта - т.о. таблицу все равно придется знать.
в третьих: получить значение очередного значения для автоинкремента ничуть не сложнее, чем гуид.
в четвертых: на клиенте никаких идентификаторов генерить нельзя потому как это уязвимость, кривость и нарушение концепции многозвенности.

Dasar

> во вторых: как, простите, в твоем примере ты при редактировании прав будешь определять, что это такое редактируется: машина или человек?
напомню, что у меня шла речь - про идентификацию (primary key у тебя идет речь - как по ключу получить необходимые данные.
это разные вещи.
> получить значение очередного значения для автоинкремента ничуть не сложнее, чем гуид.
много сложнее, потому что необходим прямой мгновенный доступ к единому центру.
> на клиенте никаких идентификаторов генерить нельзя потому как это уязвимость, кривость и нарушение концепции многозвенности
допустим - id-ы выдаются даже прямо на клиенте
в чем же здесь нарушение концепции многозвенности?
с уязвимостью - вообще - не понятно, в чем она состоит.
т.к. база, вроде. как раз и должна отслеживать такие нарушения целостности.

6yrop


1. так , например, прямо на клиенте - можно заводить/редактировать большой кусок связанных данных
например, DataSet-ы это хендлят, используют локальный автоинкремент, а при сохранении в базу значения локального автоинкремента во всех связанных сущностях заменяется на автоинкремент из базы. Но есть неудобство, нельзя использовать CommandBuuilder.
Вообщем, если ломает возиться с автоинкрементом и если длинна гуида не мешает, то можно использовать гуид. Длинна гуида мешает, когда критична время выполнения запросов с использованием этого индекса. Объем базы тоже может увеличиваться на процентов 20-30. Трафик по сети тоже больше.

Helga87

 
с уязвимостью - вообще - не понятно, в чем она состоит.
т.к. база, вроде. как раз и должна отслеживать такие нарушения целостности
Пусть у нас есть распределенная система управления телеканалами. В одной системе завязаны все каналы, все управление ими и пр. - т.е. "серьезная" система.
Злоумышленники установили на все компьютеры в региональных телестудиях "плохих" клиентов. А еще они узнали MAC-адрес компа, который отдает команды на начало показа телепередач на ОРТ (несложная задача для любого человека из их локальной сети).
Плохие клиенты в количестве больше 1000 штук начинают генерировать guid-ы из интервала 23:55:00-23:59:59 на 31 декабря 2006 года (т.е. сильно заранее). Работают они слаженно и коллизий внутри плохих клиентов при генерации id-шников не возникает, поэтому никто и не думает, что у нас что-то не так. Не думает вплоть до 31 декабря 2006 года, когда на ОРТ не смогло начаться новогоднее обращения президента России из-за того, что на главной машине с правильным (!) клиентом пытаются сгенерить id-шник начинающегося показа - коллизия, еще раз - опять.
 
И все. Новый год не начнется, лето никогда не наступит. Полный привет.

6yrop

в количестве больше 1000
а что это за количество?

Helga87

1000 - это нижняя оценка количества компов в региональных телеканалах.

bleyman

Вопрос немножко не в том, ты не уловил темы =)
В гуиде аж целых 16 байт. Из них 6 - в мак-адресе. Остаётся 10. Допустим, они считают время в 100-наносекундных тиках, как все нормальные люди, и засовывают их в 8 байт. А ещё два заполняют рандомами. Отлично! А теперь посчитаем, сколько гуидов нужно сгенерить, чтобы полностью забить 10 секунд: 10 * 1000 * 1000 * 10 * 2^16 = 10^8 * 2^16 > 2^27 * 2^16 = 2^43.
База не лопнет?
Кстати, а я правильно понимаю, что int в мсскуль-базе 32битный, так что такое количество записей туда поместиться не может в принципе?

Dasar

> И все. Новый год не начнется, лето никогда не наступит. Полный привет.
но, это отказ в доступе, а не уязвимость уровня некорректного доступа к данным, или некорректного изменения данных.
> генерировать guid-ы из интервала 23:55:00-23:59:59 на 31 декабря 2006 года
всего guid-ов в этом интервале, если не ошибаюсь - 10^7 * 60 * 5 = 3 * 10^9
имхо, база от такого кол-ва там, где ожидались всего десятки таких записей - ляжет раньше, чем дойдет очередь до Нового Года.
в целом - проблема, конечно, есть, но реальное использование очень сложное и полученный результат небольшой - поэтому на системах низкой и средней важности - guid-ы можно генерить даже на клиенте.
для важных систем - Guid можно также генерить на клиенте, лишь надо проверять, что клиент такой guid имел право создать.

bleyman

Дальнейшие занимательные вычисления:
Каждый из 1000 компов круглосуточно генерит по 100 инсертов в секунду (у нас толстая база, она не лопнет). Вася Пупкин на новый год решил сорвать следующий новый год и запустил генерацию. Он успеет сгенерить log(2, 3153600000000) = 2^41.5 гуидов, а нужно чуть больше 2^43! Вывод, генерить придётся как минимум пять лет.

Helga87

Можно просто поточнее узнать время начала. А вообще, никто и не скрывает, что пример - чистейшая паранойа. Я обычно именно guid-ами пользуюсь.
Оставить комментарий
Имя или ник:
Комментарий: