Хранить в таблице указатели на строки из другой таблицы вместо использования внешних ключей

#database-design #pointers #reference #rdbms #object-oriented-database

#проектирование базы данных #указатели #ссылка #rdbms #объектно-ориентированная база данных

Вопрос:

мне просто любопытно, возможно ли просто использовать указатели на c / java / etc. вместо объединения таблиц на основе внешнего ключа. И раз уж мы затронули эту тему, использует ли postgres или любая другая СУБД указатели при объединении, чтобы быстро найти строку, на которую ссылается внешний ключ, вместо поиска по всей таблице, содержащей FKS?

Комментарии:

1. Я часто задавался этим вопросом. СУБД может тайно хранить физический указатель на строку (например, PostgreSQL ctid) рядом со значением в столбце внешнего ключа, а затем может использовать его для поиска строк, на которые ссылаются, без необходимости проходить через индекс. Однако его необходимо было бы обновлять всякий раз, когда таблица, на которую ссылается, уплотнялась. Кроме того, строки были бы больше, поэтому пропускная способность ввода-вывода и кэш были бы более напряженными. Будет ли это чистым преимуществом в производительности? Оправдает ли это возросшую сложность?

Ответ №1:

Существенной особенностью реляционной модели данных является то, что она не использует указатели, структурные ссылки или доступ к данным на основе адресов во внешнем, логическом представлении базы данных. Отмена использования указателей была фактически одной из главных мотиваций Кодда для изобретения реляционной модели в 1969 году.

Указатели, конечно, используются внутри большинства СУБД на основе реляционных / SQL.

Комментарии:

1. Но используются ли они именно таким образом? Хранит ли какая-либо база данных указатель на строку, на которую ссылается, на диске?

Ответ №2:

В Oracle есть нечто, называемое ROWID, которое хранит физический адрес строки в таблице. Они выглядят примерно так AAAA8mAALAAAAQkAAA , которые можно разбить на:

  • Номер объекта данных (сегмент) [AAAA8m]
  • Файл данных в табличном пространстве [AAL]
  • Блок данных (внутри файла данных) [AAAAQk]
  • Строка (внутри блока) [AAA]

Использование rowid — это самый быстрый способ физического определения местоположения любой строки в одном прочитанном блоке. Они используются внутри, но могут быть использованы непосредственно разработчиком. Поиск строки по первичному ключу приводит к одному (или нескольким) чтению индекса для поиска идентификатора строки, а затем база данных обнаружит блок и извлечет строку. Если известен идентификатор строки, поиск по индексу не требуется.

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

Каждый раз, когда вы используете rowid, Единорог умрет, а корма упадет с небес. Например, если вы сжимаете таблицу или обновляете разделенную таблицу (в результате чего строка перемещается в другой раздел), или если вы перестраиваете таблицу, или экспортируете / импортируете таблицу, или … или… или… идентификатор строки изменится.

В заключение: доступ на основе rowid не обеспечивает достаточных преимуществ по сравнению с обычным индексированным доступом, чтобы оправдывать риск неизбежного сбоя. Знайте, что они существуют и что это такое, но никогда не полагайтесь на них.