From 918eed1a8f1d1fc9060048e63e5735e9ea5b71d5 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 13 Dec 2018 19:25:15 +0200 Subject: [PATCH] Nickname table structure optimization - Replaced user_id with uuid - Replaced server_id with server_uuid --- .../system/database/databases/sql/SQLDB.java | 3 +- .../sql/patches/NicknameLastSeenPatch.java | 4 +- .../patches/NicknamesOptimizationPatch.java | 74 +++++++++++++++++ .../sql/statements/TableSqlParser.java | 16 ++-- .../databases/sql/tables/NicknamesTable.java | 80 ++++++++----------- .../databases/sql/tables/UsersTable.java | 2 +- 6 files changed, 121 insertions(+), 58 deletions(-) create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknamesOptimizationPatch.java diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java index d59b5b266..b709d770e 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java @@ -206,7 +206,8 @@ public abstract class SQLDB extends Database { new WorldTimesOptimizationPatch(this), new KillsOptimizationPatch(this), new SessionsOptimizationPatch(this), - new PingOptimizationPatch(this) + new PingOptimizationPatch(this), + new NicknamesOptimizationPatch(this) }; try { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java index 49530df34..4e11a247d 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknameLastSeenPatch.java @@ -90,8 +90,8 @@ public class NicknameLastSeenPatch extends Patch { private void updateLastUsed(Map serverIDsByUUID, Map> nicknames) { String updateSQL = "UPDATE " + NicknamesTable.TABLE_NAME + " SET " + NicknamesTable.Col.LAST_USED + "=?" + " WHERE " + NicknamesTable.Col.NICKNAME + "=?" + - " AND " + NicknamesTable.Col.USER_ID + "=?" + - " AND " + NicknamesTable.Col.SERVER_ID + "=?"; + " AND user_id=?" + + " AND server_id=?"; db.executeBatch(new ExecStatement(updateSQL) { @Override diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknamesOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknamesOptimizationPatch.java new file mode 100644 index 000000000..ac3ff7b13 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/NicknamesOptimizationPatch.java @@ -0,0 +1,74 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.system.database.databases.sql.patches; + +import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.system.database.databases.sql.SQLDB; +import com.djrapitops.plan.system.database.databases.sql.tables.NicknamesTable; +import com.djrapitops.plan.system.database.databases.sql.tables.NicknamesTable.Col; + +public class NicknamesOptimizationPatch extends Patch { + + private String tempTableName; + private String tableName; + + public NicknamesOptimizationPatch(SQLDB db) { + super(db); + tableName = NicknamesTable.TABLE_NAME; + tempTableName = "temp_nicknames"; + } + + @Override + public boolean hasBeenApplied() { + return hasColumn(tableName, Col.UUID.get()) + && hasColumn(tableName, Col.SERVER_UUID.get()) + && !hasColumn(tableName, "user_id") + && !hasColumn(tableName, "server_id") + && !hasTable(tempTableName); // If this table exists the patch has failed to finish. + } + + @Override + public void apply() { + try { + tempOldTable(); + db.getNicknamesTable().createTable(); + + db.execute("INSERT INTO " + tableName + " (" + + Col.UUID + ", " + + Col.SERVER_UUID + ", " + + Col.NICKNAME + ", " + + Col.LAST_USED + + ") SELECT " + + "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + + "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + + Col.NICKNAME + ", " + + Col.LAST_USED + + " FROM " + tempTableName + ); + + dropTable(tempTableName); + } catch (Exception e) { + throw new DBOpException(NicknamesOptimizationPatch.class.getSimpleName() + " failed.", e); + } + } + + private void tempOldTable() { + if (!hasTable(tempTableName)) { + renameTable(tableName, tempTableName); + } + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/statements/TableSqlParser.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/statements/TableSqlParser.java index 730119ce9..74bdd74da 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/statements/TableSqlParser.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/statements/TableSqlParser.java @@ -104,27 +104,27 @@ public class TableSqlParser extends SqlParser { return this; } - public TableSqlParser primaryKeyIDColumn(boolean mySQL, Column column) { - return primaryKeyIDColumn(mySQL, column.get()); + public TableSqlParser primaryKeyIDColumn(boolean supportsMySQLQueries, Column column) { + return primaryKeyIDColumn(supportsMySQLQueries, column.get()); } - public TableSqlParser primaryKeyIDColumn(boolean mySQL, String column) { + public TableSqlParser primaryKeyIDColumn(boolean supportsMySQLQueries, String column) { if (columns > 0) { append(", "); } append(column).addSpace(); append(Sql.INT).addSpace(); - append((mySQL) ? "NOT NULL AUTO_INCREMENT" : "PRIMARY KEY"); + append((supportsMySQLQueries) ? "NOT NULL AUTO_INCREMENT" : "PRIMARY KEY"); columns++; return this; } - public TableSqlParser primaryKey(boolean mySQL, Column column) { - return primaryKey(mySQL, column.get()); + public TableSqlParser primaryKey(boolean supportsMySQLQueries, Column column) { + return primaryKey(supportsMySQLQueries, column.get()); } - public TableSqlParser primaryKey(boolean mySQL, String column) { - if (mySQL) { + public TableSqlParser primaryKey(boolean supportsMySQLQueries, String column) { + if (supportsMySQLQueries) { if (columns > 0) { append(", "); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java index e65961408..2224c1d11 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java @@ -37,44 +37,42 @@ import java.util.*; *

* Table Name: plan_nicknames *

- * For contained columns {@see Col} + * Patches related to this table: + * {@link com.djrapitops.plan.system.database.databases.sql.patches.Version10Patch} + * {@link com.djrapitops.plan.system.database.databases.sql.patches.NicknameLastSeenPatch} + * {@link com.djrapitops.plan.system.database.databases.sql.patches.NicknamesOptimizationPatch} * * @author Rsl1122 */ -public class NicknamesTable extends UserIDTable { +public class NicknamesTable extends UserUUIDTable { public static final String TABLE_NAME = "plan_nicknames"; - private final ServerTable serverTable; private String insertStatement; private final String updateStatement; public NicknamesTable(SQLDB db) { super(TABLE_NAME, db); - serverTable = db.getServerTable(); insertStatement = "INSERT INTO " + tableName + " (" + - Col.USER_ID + ", " + - Col.SERVER_ID + ", " + + Col.UUID + ", " + + Col.SERVER_UUID + ", " + Col.NICKNAME + ", " + Col.LAST_USED + - ") VALUES (" + - usersTable.statementSelectID + ", " + - serverTable.statementSelectServerID + ", " + - "?, ?)"; + ") VALUES (?, ?, ?, ?)"; updateStatement = "UPDATE " + tableName + " SET " + Col.LAST_USED + "=?" + " WHERE " + Col.NICKNAME + "=?" + - " AND " + Col.USER_ID + "=" + usersTable.statementSelectID + - " AND " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID; + " AND " + Col.UUID + "=?" + + " AND " + Col.SERVER_UUID + "=?"; } @Override public void createTable() throws DBInitException { createTable(TableSqlParser.createTable(tableName) - .column(Col.USER_ID, Sql.INT).notNull() + .primaryKeyIDColumn(supportsMySQLQueries, Col.ID) + .column(Col.UUID, Sql.varchar(36)).notNull() .column(Col.NICKNAME, Sql.varchar(75)).notNull() - .column(Col.SERVER_ID, Sql.INT).notNull() + .column(Col.SERVER_UUID, Sql.varchar(36)).notNull() .column(Col.LAST_USED, Sql.LONG).notNull() - .foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID) - .foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID) + .primaryKey(supportsMySQLQueries, Col.ID) .toString() ); } @@ -88,8 +86,8 @@ public class NicknamesTable extends UserIDTable { */ public List getNicknames(UUID uuid, UUID serverUUID) { String sql = "SELECT " + Col.NICKNAME + " FROM " + tableName + - " WHERE (" + Col.USER_ID + "=" + usersTable.statementSelectID + ")" + - " AND " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID; + " WHERE (" + Col.UUID + "=?)" + + " AND " + Col.SERVER_UUID + "=?"; return query(new QueryStatement>(sql, 1000) { @Override @@ -126,26 +124,20 @@ public class NicknamesTable extends UserIDTable { } public Map>> getAllNicknames() { - String usersIDColumn = usersTable + "." + UsersTable.Col.ID; - String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid"; - String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID; - String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid"; String sql = "SELECT " + Col.NICKNAME + ", " + Col.LAST_USED + ", " + - usersUUIDColumn + ", " + - serverUUIDColumn + - " FROM " + tableName + - " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID + - " INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID; + Col.UUID + ", " + + Col.SERVER_UUID + + " FROM " + tableName; return query(new QueryAllStatement>>>(sql, 5000) { @Override public Map>> processResults(ResultSet set) throws SQLException { Map>> map = new HashMap<>(); while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString("s_uuid")); - UUID uuid = UUID.fromString(set.getString("uuid")); + UUID serverUUID = UUID.fromString(set.getString(Col.SERVER_UUID.get())); + UUID uuid = UUID.fromString(set.getString(Col.UUID.get())); Map> serverMap = map.getOrDefault(serverUUID, new HashMap<>()); List nicknames = serverMap.getOrDefault(uuid, new ArrayList<>()); @@ -169,25 +161,19 @@ public class NicknamesTable extends UserIDTable { * @see NicknamesTable#getAllNicknames(); */ public Map> getAllNicknamesUnmapped() { - String usersIDColumn = usersTable + "." + UsersTable.Col.ID; - String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid"; - String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID; - String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid"; String sql = "SELECT " + Col.NICKNAME + ", " + Col.LAST_USED + ", " + - usersUUIDColumn + ", " + - serverUUIDColumn + - " FROM " + tableName + - " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID + - " INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID; + Col.UUID + ", " + + Col.SERVER_UUID + + " FROM " + tableName; return query(new QueryAllStatement>>(sql, 5000) { @Override public Map> processResults(ResultSet set) throws SQLException { Map> map = new HashMap<>(); while (set.next()) { - UUID uuid = UUID.fromString(set.getString("uuid")); - UUID serverUUID = UUID.fromString(set.getString("s_uuid")); + UUID uuid = UUID.fromString(set.getString(Col.UUID.get())); + UUID serverUUID = UUID.fromString(set.getString(Col.SERVER_UUID.get())); List nicknames = map.computeIfAbsent(uuid, x -> new ArrayList<>()); nicknames.add(new Nickname( set.getString(Col.NICKNAME.get()), set.getLong(Col.LAST_USED.get()), serverUUID @@ -232,15 +218,12 @@ public class NicknamesTable extends UserIDTable { } public List getNicknameInformation(UUID uuid) { - String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID; - String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid"; String sql = "SELECT " + Col.NICKNAME + ", " + Col.LAST_USED + ", " + - serverUUIDColumn + + Col.SERVER_UUID + " FROM " + tableName + - " INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID + - " WHERE (" + Col.USER_ID + "=" + usersTable.statementSelectID + ")"; + " WHERE (" + Col.UUID + "=?)"; return query(new QueryStatement>(sql, 5000) { @@ -253,7 +236,7 @@ public class NicknamesTable extends UserIDTable { public List processResults(ResultSet set) throws SQLException { List nicknames = new ArrayList<>(); while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString("s_uuid")); + UUID serverUUID = UUID.fromString(set.getString(Col.SERVER_UUID.get())); String nickname = set.getString(Col.NICKNAME.get()); nicknames.add(new Nickname(nickname, set.getLong(Col.LAST_USED.get()), serverUUID)); } @@ -291,8 +274,13 @@ public class NicknamesTable extends UserIDTable { } public enum Col implements Column { + ID("id"), + @Deprecated USER_ID(UserIDTable.Col.USER_ID.get()), + UUID(UserUUIDTable.Col.UUID.get()), + @Deprecated SERVER_ID("server_id"), + SERVER_UUID("server_uuid"), NICKNAME("nickname"), LAST_USED("last_used"); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java index 7aee8b366..df576f06d 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UsersTable.java @@ -249,7 +249,7 @@ public class UsersTable extends UserUUIDTable { String sql = "SELECT DISTINCT " + Col.USER_NAME + " FROM " + tableName + " WHERE LOWER(" + Col.USER_NAME + ") LIKE LOWER(?)" + " UNION SELECT DISTINCT " + Col.USER_NAME + " FROM " + tableName + - " INNER JOIN " + nicknamesTable + " on " + Col.ID + "=" + nicknamesTable + "." + NicknamesTable.Col.USER_ID + + " INNER JOIN " + nicknamesTable + " on " + Col.UUID + "=" + nicknamesTable + "." + NicknamesTable.Col.UUID + " WHERE LOWER(" + NicknamesTable.Col.NICKNAME + ") LIKE LOWER(?)"; return query(new QueryStatement>(sql, 5000) {