диаграмма отношений сущностей
Структура моей таблицы базы данных выглядит следующим образом:
Таблица курса: (id (первичный ключ), name, descr и другие поля)
Таблица взаимосвязей активности курса: (идентификатор курса, идентификатор активности) (составной ключ - оба столбца)
Таблица взаимосвязи формата курса: (идентификатор курса, идентификатор формата) ( составной ключ - оба столбца)
таблица соотношения экзамена курса: (идентификатор курса, идентификатор экзамена) (составной ключ - оба столбца)
В настоящее время я извлекаю его из базы данных следующее:
Получить курс из запроса db: SELECT по курсу на основе условия.
В java коде: сохраните эти данные в Map, ключ: courseId и значение: course dto
final Map<String, CourseInfo> data = new LinkedHashMap<>();
Теперь все идентификаторы курсов сохраняются в ключе карты, используя это Я получу все FormatIds , ActivityIds и ExamIds
Это будет три отдельных запроса к соответствующим таблицам, и каждый результат будет сохранен в CourseInfo.List formatIds, CourseInfo.List ActivityIds, CourseInfo.List examIds, CourseInfos находятся в карте.
public static void loadCourseRelatedData(final Connection connection,
final Map<String, CourseInfo> data)
throws SQLException {
if (!data.isEmpty()) {
// Load the related data for : ActivityIds
loadFormatOfferingRelatedDataByTable(connection, COURSE_ACTIVITY_REL_TABLE_NAME ,
COURSE_ACTIVITY_REL_FIELDS.ACTIVITY_ID.name(),
COURSE_ACTIVITY_REL_FIELDS.COURSE_ID.name(), data);
// Load the related data for : formatIds
loadFormatOfferingRelatedDataByTable(connection, COURSE_FORMAT_REL_TABLE_NAME ,
COURSE_FORMAT_REL_FIELDS.FORMAT_ID.name(),
COURSE_FORMAT_REL_FIELDS.COURSE_ID.name(), data);
// Load the related data for : ExamIds
loadFormatOfferingRelatedDataByTable(connection, COURSE_EXAM_REL_TABLE_NAME ,
COURSE_EXAM_REL_FIELDS.EXAM_ID.name(),
COURSE_EXAM_REL_FIELDS.COURSE_ID.name(), data);
}
}
Код loadCourseRelatedData выглядит следующим образом
private static void loadCourseRelatedDataByTable(
final Connection connection,
final String tableName,
final String listFieldName,
final String parentField,
final Map<String, CourseInfo> data)
throws SQLException {
StringBuilder sql = new StringBuilder();
try {
sql.append(SELECT).append(NEW_LINE);
sql.append(listFieldName).append(" , ").append(parentField).append(NEW_LINE);
sql.append(FROM).append(NEW_LINE);
sql.append(tableName).append(NEW_LINE);
sql.append(WHERE).append(NEW_LINE);
sql.append(parentField).append(" in ( ").append(NEW_LINE);
sql.append(getCommaSeperatedString(data.size(), "?")).append(NEW_LINE);
sql.append(")");
try (PreparedStatement statement = connection.prepareStatement(sql.toString())) {
// set the perameter
int counter = 1;
for (String parentId : data.keySet()) {
statement.setString(counter++, parentId);
}
try (ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
String parentId = resultSet.getString(parentField);
String relatedId = resultSet.getString(listFieldName);
CourseInfo info = data.get(parentId);
switch (tableName) {
case COURSE_ACTIVITY_REL_TABLE_NAME:
info.getActivityIds().add(relatedId);
break;
case COURSE_FORMAT_REL_TABLE_NAME:
info.getFormatIds().add(relatedId);
break;
case COURSE_EXAM_REL_TABLE_NAME:
info.getExamIds().add(relatedId);
break;
default:
throw new IllegalArgumentException(
tableName + " : Is not valid realtive table");
}
}
}
}
} catch (SQLException ex) {
StringBuilder message = new StringBuilder();
message.append("\t Related Sql--> ").append(sql).append(NEW_LINE);
// add the cause Message
message.append(ex.getMessage());
throw new SQLException(message.toString(), ex);
}
}
Теперь вопрос заключается в том, как повысить производительность, избегая этих трех дополнительных вызовов БД для связанных идентификаторов?
Подход 1:
Один из подходов, который я выбрал, - это добавить поле для каждого списка, то есть formatIds, ActivityIds и examIds в Course Table, в котором будут храниться все идентификаторы с разделенными запятыми значениями при вставке.
Так что теперь у меня будут данные через запятую, разделенные в CourseTable, а также связанные таблицы.
Данные таблицы курса будут выглядеть следующим образом:
ID | Name | FomatIds | ActivityIds | ExamIds
---------------------------------------------------------------------------------
001 | couse.01 | for.1,for.2 |act.1, act.2, act.3 | exm.1, exm.2, exm3
002 | couse.02 | for.3,for.4 |act.1, act.3, act.5 | exm.1, exm.2, exm3
.....
.....
Для всех запросов на присоединение также будут доступны связанные таблицы:
COURSE_ACTIVITY_REL_TABLE_NAME
COURSEID | ACTIVITY ID
---------------------------------------------------------------------------------
couse.01 | act.1
couse.01 | act.2
couse.01 | act.3
couse.02 | act.1
couse.02 | act.3
couse.02 | act.5
.....
.....
Недостатками этого подхода являются
- вставка и обновление курса будет немного дороже
- главный недостаток в том, что я могу хранить значения, разделенные запятыми, до 32000 символов как VARCHAR2 (32000). Это единственный пример сущности курса, у меня в приложении много сущностей, поэтому не рекомендуется использовать CLOB вместо VARCHAR2 (32000)
Можете ли вы предложить любой другой подход, который я могу использовать улучшить производительность при получении данных значительно?