Проблемы, возникающие при импорте больших объемов данных из MYSQL и их решения

база данных MySQL

В проекте часто встречается импорт большого количества данных в БД, чтобы использовать sql для анализа данных. В процессе импорта данных будут некоторые проблемы, которые необходимо решить.Здесь, в сочетании с практикой импорта txt данных о 4G, будут показаны возникшие проблемы и решения.Есть ссылка для тех, кто сталкивается та же проблема.

Данные, которые я импортировал, представляют собой текстовый файл энциклопедии, размер файла превышает 4G, и в нем содержится более 65 миллионов фрагментов данных, и каждый фрагмент данных отделяется новой строкой. Каждая часть данных содержит три поля, разделенные вкладками. Метод извлечения данных заключается в использовании класса TripleData для хранения этих трех полей, все поля являются строковыми, а затем сохранения нескольких фрагментов данных в List, а затем сохранения List в базе данных mysql, сохранения всех данных в базе данных mysql партиями.

Вышеизложенное является общей идеей, а ниже перечислены проблемы, возникающие в конкретном процессе импорта.

1 Искаженные символы и проблемы совместимости при подключении к базе данных.

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

URL="jdbc:mysql://"+IP+":"+PORT+"/"+DB_NAME+"?useSSL=false&useUnicode=true&characterEncoding=utf-8";

Установка кодировки в UTF-8 предназначена для решения проблемы искаженных символов, а установка useSSL — для решения проблемы совместимости между JDBC и mysql. Если useSSL не установлен, будет сообщено об ошибке. похожий на

Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

такое сообщение об ошибке. Основная причина в том, что версия MySQL относительно высока, а версия JDBC относительно низка, что должно быть совместимым.

2 проблема с кодировкой utf8mb4

В процессе импорта данных вы столкнетесь с чем-то вроде

SQLException :Incorrect string value: '\xF0\xA1\x8B\xBE\xE5\xA2...' for column 'name'

Этот вид сообщения об ошибке связан с тем, что набор UTF-8 в MySQL - 3 байта по умолчанию, что не проблема для общих данных. Если это большой объем данных, он неизбежно содержит некоторые выражения WECHAT или специальные символы., Они Занимайте 4 байта, и UTF-8 не может справиться с этим, поэтому сообщается об ошибке. Решением является то, что MySQL ввел 4-байтовую кодировку UTF-8 в версиях после 5,5,3, то есть UTF8MB4, а кодирование MySQL необходимо сбросить.

Вы можете выполнить следующие действия.Во-первых, создайте резервную копию базы данных, которую необходимо изменить.Хотя utf8mb4 обратно совместим с utf8, во избежание неправильной работы вам все равно необходимо принимать меры предосторожности и делать резервные копии. Второй — изменить кодировку набора символов базы данных на utf8mb4 — UTF-8 Unicode и сопоставление utf8mb4_general_ci. Я использовал navicat для модификации вышеуказанной модификации.Как модифицировать с помощью командной строки, вы можете найти сами. Третий — изменить файл конфигурации my.ini в корневом каталоге установки mysql. Добавьте следующие настройки.

[client]
default-character-set = utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
[mysql]
default-character-set = utf8mb4

После завершения модификации вам необходимо перезапустить mysql, чтобы модификация вступила в силу.

Затем снова импортируйте данные, и они должны нормально импортироваться.

 

3 Проблемы эффективности времени при импорте больших партий

Из-за большого объема данных мы разделили данные, я разделил 65 миллионов фрагментов данных на 500 файлов, в каждом файле около 110 000 фрагментов данных, и поместил эти 110 000 фрагментов данных в ArrayList, затем пакетный импорт. Общая идея состоит в том, чтобы использовать метод «вставить в tb (...) значения (...), (...)...;» и использовать вставку для вставки за один раз, что сэкономит много времени. время. Пример метода заключается в следующем.

public static void insertSQL(String sql,List<TripleObject> tripleObjectList) throws SQLException{

        Connection conn=null;

        PreparedStatement psts=null;

        try {

           

           conn=DriverManager.getConnection(Common.URL, Common.DB_USERNAME, Common.DB_PASSWORD);

           conn.setAutoCommit(false); // установить ручную фиксацию

// сохранить суффикс sql

            StringBuffer suffix = new StringBuffer();

          

           int count = 0; 

           psts=conn.prepareStatement("");

           String s="";

           String p="";

           String o="";

            while (count<tripleObjectList.size()) {

                s=tripleObjectList.get(count).getSubject().replaceAll(",", ".").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\'", "").replaceAll("\\\\", "");

                p=tripleObjectList.get(count).getPredicate().replaceAll(",", ".").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\'", "").replaceAll("\\\\", "");

                o=tripleObjectList.get(count).getObject().replaceAll(",", ".").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\'", "").replaceAll("\\\\", "");

                suffix.append("('" +s +"','"+p+"','"+ o+"'),");

                count++;

            }

// Собираем полный SQL

            String allsql = sql + suffix.substring(0, suffix.length() - 1);

// Добавляем исполняемый SQL

            psts.addBatch(allsql);

psts.executeBatch(); // выполнить пакетную обработку

conn.commit(); // фиксация

 

        } catch (Exception e) {

           e.printStackTrace();

        }finally{

           if(psts!=null){

               psts.close();

           }

           if(conn!=null){

               conn.close();

           }

        }

    }

Преимущество этого метода в том, что для импорта данных требуется очень мало времени, 65 миллионов фрагментов данных, и это заняло ровно 1 час. Недостатком является то, что при большом предложении в данных необходимо обрабатывать запятые, круглые скобки, обратную косую черту и т. д. Здесь необходимо измерить, следует ли использовать этот метод.

Если вставлять нормально, то есть использовать форму "вставить в tb(...) values(...);вставить в tb(...) values(...);...", без специальных символов обрабатываются , но это займет много времени. Я протестировал его. На 110 000 единиц данных уходит около 12 минут, а на импорт 65 миллионов единиц данных уходит около 100 часов.

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

Выше приведены проблемы, с которыми я столкнулся при импорте больших объемов данных в mysql, и решения, которые я придумал.Если у вас есть лучшие решения или вы сталкиваетесь с другими проблемами, я надеюсь обсудить их вместе.