Когда использовать TINYINT по INT?

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

Например, лучше использовать tinyint, когда вы знаете, что единственные данные, которые вы будете хранить, это 1, 0 или нуль (с очень небольшим шансом расширить это до 2 или 3 позже ).

Однако единственная причина, по которой я знаю, для этого - для целей хранения - использование 1 байт в строке вместо 4 байтов.

Каковы последствия использования tinyint (или smallint или даже bigint)) только через int, другие чем экономить место на жестком диске?

83 голоса | спросил Richard 23 PM00000060000002431 2011, 18:25:24

5 ответов


84

Дисковое пространство дешево ... это не точка!

Остановите мышление с точки зрения пространства для хранения, вместо этого подумайте о пуле буферов и пропускной способности хранилища . В крайнем случае кеш процессора и пропускная способность шины памяти . Связанная статья является частью серии, посвященной проблемам с плохим выбором кластерного ключа (INT vs GUID vs Sequential GUID), но в нем подчеркивается разница, которую могут сделать байты.

Главное сообщение - это вопросы дизайна. Разница не будет отображаться в отдельной базе данных на соответствующем spec'-сервере, пока вы не нажмете на территорию VLDB, но если вы можете сохранить несколько байтов, почему бы и нет.

Мне напомнили об окружающей среде, описанной в более раннем вопросе . 400+, размером от 50 МБ до 50 ГБ на каждый экземпляр SQL. Сжатие нескольких байтов на каждую запись за одну таблицу за одну базу данных в этой среде может существенно повлиять.

ответил Mark Storey-Smith 23 PM00000070000000631 2011, 19:16:06
25

В дополнение к другим ответам ...

Строки и записи индекса хранятся на страницах 8k. Таким образом, миллион строк по 3 байта на строку не составляет 3 МБ на диске: он влияет на количество строк на странице («плотность страницы»).

То же самое относится к nvarchar к varchar, smalldatetime к datetime, int к tinyint и т. д.

Изменить, июнь 2013 г.

http://sqlblog.com/blogs/joe_chang/archive /2013/06/16/load-test-manifesto.aspx

В этой статье говорится:

  

Важными критериями являются коэффициент мощности и соотношение между страницами.

Таким образом, выбор типа данных имеет значение

ответил gbn 23 PM000000100000002231 2011, 22:53:22
11

Это не только хранение таблиц. Если вы используете индексы, в которых столбец int является частью составного ключа, вы, естественно, хотите, чтобы страницы индекса были как можно полнее, это было результатом того, что записи индекса были как можно меньше.

Я определенно ожидал бы, что изучение записей индекса на страницах BTREE будет немного быстрее при использовании меньших типов данных. Однако любые VARCHAR, участвующие в записях индекса, будут компенсировать (снижать) прирост производительности от использования TINYINT по INT.

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

ответил RolandoMySQLDBA 23 PM00000070000004631 2011, 19:39:46
11

Все становится сложнее, когда базы данных становятся больше:

  • окна обслуживания должны быть увеличены или перенесены.
  • резервное копирование (полная резервная копия в конце дня становится абсурдным временем, поэтому вам нужны дифференциальные или даже резервные копии журналов и выполните полную раз в неделю, может быть, раз в месяц).
  • Работы по исполнению становятся пожирателями времени (создание индекса в многомиллионной таблице не требует тривиального времени), и его нужно перепланировать и ухудшать, если таблица широко распространена ...
  • И передача этой 100Gb-резервной копии через сеть не является тем, что я называю куском торта - особенно если сеть (по какой-то неизвестной причине) упрямна при отключении соединения на метке 75Gb ... (произошло с установкой I работала, которая выполняла резервное копирование на подключенный диск в сети - сеть) ...

И какие типы данных имеют к этому отношение? ВСЕ. . Используя размеры строк, превышающие необходимые, страницы базы данных заполняются до того, как они нужны или даже теряют пространство, если размер строки таков, что можно записать не более одной записи на странице. Результатом является больше страниц, необходимых для написания и чтения, большая память RAM используется для кэширования (большие записи требуют большей памяти). И так как ваши типы данных указаны больше, чем нужно на диске, ваши индексы будут испытывать такую ​​же проблему - особенно если вы кластерный основной 2-битный первичный ключ BIGINT, так как любые другие созданные индексы будут копировать этот первичный ключ неявно по их определению.

Если вы знаете, что некоторые столбцы в таблице, которые будут иметь миллионы строк или даже небольшую таблицу, которые будут FK'ed для многомиллионной строки, для которой не требуется целое число 4 байта для хранения своих данных, 2 байта - используйте SMALLINT . Если значений в диапазоне 0-255 достаточно, TINYINT . Флаг «Да /Нет»? Там BIT .

ответил Fabricio Araujo 28 J0000006Europe/Moscow 2012, 00:48:03
7

В то время как для tinyint vs int существуют четкие различия, такие как дисковое пространство, разбиение страниц и время обслуживания, не было бы ни одного из них для varchar.

Итак, почему бы не объявить все текстовые поля как varchar (4000), так как в любом случае он будет использовать только необходимое пространство? Еще больше вам гарантируется, что ваши данные никогда не будут урезаны.

Конечно, ответ:

  1. Разъяснение ваших намерений (поскольку никто не поймет, почему поле имени должно быть 4000 символов)
  2. Валидация, так как вы хотите удостовериться, что никто не входит в целую биографию как имя.

Эти же причины относятся и к tinyint.

ответил yoel halb 24 AM00000050000005631 2012, 05:43:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132