Дубликаты данных в Arraylist - PullRequest
0 голосов
/ 12 июня 2019

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

        Connection conn = DriverManager.getConnection(url, userid, password);
        String strSql = "SELECT * FROM events, eventStats" ;
        PreparedStatement Stmt = conn.prepareStatement(strSql);
        ResultSet rs = Stmt.executeQuery(strSql);

        while(rs.next()){
            Events user = new Events();
            user.seteName(rs.getString(2));
            user.setePlace(rs.getString(4));
            user.seteDate(rs.getString(5));
            user.seteInscrit(String.valueOf(rs.getInt(8)));
            user.seteTotal(String.valueOf(rs.getFloat(10)));
            data.add(user);
        }

Спасибо за вашу помощь!

1 Ответ

3 голосов
/ 12 июня 2019

Вы на самом деле не видите «повторяющиеся» строки в самом строгом смысле этого слова.

То, что вы видите, это декартово произведение , в котором каждая строка в одной таблице соединена с каждой отдельной строкой в другой таблице. Вы получаете это, потому что у вас есть декартово соединение (или перекрестное соединение, если вы предпочитаете) в вашем SQL-выражении:

SELECT * FROM events, eventStats
--            ^^^^^^^^^^^^^^^^^^

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

Существует несколько сценариев, в которых желательно декартово объединение, однако оно очень часто является показателем ошибочного запроса и может оказать огромное влияние на производительность вашей системы, если одна из таблиц особенно велика. 1

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

SELECT *
  FROM events v
       [INNER|LEFT OUTER|RIGHT OUTER] JOIN eventStats s
         ON v.SomeColumn = s.SomeMatchingColumn

или неявный:

SELECT *
  FROM events v, eventStats s
 WHERE v.SomeColumn = s.SomeMatchingColumn

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

1 Количество строк, возвращаемых декартовым объединением, равно произведению размеров таблиц, участвующих в объединении. Например, скажем, таблица events содержит 50 000 строк, а таблица eventStats также содержит 50 000 строк, по одной на каждый event. С декартовым объединением этих таблиц ваш запрос вернет огромные 2 500 000 000 , да, это 2,5 миллиардов строк данных. А теперь представьте, что вы читаете все это в ArrayList ... за исключением того, что вы не можете, потому что массивы Java не могут быть такими большими! Ваше приложение завершится с ошибкой java.lang.OutOfMemoryError: Requested array size exceeds VM limit или java.lang.OutOfMemoryError: Java heap space, прежде чем вы сможете прочитать все данные в.

...