2013-02-12 3 views
0

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

CREATE TABLE `data` (
    `id` INT UNSIGNED NULL PRIMARY KEY AUTO_INCREMENT, 
    `datetime` DATETIME NOT NULL, 
    `res1` INT UNSIGNED NOT NULL, 
    `res2` INT UNSIGNED NOT NULL, 
    `res3` INT UNSIGNED NOT NULL, 
    `res4` INT UNSIGNED NOT NULL, 
    `res5` INT UNSIGNED NOT NULL, 
    `value` DECIMAL(10,0) NOT NULL, 
    UNIQUE INDEX `datetime_res1_to_res5` (`datetime`, `res1`, `res2`, `res3`, `res4`, `res5`) 
) 

где res1 до res5 внешние ключи к соответствующим таблицам.

Эта таблица будет содержать много строк - легко сломается 20 миллионов.

Что я любопытно, если я должен поставить комбинацию внешних ключей в отдельную таблицу, так что у меня есть две таблицы, как так:

CREATE TABLE `data` (
    `id` INT UNSIGNED NULL PRIMARY KEY AUTO_INCREMENT, 
    `datetime` DATETIME NOT NULL, 
    `superKeys_id` INT UNSIGNED NOT NULL, 
    `value` DECIMAL(10,0) NOT NULL, 
    UNIQUE INDEX `datetime_superKeys_id` (`datetime`, `superKeys_id`) 
) 

CREATE TABLE `superKeys` (
    `id` INT UNSIGNED NULL PRIMARY KEY AUTO_INCREMENT, 
    `res1` INT UNSIGNED NOT NULL, 
    `res2` INT UNSIGNED NOT NULL, 
    `res3` INT UNSIGNED NOT NULL, 
    `res4` INT UNSIGNED NOT NULL, 
    `res5` INT UNSIGNED NOT NULL, 
    UNIQUE INDEX `res1_to_res5` (`res1`, `res2`, `res3`, `res4`, `res5`) 
) 

где data. superKeys_id - это внешний ключ до superKeys. id.

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

В моей реальной ситуации в мире, один из ресурсов будет user_id и мне часто нужно будет суммировать значения для пользователя, так что я, вероятно, держать такую ​​колонку в data, а не сделать его частью superKeys таблицы ради того, чтобы не присоединяться к каждому запросу. Тогда используйте только соединение, когда мне нужно суммировать значения для других ресурсов, которые будут реже.

+0

Возможно, опустить суррогатный ключ 'id' alltogether? Если res1 ... res5 являются естественным уникальным ключом, другой ключ будет лишним. – wildplasser

+0

Вам нужно сравнить более или менее 5 ресурсов? Это кажется очень денормализованной схемой. –

+0

Да, вертикальное разбиение может быть выполнено для минимизации ввода-вывода для «горячей» половины таблицы. _However_, это имеет смысл только для больших таблиц, а 20 миллионов на самом деле не квалифицируются как «большие» на современном оборудовании, так как @Catcall [настолько красноречиво объяснил] (http://stackoverflow.com/a/14823645/533120) (+ 1 ему). –

ответ

1

Это не уменьшит размер данных . Вам нужно будет хранить 20 миллионов строк данных в одной таблице и 20 миллионов строк суперклеев в другой.

Пять целых чисел - 40 байт. Умножьте на 20 миллионов - 800 мегабайт, плюс столбец datetime и десятичный. Весь этот стол поместился бы в ОЗУ на моем нетбуке.

Сохраните таблицу «данные». Бросьте суррогатный ключ.

+0

В моем примере произошла ошибка, когда я положил столбец значений в superKeys. С учетом сказанного, может быть 10 000 уникальных комбинаций res1 to res5 на 1-й день и 10 000 в день 2, но в течение 2 дней вместе может быть только 12 000 уникальных комбинаций - определенно не 20 000. Таким образом, в 'data' будет 20 000 строк, но только 12 000 в' superKeys'. – user2045006

Смежные вопросы