таблица mysqldump без сброса первичного ключа - PullRequest
33 голосов
/ 19 июня 2009

У меня одна таблица распределена по двум серверам под управлением MySql 4. Мне нужно объединить их в один сервер для нашей тестовой среды.

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

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

Проблема заключается в том, что первичный ключ - это уникальное поле с автоматическим приращением, поэтому имеются пересечения.

Я пытался выяснить, как использовать команду mysqldump для игнорирования определенных полей, но --disable-keys просто изменяет таблицу, а не полностью избавляется от ключей.

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

Помощь!

Ответы [ 10 ]

24 голосов
/ 19 июня 2009

если вам все равно, каким будет значение столбца auto_increment, просто загрузите первый файл, переименуйте таблицу, затем заново создайте таблицу и загрузите второй файл. наконец, используйте

INSERT newly_created_table_name (all, columns, except, the, auto_increment, column)
       SELECT all, columns, except, the, auto_increment, column
         FROM renamed_table_name
13 голосов
/ 24 февраля 2015

Чтобы решить эту проблему, я посмотрел этот вопрос, нашел ответ @ pumpkinthehead и понял, что все, что нам нужно сделать, это найти + заменить первичный ключ в каждой строке на NULL, чтобы mysql использовал вместо этого значение по умолчанию auto_increment .

(your complete mysqldump command) | sed -e "s/([0-9]*,/(NULL,/gi" > my_dump_with_no_primary_keys.sql

Исходный вывод:

INSERT INTO `core_config_data` VALUES
    (2735,'default',0,'productupdates/configuration/sender_email_identity','general'),
    (2736,'default',0,'productupdates/configuration/unsubscribe','1'),

Преобразованный вывод:

INSERT INTO `core_config_data` VALUES
    (NULL,'default',0,'productupdates/configuration/sender_email_identity','general'),
    (NULL,'default',0,'productupdates/configuration/unsubscribe','1'),

Примечание: это все еще хак; Например, произойдет сбой, если ваш столбец автоинкремента не является первым столбцом, но решит мою проблему в 99% случаев.

11 голосов
/ 19 июня 2009

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

Так что, если в вашей таблице «пользователи» есть столбцы: идентификатор, имя, адрес электронной почты

> CREATE VIEW myView AS
  SELECT name, email FROM users

Редактировать: ах, я вижу, я не уверен, есть ли другой способ.

6 голосов
/ 21 ноября 2011
  1. Клонируйте ваш стол
  2. Удалить столбец в таблице клонов
  3. Создать дамп таблицы клонов без структуры (но с опцией -c для получения полных вставок)
  4. Импортируйте куда хотите
5 голосов
/ 13 апреля 2012

Это полная боль. Я могу обойти эту проблему, запустив что-то вроде

sed -e "s/([0-9]*,/(/gi" export.sql > expor2.sql 

на дамп, чтобы избавиться от первичных ключей, а затем

sed -e "s/VALUES/(col1,col2,...etc.) VALUES/gi" LinxImport2.sql > LinxImport3.sql

для всех столбцов, кроме первичного ключа. Конечно, вы должны быть осторожны, чтобы ([0-9]*, не заменило то, что вы действительно хотите.

Надеюсь, это кому-нибудь поможет.

3 голосов
/ 19 июня 2009
SELECT null as fake_pk, `col_2`, `col_3`, `col_4` INTO OUTFILE 'your_file'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM your_table;

LOAD DATA INFILE 'your_file' INTO TABLE your_table
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';

Для дополнительной фантазии вы можете установить триггер перед вставкой в принимающей таблице, который устанавливает новый первичный ключ для строки досягаемости до вставки, тем самым используя регулярные дампы и все еще очищая ваш pk. Не проверено, но чувствую себя довольно уверенно.

2 голосов
/ 22 января 2010

Использовать фиктивный временный первичный ключ:

Используйте mysqldump обычно --opts -c. Например, ваш первичный ключ - «id». Отредактируйте выходные файлы и добавьте строку «dummy_id» в структуру вашей таблицы того же типа, что и «id» (но, конечно, не первичный ключ). Затем измените оператор INSERT и замените «id» на «dummy_id». После импорта удалите столбец dummy_id.

0 голосов
/ 10 июня 2019

Мне нравится временная таблица маршрутов.

create temporary table my_table_copy
select * from my_table;

alter table my_table_copy drop id;

// Use your favorite dumping method for the temporary table

Как и другие, это не универсальное решение (особенно учитывая миллионы строк OP), но даже при 10 ^ 6 строках для его запуска требуется несколько секунд, но он работает.

0 голосов
/ 08 июня 2012

Решение, которое я использовал, заключается в том, чтобы просто выполнять SQL-экспорт экспортируемых данных, а затем удалять первичный ключ из операторов вставки с помощью редактора поиска и замены RegEx. Лично я использую Sublime Text, но я уверен, что TextMate, Notepad ++ и т. Д. Могут делать то же самое.

Затем я просто запускаю запрос, в который всегда должна быть вставлена ​​база данных, скопировав запрос в окно запроса HeidiSQL или PHPMyAdmin. Если имеется LOT данных, я сохраняю запрос вставки в файл SQL и вместо этого использую импорт файла. Копирование и вставка большого количества текста часто приводит к зависанию Chrome.

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

0 голосов
/ 22 января 2010

Джимми был на правильном пути.

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

CREATE VIEW myView AS
SELECT id*10+$x, name, email FROM users

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

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

CREATE VIEW users AS
(SELECT * FROM users_on_a) UNION (SELECT * FROM users_on_b)

С

...