public List<GroupedDataRecord> group(final List<DataRecord> dataRecords) {
        List<GroupedDataRecord> result = new ArrayList<>(100);
        List<DataRecord> mergedDataRecords = dataRecords.get(0).getUniqueKeyValue().isEmpty() ? dataRecords : merge(dataRecords);
        Map<String, List<DataRecord>> tableGroup = mergedDataRecords.stream().collect(Collectors.groupingBy(DataRecord::getTableName));
        for (Entry<String, List<DataRecord>> entry : tableGroup.entrySet()) {
            Map<PipelineSQLOperationType, List<DataRecord>> typeGroup = entry.getValue().stream().collect(Collectors.groupingBy(DataRecord::getType));
            result.add(new GroupedDataRecord(entry.getKey(), typeGroup.getOrDefault(PipelineSQLOperationType.INSERT, Collections.emptyList()),
                    typeGroup.getOrDefault(PipelineSQLOperationType.UPDATE, Collections.emptyList()), typeGroup.getOrDefault(PipelineSQLOperationType.DELETE, Collections.emptyList())));
        }
        return result;
    }
@Test
    void assertGroup() {
        List<DataRecord> dataRecords = mockDataRecords();
        List<GroupedDataRecord> groupedDataRecords = groupEngine.group(dataRecords);
        assertThat(groupedDataRecords.size(), is(2));
        assertThat(groupedDataRecords.get(0).getTableName(), is("t1"));
        assertThat(groupedDataRecords.get(1).getTableName(), is("t2"));
        assertThat(groupedDataRecords.get(0).getInsertDataRecords().size(), is(1));
        assertThat(groupedDataRecords.get(0).getUpdateDataRecords().size(), is(1));
        assertThat(groupedDataRecords.get(0).getDeleteDataRecords().size(), is(1));
    }