Пакетная вставка в несколько таблиц с внешними ключами с использованием JDBC - PullRequest
0 голосов
/ 03 марта 2020

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

tree = {
    "_id": "111",
    "field1": "",
    "field2": "",
    "field3": {
        "_id": "333",
        "_parent_id": "111",
        "field3_1": "",
        "field3_2": "",
        "field3_3": [
            {
                "_id": "1",
                "_parent_id": "333",
                "field3_3_1": ""
            },
            {
                "_id": "2",
                "_parent_id": "333",
                "field3_3_1": ""
            },
            {
                "_id": "3",
                "_parent_id": "333",
                "field3_3_1": ""
            }
        ]
    }
}

Должно соответствовать 3 таблицам: tree, field3 и field3_3 - которые имеют отношения к _id и _parent_id. Каждая ветвь может быть одним значением, таблицей или объектом, в основном дерево имеет динамическую структуру c, которая соответствует некоторой структуре данных в базе данных PostgreSQL. Я использую JDB c для вставки данных в базу данных. Каков наилучший способ вставки таких данных, когда возможно, что пользователь предоставит большие деревья с несколькими ветвями или несколькими значениями ветвей? Я думал о таком утверждении, как:

                 with first_insert as(
                 insert into sample(firstname, lastname)
                 values('fai55', 'shaggk')
                 RETURNING id
                 ),

                 second_insert as(
                 insert into sample1(id, adddetails)
                 values
                 ((select id from first_insert), 'ss')
                 RETURNING user_id
                 )

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

I Я уже реализовал метод, который принимает таблицу и вставки на одном уровне БД, используя PreparedStatement и executeBatch (), и он прекрасно работает. Что-нибудь вроде этого метода, доступного для деревьев?

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

Я решил проблему следующим образом: я беру элементы с одного уровня дерева и вставляю все его необъектные значения в подготовленный пакет (они находятся в одной таблице), возвращая идентификаторы вставленной записи. Затем я беру дочерние элементы каждого из вставленных элементов, назначаю правильный parent_id и пакетно вставляю их в другую таблицу и в другую. Отлично работает!

0 голосов
/ 03 марта 2020

Если дерево имеет динамическую c структуру, я думаю, вам придется проанализировать json, которую вы получите, во что-то, с чем вы можете работать * Java.

Такого можно достичь с помощью и JSONObject . Предположим, вы получили входящий json сериализованный в String data. Тогда вы можете использовать:

JSONObject dataJson = new JSONObject(data);

Теперь вы можете работать с этой древовидной структурой в Java. Вы можете сериализовать его обратно с помощью dataJson.toString() или создать собственный сериализатор.

Если проблема заключается в размере вставки, вы можете l oop over dataJson и разбить его на разумные куски. Например, вы можете использовать что-то вроде этого

        JSONArray jsonArr = dataJson.getJSONArray("field3");
        JSONArray dataAccumJsonArr = new JSONArray();
        for (int i = 0; i < jsonArr.length(); i++) {
            dataAccumJsonArr.put(jsonArr.get(i));
            if (dataAccum.length() > 999) {
                doInsert(dataAccumJsonArr);
                dataAccumJsonArr = new JSONArray();
            }
        }
        doInsert(dataAccumJsonArr);
...