Pull to refresh

Comments 15

Чего вы пытаетесь добиться своим предложением?
Добиться, пожалуй, ничего. В основном, хочу узнать, правильно я рассуждаю или нет.
Рассуждаете вы неправильно.

Во-первых, методологически. Нам не важно, как идентифицируются объекты; потому что объекты — это такая же абстракция, как и строчки в БД. Нам важно, как идентифицируются сущности из бизнес-модели. Причем именно сущности, а не значения (поэтому, скажем, пример с целым числом нам не интересен, поскольку число — это классический value type, у него не стоит проблемы идентификации). А у сущностей, в свою очередь, вполне себе есть проблема идентификации — какие-то сущности идентифицируются по формальным признакам (например, счет — по номеру), а какие-то — нет (например — человек). Когда мы преобразуем сущности в реализацию (объектную, документную, реляционную), мы тем или иным способом решаем проблему идентификации — где-то мы берем готовые признаки, где-то вводим искуственные. И внезапно выясняется, что тот простой способ идентификации объектов, который вы предлагаете — равенство и идентичность по ссылке — не работает, потому что для одной сущности внезапно может оказаться два объекта с разными адресами. Отсюда появляются компареры, identity maps и другие занимательные вещи. Поэтому нет, все объекты-то идентифицируются по адресу, но бизнесу плевать на объекты, ему нужны сущности.

А во-вторых, технически. Что вы выигрываете от сквозного ключа? Окей, единый способ адресации. Как нам теперь понять, на каком шарде лежит объект? По диапазону? Дополнительная сущность. Какого типа объект? По диапазону? Еще одна сущность. А если у вас в системе есть короткоживущие объекты — они все равно будут поедать емкость из общего множества идентификаторов? А если у вас есть объекты с естественными идентификаторами — для них все равно заводить искусственный и поддерживать две уникальности? А если у вас есть связи, у которых «естественный» ключ — составной, с ними как поступать?

Итого. Недостатков уйма, но где достоинства? Ощутимые, видимые достоинства, которые перевесят эти недостатки?
Да, бизнесу нужны сущности. И мы можем идентифицировать сущность по атрибутам, только если мы специально вводили для нее ключ в качестве атрибута — тот же номер счета. С этой точки зрения нет разницы, использовать для идентификации этот уникальный атрибут, или внутренний дополнительный.
Кроме адресации, из плюсов мне пришли в голову примерно такие:
— Без проблем можно перенести данные между таблицами при рефакторинге
— Отображает последовательность создания объектов
— Меньше ресурсов требуется на создание ID для новой записи (по сравнению с guid)

Как нам теперь понять, на каком шарде лежит объект? По диапазону? Дополнительная сущность.

Насколько я знаю, некоторые варианты реализации шардинга предполагают использование диапазонов, есть варианты с централизованным генератором ключей. Так что тут различий почти нет.

Какого типа объект? По диапазону? Еще одна сущность.

Ну таблицы-то никуда не деваются. Просто немного меняется способ генерации ключа.

А если у вас в системе есть короткоживущие объекты — они все равно будут поедать емкость из общего множества идентификаторов?

Да. Если на них бывают внешние ключи в других таблицах, хоть и ненадолго, то в этот момент они являются частью системы. А если не бывают, и если мы не хотим тратить на них идентификаторы, можно завести для них отдельную последовательность.
Множество значений идентификаторов это небольшая проблема. Кроме того, если использовать GUID, то про них тоже можно сказать, что значения поедаются.

А если у вас есть объекты с естественными идентификаторами — для них все равно заводить искусственный и поддерживать две уникальности?

Да. Это ничем не отличается от составного ключа. Ну и технические причины есть, по числовому идентификатору искать быстрее, чем по 20-символьной строке с номером счета.

А если у вас есть связи, у которых «естественный» ключ — составной, с ними как поступать?

Здесь я пожалуй у вас спрошу, как у более опытного. Можете привести пару примеров? Мне не встречались случаи, где это действительно было нужно.
Ваши утверждения — сборник заблуждении. Просто хотя бы вспомните про индексы.
Плюсы — надуманы.
Например, для «отображения последовательности создания объектов», если это действительно нужно, заводят отдельное поле с датой-временем создания запись.
Работал с подобными базами — преимуществ не увидел, имел проблемы при тестовых/нештатных «разворачивании бэкапов-переносов данных» — вечно забывали тот или иной счетчик передвинуть вперед на нужное значение.
Чем это помешает работе индексов?
Дата-время не всегда имеет достаточную точность.
Про счетчики — если у нас будет один централизованный счетчик на всю базу, то при вставке записи с большим id он будет и меняться соответственно. Как автоинкремент в таблице mysql.
В любом случае, спасибо за информацию.
И мы можем идентифицировать сущность по атрибутам, только если мы специально вводили для нее ключ в качестве атрибута — тот же номер счета.

