Оценка размера базы данных

Я пытаюсь предвидеть, насколько большой будет моя база данных. Допустим, у меня есть только одна таблица:

CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
электронная почта VARCHAR(50),
pass CHAR( 40),
url VARCHAR(1000),
PRIMARY KEY(id));

Складываем все вместе: 4 + 51 + 40 + 1001 = 1096 байт в одной записи.
Если у меня 1 миллион записей: 1 000 000 x 1096 байт = 1 045 МБ!

Итак, это одна крошечная таблица, и я ищу 1 гигабайт для ее хранения. Прав ли я в своей оценке?


person z-boss    schedule 05.11.2008    source источник
comment
э... откуда скачок с MB на GB?   -  person Powerlord    schedule 06.11.2008


Ответы (5)


Помимо проблемы с varchar, вам также необходимо знать, что большинство баз данных хранят записи в выделенных блоках памяти (иногда называемых экстентами, хотя точная терминология зависит от rdbms), которые содержат определенное количество свободного места. Цель этого состоит в том, чтобы разрешить обновления при минимизации фрагментации таблиц и индексов. Конечно, выделенное свободное пространство увеличивает размер файла базы данных, даже если в нем нет фактических данных.

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

Хорошее эмпирическое правило состоит в том, чтобы рассчитать ожидаемый размер таблицы так же, как вы это делаете, хотя и оцениваете размеры varchar, как обсуждалось в других сообщениях (или лучше проводите анализ выборочных данных), а затем добавляете 20% - обычное распределение свободного места по умолчанию. На практике выделение свободного места редко вызывает проблемы, особенно если вы развертываете разумную процедуру обслуживания (поэтому большинство людей никогда не задумываются об этом), но неспособность предвидеть и сделать подходящее распределение для таблицы, затронутой необычно высокой активностью ВМС, может порождают сложные для отслеживания проблемы с производительностью.

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

*ОТРЕДАКТИРОВАНО в ответ на комментарий - "Что такое ВМС и что вы подразумеваете под обслуживанием? Удаление старых записей? - sneg"

ВМС = Вставка, обновление, удаление. Чтобы проиллюстрировать проблему обслуживания, давайте рассмотрим, что произойдет, если мы создадим базу данных без свободного места и загрузим таблицу, подобную той, которую вы предлагаете, с записями, содержащими данные varchar. Все записи будут помещены в файл нашей базы данных встык, без пробелов между ними.

Если пользователь затем обновил часть записи varchar, есть три возможности. Если поле одинаковой длины, то структурных изменений нет. Если оно короче, мы перезаписываем старое поле и в конце поля остается несколько лишних байтов — ничего страшного. Однако, если он длиннее, у нас проблема - запись больше не помещается. В этом случае одним из решений было бы скопировать всю измененную запись в новое место и обновить индексы (а в некоторых схемах управления поместить указатель туда, где была старая запись). Теперь проблема заключается в том, что при последовательном чтении данных — довольно распространенной операции — теперь придется прыгать по файлу базы данных, а не читать его напрямую — классический сценарий фрагментации — и производительность постепенно снижается.

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

Обслуживание в этом случае, по сути, представляет собой процесс дефрагментации для перемещения записей, чтобы они были перемещены и освободили место, чтобы они снова эффективно распределялись. В некоторых (большинстве) RDBM вы можете просто назначить план обслуживания и запланировать задание, чтобы сделать это в q спокойное время (например, SQL Server), но в других вам, возможно, придется делать это вручную — например, в более старых версиях Oracle рекомендуется Подход заключался в том, чтобы экспортировать данные, удалить таблицу и воссоздать ее, а затем повторно импортировать из резервной копии — процесс экспорта/перезагрузки будет очищать данные в соответствии с любой новой загрузкой.

Структуры индексов имеют схожие проблемы.

Я, конечно, многое здесь умалчиваю, но существенные проблемы хранения записей данных произвольного доступа переменной длины в файле останутся, независимо от того, сколько слоев абстракции вы наложите поверх него. Хорошо, что такого рода проблемы хорошо известны, и в большинстве случаев вам не о чем беспокоиться, пока вы не зададите, казалось бы, простой вопрос, например, «сколько места потребуется для этой таблицы» :-)

person Cruachan    schedule 05.11.2008
comment
Что такое ВМС и что вы подразумеваете под поддержанием? Удаление старых записей? - person z-boss; 06.11.2008

Загрузите некоторые тестовые данные с той же средней длиной поля, что и в производственной среде, а затем измерьте, сколько места они занимают. Это то, что мы делаем.

Не утруждайте себя загрузкой 100 строк, просто загрузите 1 млн строк или 10 млн с самого начала. Загрузить больше строк в непроизводственные системы легко — это займет немного больше времени.

Очень удобно иметь большой набор тестовых данных — таким образом вы можете точно измерить влияние на дисковое пространство (и влияние времени простоя) изменений схемы базы данных, например, в частности, добавление индексов.

Убедитесь, что ваши тестовые данные не меньше производственных, а в идеале больше.

person MarkR    schedule 05.11.2008
comment
Хорошая идея, но где взять такой набор тестовых данных? - person z-boss; 06.11.2008

Фактически, использование пространства типа VARCHAR MySQL является переменным, на основании введенных в него данных. Тип CHAR использует постоянное пространство. Кроме того, ваши вычисления выглядят правильно: насколько мне известно, таблицы MySQL не хранятся на сжатом диске, хотя вы можете явно сжать их за счет того, что сделаете их доступными только для чтения.

person hark    schedule 05.11.2008

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

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

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

person Jarod Elliott    schedule 05.11.2008

На самом деле поле varchar представляет более одного поля char. Это справедливо и для других типов данных.

Простым способом было бы добавить 100 записей со случайными тестовыми данными, а затем посмотреть, насколько велик файл базы данных в вашей файловой системе. Затем добавьте еще сотню и посмотрите, насколько она увеличилась.

person branchgabriel    schedule 05.11.2008
comment
Разве VARCHAR потенциально не меньше 1000, если вы его тоже не используете? - person kenny; 06.11.2008
comment
Также помните, что varchar требует несколько байтов для хранения длины поля, в дополнение к данным. - person tmeisenh; 01.01.2009