Оптимизация редко используемых полей varchar - PullRequest
1 голос
/ 08 сентября 2011

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

Предположим, у меня в настоящее время есть следующая таблица:

Stuff
------------
ID  Integer
Attr1   Integer
Attr2   Integer
Attr3   Double
Attr4   TinyInt
Attr5   Varchar(250)

Заглядывая вперед, предположим, что в этой таблице будет 500 миллионов записей. Однако в любой момент времени только около 5000 записей будут иметь что-либо в столбце Attr5; все остальные записи будут иметь пустой или нулевой столбец Attr5. Столбец Attr5 заполняется 100-200 символами, когда вставляется запись, тогда ночной процесс очистит данные в нем.

Меня беспокоит то, что такое большое поле varchar в центре табличного пространства, которое в большинстве случаев содержит в основном небольшие числовые поля, снизит эффективность чтения таблицы. Поэтому я бродил, не лучше ли изменить дизайн БД, чтобы использовать две таблицы, подобные этой:

Stuff
------------
ID  Integer
Attr1   Integer
Attr2   Integer
Attr3   Double
Attr4   TinyInt

Stuff_Text
------------
StuffID Integer
Attr5   Varchar(250)

Затем просто удалите из Stuff_Text во время ночного процесса, сохраняя его на уровне 5000 записей, таким образом, сохраняя размер таблицы Stuff минимальным.

Итак, мой вопрос заключается в следующем: нужно ли разбивать эту таблицу на две части или достаточно ли интеллектуален механизм базы данных для эффективного хранения и доступа к информации? Я мог видеть, как БД сжимает эффективность данных и сохраняет записи без данных в Attr5, как если бы не было столбца varchar. Я также мог видеть, что БД оставляла открытые 250 байтов данных в каждой записи, ожидая данные для Attr5. Я склонен ожидать первого, поскольку я думал, что это было целью varchar, а не char, но мой опыт работы с БД ограничен, поэтому я решил, что лучше перепроверить.

Я использую MySQL 5.1, в настоящее время на Windows 2000AS, в конечном итоге обновление до семейства Windows Server 2008. В настоящее время база данных находится на стандартном магнитном диске со скоростью 7200 об / мин, который в конечном итоге будет перенесен на SSD.

Ответы [ 2 ]

0 голосов
/ 08 сентября 2011
Stuff
------------
ID     Integer
Attr1  Integer
Attr2  Integer
Attr3  Double
Attr4  TinyInt
Attr5  Integer NOT NULL DEFAULT 0 (build an index on this)

Stuff_Text
------------
Attr5_id   Integer (primary key)
Attr5_text Varchar(250)

В действии

desc select * from Stuff WHERE Attr5<>0;

desc select Stuff.*, Stuff_text.Attr5_text 
from Stuff
inner join Stuff_text ON Stuff.Attr5=Stuff_text.Attr5_id;
  1. не хранить NULL
  2. использовать в качестве внешнего ключа целое число
  3. при извлечении записи where Attr5 <>0 <-- scan 5,000 rows
  4. намного меньший размер индекса
  5. сделайте тест самостоятельно
0 голосов
/ 08 сентября 2011

Если вы используете VARCHAR и допускаете значения NULL, у вас не должно возникнуть проблем.Потому что это действительно эффективно хранить этот тип данных.Это очень отличается от CHAR типа данных, но у вас уже есть VARCHAR.

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

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

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