Неправда. Мы можем идентифицировать сущность по атрибутам в том случае, если это возможно с точки зрения бизнеса. Номер счета — это не какой-то атрибут, который ввели мы, это атрибут, который есть в бизнесе безо всякого вмешательства с нашей стороны.

С этой точки зрения нет разницы, использовать для идентификации этот уникальный атрибут, или внутренний дополнительный.

Вообще-то, разница большая. Натуральный и искусственный ключи отличаются по поведению и ограничениям.

Кроме адресации, из плюсов мне пришли в голову примерно такие:
— Без проблем можно перенести данные между таблицами при рефакторинге

Во-первых, это означает, что вы ошиблись с дизайном модели, и в этом случае ключи — это наименьшая из ваших проблем. А во-вторых, при локальных ключах проблемы тоже не так уж велики.

— Отображает последовательность создания объектов

Во-первых, только в том случае, если вы никогда не заполняете пустоты. А во-вторых, зачем вам это надо в масштабе всей БД?

— Меньше ресурсов требуется на создание ID для новой записи (по сравнению с guid)

Во-первых, это относится не к глобальный vs локальный, а к автоинкремент vs guid. А во-вторых это банально неправда. Посудите сам: вот у вас есть система со сквозной автоинкрементной идентификацией. Чтобы получить следующий идентификатор, вам надо заблокировать то место, где вы храните последнее значение, увеличить его, использовать, разблокировать. Все в рамках транзакции. Это означает, что все ваши операции вставки выстроены в строго последовательную очередь, требующую обращения к одному бутылочному горлышку. Это меньше ресурсов? Поверьте, нет.

Ну таблицы-то никуда не деваются. Просто немного меняется способ генерации ключа.

А как понять, из какой таблицы читать, получив на входе только ключ? И как понять, какая будет форма результата?

А если не бывают, и если мы не хотим тратить на них идентификаторы, можно завести для них отдельную последовательность.

После этого вы теряете свою единую адресацию со всеми ее преимуществами. Вы не можете так сделать.

Ну и технические причины есть, по числовому идентификатору искать быстрее, чем по 20-символьной строке с номером счета.

Скорость поиска существенно сильнее зависит от количества элементов, нежели от размера ключа (для разумных размеров). И, что характерно, для сквозного ключа эта проблема будет выражена очень сильно: скорость поиска даже в самой маленькой таблице все равно будет равна скорости поиска по всей системе.

А если у вас есть связи, у которых «естественный» ключ — составной, с ними как поступать?

Здесь я пожалуй у вас спрошу, как у более опытного. Можете привести пару примеров?

Типовой пример: книга написана автором, связь многие-ко-многим, но один автор не может написать одну книгу дважды. В таблице связей нет собственного искусственного ключа, только «естественный» составной — BookId, AuthorId.
Да, наверно я был неправ. Спасибо за разъяснение.
Не совсем. Я имел в виду абстракцию над такими вещами, чтобы ее можно было использовать и для больших таблиц, и в распределенной базе.
Хм. Тут как-то все свалено в кучу.
Я знаком со свойством AUTO_INCREMENT только в реляционных базах данных. В этих базах данных отсутствует понятие «объект», поэтому и говорить о каком-то «адресе объекта» бессмысленно. Естественно, сами данные где-то хранятся и у этого места хранения есть «физический адрес». Некоторые СУБД дают API к этому адресу (например, в Oracle есть псевдоколонка rowid). Но считать этот адрес идентификатором объекта — нельзя.
А в объектных базах данных глобально-уникальные идентификаторов используются вовсю и да, он вынесен за пределы модели данных. Так что тут у вас ничего нового. Правда я не встречал реализаций, когда этот идентификатор целочисленный и возрастающий (аналог AUTO_INCREMENT), но это тоже вполне объяснимо с учетом того, что объекты в таких системах появляются у клиентов и обеспечение синхронизации последовательностей требует никому ненужных дополнительных затрат.
Справедливости ради, у автора промелькнула мысль про диапазоны адресов, правда, он их с таблицами связал, а не с клиентами.
Но считать этот адрес идентификатором объекта — нельзя

Да, я знаю. Поэтому у меня и появилась мысль о более абстрактном адресе.
Ну у него тоже свои недостатки есть. Поэтому я подумал о другом подходе. Ну и в целом, попытался взглянуть на идентификаторы с другой точки зрения.
Sign up to leave a comment.

Articles