Что является более эффективным smallint или символом (10)? - PullRequest
0 голосов
/ 26 сентября 2019

Я храню 5000 книг в таблице, таблица содержит названия, авторов, годы и ISBN.Сейчас я делаю таблицу для обзоров книг.Что было бы более эффективным или просто лучшим способом сделать это, создать столбец для идентификаторов в таблице книг и использовать этот идентификатор для хранения рецензий на книги в таблице рецензий или использовать номер ISBN книг, который хранится каксимвол (10)?

Когда я говорю «эффективный», я имею в виду «сохранение места для хранения».

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

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

A smallint занимает 2 байта, тогда как character(10) (что нелогично varlena), содержащее символы ASCII, будет занимать 14 байтов.

В таблице лишние 2 байта будут бесполезными, но не забывайте, что у вас будетиндекс столбца первичного ключа.Таким образом, индексированное значение будет фактически сохранено дважды: один раз в таблице, один раз в индексе.

Для простоты давайте проигнорируем заголовки кортежей и другие издержки.

  • Использование ISBN в качестве первичного ключа обойдется в дополнительные 14 байтов на строку таблицы.

  • Добавление первичного ключа smallint добавит два байта к таблице и два к индексу, что сделаетвсего четыре добавленных байта.

Итак, добавление smallint первичного ключа должно сэкономить пространство .

Не следует игнорировать проблемы с выравниванием.Все типы данных хранятся по адресам памяти, кратным определенной степени двух.Это требуется архитектурами процессоров.A smallint обычно имеет выравнивание 2, character имеет выравнивание 1, в то время как, например, timestamp имеет выравнивание 8.

Так что если ваша таблица определена как

CREATE TABLE book (
   id smallint PRIMARY KEY,
   issue_time timestamp with time zone,
   isbn character(10)
);

, тогдаданные таблицы будут выглядеть так:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | |X|X|X|X|X|X| | | | | | | | | ... (ISBN omitted)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 id    padding     issue_time

Строка будет выровнена по 8-байтовой границе, и шесть байтов от конца, если id до начала issue_time, будут пустыми «padding»байты ».

Таким образом, чтобы максимально использовать это, вы должны рассмотреть, в каком порядке вы определяете столбцы.

Почему все это не очень важно в реальности:

Таблица с 5000 или 10000 записей крошечная, несмотря ни на что.

Любая затраченная на оптимизацию пространства здесь в лучшем случае ненужная микрооптимизация.

Но то, что может быть разумной идеей для таблицы планирования, может легко привести к обратным последствиям позже: если - в отличие от того, что вы ожидаете - вы хотите хранить 70000 книг в таблице, вы обнаружите, что smallint будет недостаточно, даже есливы допускаете отрицательные id с.Боль, которую вам придется пережить, когда вам придется изменить тип данных первичного ключа и всех внешних ключей, которые ссылаются на него в действующей системе, значительно перевесят любое удовольствие, которое вы получите от экономии около 100 КБ с помощью умных оптимизаций.

1 голос
/ 26 сентября 2019

Обычно - это зависит.Работа над типом int довольно быстрая.Должно быть быстрее, чем на любом типе символов.Тип "char" в Postgres - это "varchar", а char (10) требуется 11 байтов, что больше 4 для целого числа.С другой стороны, isbn является обязательным полем, а идентификаторы могут быть необязательными, поэтому таблица без идентификаторов может быть меньше.

Таким образом, int является более эффективным типом для первичного ключа, чем varchar.Но на машинах этого дня вам нужно выполнить множество сложных операций, возможно, с более чем 1 млн строк, чтобы найти какие-либо видимые различия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...