2012-02-23 3 views
0

У меня есть таблица с примерно 20 столбцами. 10 из них обычно имеют 1 из 15 возможных значений (по разному для каждого столбца). Кроме того, один столбец имеет довольно большую строку. В настоящее время таблица имеет более 3 миллионов строк и растет. Это около 1 ГБ (только данные)MySQL table split

  1. Я хотел бы отделить большой столбец текста, так как он не используется часто и, возможно, значительно уменьшит размер таблицы, что улучшит производительность.
  2. Я хотел бы «нормализовать» все эти повторяющиеся столбцы в отдельную таблицу (каждый), чтобы я мог получить список текущих значений без выполнения запросов 10 distinct на строках 3М. Это займет много времени.

# 2 будет отношения «один ко многим». # 1 может быть 1-к-1 или 1-ко-многим. Мне все равно.

Вопрос в следующем: могут ли это выполняться с помощью простых операторов SQL? Как? Или мне нужно написать программу, чтобы поместить данные в новую таблицу и получить PK и вставить ее в правый столбец, по одной строке за раз?

Редактировать
Вот пример того, что я пытаюсь сделать:

ID Field1 Lookup Text 
10 val1 look1 some very long text 
11 val2 look2 more very long text 
12 val2 look1 NULL 
13 val4 look1 some very long text 
. 
. 
. 

Для этого:

ID Field1 Lookup Text 
10 val1 1  1 
11 val2 2  2 
12 val2 1  0 
13 val4 1  4 (1?) 
. 
. 
. 

ответ

1

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

  1. Создать таблицу mytable_text с ПК одного и того же типа (не в автоматическом приращении конечно), столбце TEXT, и, если вы используете InnoDB (что рекомендуется в данном случае), внешний ключ ваш первый (основной) стол. Вы можете добавить ON DELETE CASCADE к внешнему ключу, чтобы облегчить обслуживание.
  2. INSERT INTO mytable_text (id, large_text_column) (SELECT id, large_text_column FROM mytable)
  3. ALTER TABLE mytable DROP large_text_column

Для точки 2, это немного больше, но это также выполнимо в SQL (я беру пример вашей области «Уточняющий»). Это может быть что-то вроде этого:

  1. Создайте вторичные таблицы «поисков» со автоинкремент ID и поле «название», например (с UNIQUE INDEX, если вы чувствуете, как он).
  2. INSERT INTO lookups (title) (SELECT DISTINCT Lookup FROM mytable)
  3. SET foreign_key_checks = 0
  4. ALTER TABLE mytable ADD lookup_id INTEGER UNSIGNED [...], ADD FOREIGN KEY [...]
  5. UPDATE mytable SET lookup_id = (SELECT id FROM lookups WHERE lookup.title = mytable.Lookup
  6. ALTER TABLE mytable DROP Lookup
  7. (необязательно) ALTER TABLE mytable CHANGE lookup_id Lookup [...] (если вы хотите сохранить то же имя)
  8. SET foreign_key_checks = 1
+0

Я добавил пример – baruch

+0

Я отредактировал свой ответ на основе вашего примера. Обратите внимание, что с 3M строками инструкции alter могут занимать некоторое время. – rlanvin