Kills table structure optimization

- Replaced victim_id with victim_uuid
- Replaced killer_id with killer_uuid
- Replaced server_id with server_uuid
This commit is contained in:
Rsl1122 2018-12-13 19:11:56 +02:00
parent 35d6d0bbb4
commit 1f6edf0588
4 changed files with 134 additions and 53 deletions

View File

@ -204,6 +204,7 @@ public abstract class SQLDB extends Database {
new DiskUsagePatch(this), new DiskUsagePatch(this),
new WorldsOptimizationPatch(this), new WorldsOptimizationPatch(this),
new WorldTimesOptimizationPatch(this), new WorldTimesOptimizationPatch(this),
new KillsOptimizationPatch(this),
new SessionsOptimizationPatch(this), new SessionsOptimizationPatch(this),
new PingOptimizationPatch(this) new PingOptimizationPatch(this)
}; };

View File

@ -0,0 +1,80 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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.KillsTable;
import com.djrapitops.plan.system.database.databases.sql.tables.KillsTable.Col;
public class KillsOptimizationPatch extends Patch {
private String tempTableName;
private String tableName;
public KillsOptimizationPatch(SQLDB db) {
super(db);
tableName = KillsTable.TABLE_NAME;
tempTableName = "temp_kills";
}
@Override
public boolean hasBeenApplied() {
return hasColumn(tableName, Col.VICTIM_UUID.get())
&& hasColumn(tableName, Col.KILLER_UUID.get())
&& hasColumn(tableName, Col.SERVER_UUID.get())
&& !hasColumn(tableName, "killer_id")
&& !hasColumn(tableName, "victim_id")
&& !hasColumn(tableName, "server_id")
&& !hasTable(tempTableName); // If this table exists the patch has failed to finish.
}
@Override
public void apply() {
try {
tempOldTable();
db.getKillsTable().createTable();
db.execute("INSERT INTO " + tableName + " (" +
Col.VICTIM_UUID + ", " +
Col.KILLER_UUID + ", " +
Col.SERVER_UUID + ", " +
Col.DATE + ", " +
Col.WEAPON + ", " +
Col.SESSION_ID +
") SELECT " +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".victim_id LIMIT 1), " +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".killer_id LIMIT 1), " +
"(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " +
Col.DATE + ", " +
Col.WEAPON + ", " +
Col.SESSION_ID +
" FROM " + tempTableName
);
dropTable(tempTableName);
} catch (Exception e) {
throw new DBOpException(KillsOptimizationPatch.class.getSimpleName() + " failed.", e);
}
}
private void tempOldTable() {
if (!hasTable(tempTableName)) {
renameTable(tableName, tempTableName);
}
}
}

View File

@ -35,8 +35,11 @@ public class KillsServerIDPatch extends Patch {
@Override @Override
public boolean hasBeenApplied() { public boolean hasBeenApplied() {
String tableName = KillsTable.TABLE_NAME; String tableName = KillsTable.TABLE_NAME;
String columnName = KillsTable.Col.SERVER_ID.get(); String columnName = "server_id";
return hasColumn(tableName, columnName) && allValuesHaveServerID(tableName, columnName);
// KillsOptimizationPatch makes this patch incompatible with newer patch versions.
return hasColumn(tableName, KillsTable.Col.SERVER_UUID.get())
|| hasColumn(tableName, columnName) && allValuesHaveServerID(tableName, columnName);
} }
private Boolean allValuesHaveServerID(String tableName, String columnName) { private Boolean allValuesHaveServerID(String tableName, String columnName) {
@ -56,13 +59,11 @@ public class KillsServerIDPatch extends Patch {
@Override @Override
public void apply() { public void apply() {
addColumn(KillsTable.TABLE_NAME, KillsTable.Col.SERVER_ID + " integer NOT NULL DEFAULT 0"); addColumn(KillsTable.TABLE_NAME, "server_id integer NOT NULL DEFAULT 0");
Map<Integer, Integer> sessionIDServerIDRelation = db.getSessionsTable().getIDServerIDRelation(); Map<Integer, Integer> sessionIDServerIDRelation = db.getSessionsTable().getIDServerIDRelation();
String sql = "UPDATE " + KillsTable.TABLE_NAME + " SET " + String sql = "UPDATE " + KillsTable.TABLE_NAME + " SET server_id=? WHERE " + KillsTable.Col.SESSION_ID + "=?";
KillsTable.Col.SERVER_ID + "=?" +
" WHERE " + KillsTable.Col.SESSION_ID + "=?";
db.executeBatch(new ExecStatement(sql) { db.executeBatch(new ExecStatement(sql) {
@Override @Override

View File

@ -40,31 +40,31 @@ import java.util.*;
* <p> * <p>
* Table Name: plan_kills * Table Name: plan_kills
* <p> * <p>
* 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.KillsServerIDPatch}
* {@link com.djrapitops.plan.system.database.databases.sql.patches.KillsOptimizationPatch}
* *
* @author Rsl1122 * @author Rsl1122
*/ */
public class KillsTable extends UserIDTable { public class KillsTable extends UserUUIDTable {
public static final String TABLE_NAME = "plan_kills"; public static final String TABLE_NAME = "plan_kills";
private final ServerTable serverTable;
private final UsersTable usersTable;
public KillsTable(SQLDB db) { public KillsTable(SQLDB db) {
super(TABLE_NAME, db); super(TABLE_NAME, db);
usersTable = db.getUsersTable();
sessionsTable = db.getSessionsTable(); sessionsTable = db.getSessionsTable();
serverTable = db.getServerTable();
insertStatement = "INSERT INTO " + tableName + " (" insertStatement = "INSERT INTO " + tableName + " ("
+ Col.KILLER_ID + ", " + Col.KILLER_UUID + ", "
+ Col.VICTIM_ID + ", " + Col.VICTIM_UUID + ", "
+ Col.SERVER_ID + ", " + Col.SERVER_UUID + ", "
+ Col.SESSION_ID + ", " + Col.SESSION_ID + ", "
+ Col.DATE + ", " + Col.DATE + ", "
+ Col.WEAPON + Col.WEAPON
+ ") VALUES (" + ") VALUES (?, ?, ?, ?, ?, ?)";
+ usersTable.statementSelectID + ", "
+ usersTable.statementSelectID + ", "
+ serverTable.statementSelectServerID + ", "
+ "?, ?, ?)";
} }
private final SessionsTable sessionsTable; private final SessionsTable sessionsTable;
@ -73,16 +73,15 @@ public class KillsTable extends UserIDTable {
@Override @Override
public void createTable() throws DBInitException { public void createTable() throws DBInitException {
createTable(TableSqlParser.createTable(tableName) createTable(TableSqlParser.createTable(tableName)
.column(Col.KILLER_ID, Sql.INT).notNull() .primaryKeyIDColumn(supportsMySQLQueries, Col.ID)
.column(Col.VICTIM_ID, Sql.INT).notNull() .column(Col.KILLER_UUID, Sql.varchar(36)).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull() .column(Col.VICTIM_UUID, Sql.varchar(36)).notNull()
.column(Col.SERVER_UUID, Sql.varchar(36)).notNull()
.column(Col.WEAPON, Sql.varchar(30)).notNull() .column(Col.WEAPON, Sql.varchar(30)).notNull()
.column(Col.DATE, Sql.LONG).notNull() .column(Col.DATE, Sql.LONG).notNull()
.column(Col.SESSION_ID, Sql.INT).notNull() .column(Col.SESSION_ID, Sql.INT).notNull()
.foreignKey(Col.KILLER_ID, usersTable.getTableName(), UsersTable.Col.ID) .primaryKey(supportsMySQLQueries, Col.ID)
.foreignKey(Col.VICTIM_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID) .foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID)
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
.toString() .toString()
); );
} }
@ -90,8 +89,8 @@ public class KillsTable extends UserIDTable {
@Override @Override
public void removeUser(UUID uuid) { public void removeUser(UUID uuid) {
String sql = "DELETE FROM " + tableName + String sql = "DELETE FROM " + tableName +
" WHERE " + Col.KILLER_ID + " = " + usersTable.statementSelectID + " WHERE " + Col.KILLER_UUID + "=?" +
" OR " + Col.VICTIM_ID + " = " + usersTable.statementSelectID; " OR " + Col.VICTIM_UUID + "=?";
execute(new ExecStatement(sql) { execute(new ExecStatement(sql) {
@Override @Override
@ -103,18 +102,17 @@ public class KillsTable extends UserIDTable {
} }
public void addKillsToSessions(UUID uuid, Map<Integer, Session> sessions) { public void addKillsToSessions(UUID uuid, Map<Integer, Session> sessions) {
String usersIDColumn = usersTable + "." + UsersTable.Col.ID; String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID;
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid";
String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name"; String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name";
String sql = "SELECT " + String sql = "SELECT " +
Col.SESSION_ID + ", " + Col.SESSION_ID + ", " +
Col.DATE + ", " + Col.DATE + ", " +
Col.WEAPON + ", " + Col.WEAPON + ", " +
usersUUIDColumn + ", " + Col.VICTIM_UUID + ", " +
usersNameColumn + usersNameColumn +
" FROM " + tableName + " FROM " + tableName +
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.VICTIM_ID + " INNER JOIN " + usersTable + " on " + usersUUIDColumn + "=" + Col.VICTIM_UUID +
" WHERE " + Col.KILLER_ID + "=" + usersTable.statementSelectID; " WHERE " + Col.KILLER_UUID + "=?";
query(new QueryStatement<Object>(sql, 50000) { query(new QueryStatement<Object>(sql, 50000) {
@Override @Override
@ -130,7 +128,7 @@ public class KillsTable extends UserIDTable {
if (session == null) { if (session == null) {
continue; continue;
} }
UUID victim = UUID.fromString(set.getString("victim_uuid")); UUID victim = UUID.fromString(set.getString(Col.VICTIM_UUID.get()));
String victimName = set.getString("victim_name"); String victimName = set.getString("victim_name");
long date = set.getLong(Col.DATE.get()); long date = set.getLong(Col.DATE.get());
String weapon = set.getString(Col.WEAPON.get()); String weapon = set.getString(Col.WEAPON.get());
@ -142,18 +140,17 @@ public class KillsTable extends UserIDTable {
} }
public void addDeathsToSessions(UUID uuid, Map<Integer, Session> sessions) { public void addDeathsToSessions(UUID uuid, Map<Integer, Session> sessions) {
String usersIDColumn = usersTable + "." + UsersTable.Col.ID; String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID;
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as killer_uuid";
String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as killer_name"; String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as killer_name";
String sql = "SELECT " + String sql = "SELECT " +
Col.SESSION_ID + ", " + Col.SESSION_ID + ", " +
Col.DATE + ", " + Col.DATE + ", " +
Col.WEAPON + ", " + Col.WEAPON + ", " +
usersUUIDColumn + ", " + Col.KILLER_UUID + ", " +
usersNameColumn + usersNameColumn +
" FROM " + tableName + " FROM " + tableName +
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.KILLER_ID + " INNER JOIN " + usersTable + " on " + usersUUIDColumn + "=" + Col.KILLER_UUID +
" WHERE " + Col.VICTIM_ID + "=" + usersTable.statementSelectID; " WHERE " + Col.VICTIM_UUID + "=?";
query(new QueryStatement<Object>(sql, 50000) { query(new QueryStatement<Object>(sql, 50000) {
@Override @Override
@ -169,7 +166,7 @@ public class KillsTable extends UserIDTable {
if (session == null) { if (session == null) {
continue; continue;
} }
UUID killer = UUID.fromString(set.getString("killer_uuid")); UUID killer = UUID.fromString(set.getString(Col.KILLER_UUID.get()));
String name = set.getString("killer_name"); String name = set.getString("killer_name");
long date = set.getLong(Col.DATE.get()); long date = set.getLong(Col.DATE.get());
String weapon = set.getString(Col.WEAPON.get()); String weapon = set.getString(Col.WEAPON.get());
@ -209,28 +206,24 @@ public class KillsTable extends UserIDTable {
} }
public Map<UUID, List<PlayerKill>> getPlayerKills() { public Map<UUID, List<PlayerKill>> getPlayerKills() {
String usersVictimIDColumn = usersTable + "." + UsersTable.Col.ID; String usersVictimUUIDColumn = usersTable + "." + UsersTable.Col.UUID;
String usersKillerIDColumn = "a." + UsersTable.Col.ID;
String usersVictimUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid";
String usersVictimNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name"; String usersVictimNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name";
String usersKillerUUIDColumn = "a." + UsersTable.Col.UUID + " as killer_uuid";
String sql = "SELECT " + String sql = "SELECT " +
Col.DATE + ", " + Col.DATE + ", " +
Col.WEAPON + ", " + Col.WEAPON + ", " +
usersVictimUUIDColumn + ", " + Col.VICTIM_UUID + ", " +
usersVictimNameColumn + ", " + usersVictimNameColumn + ", " +
usersKillerUUIDColumn + Col.KILLER_UUID +
" FROM " + tableName + " FROM " + tableName +
" INNER JOIN " + usersTable + " on " + usersVictimIDColumn + "=" + Col.VICTIM_ID + " INNER JOIN " + usersTable + " on " + usersVictimUUIDColumn + "=" + Col.VICTIM_UUID;
" INNER JOIN " + usersTable + " a on " + usersKillerIDColumn + "=" + Col.KILLER_ID;
return query(new QueryAllStatement<Map<UUID, List<PlayerKill>>>(sql, 50000) { return query(new QueryAllStatement<Map<UUID, List<PlayerKill>>>(sql, 50000) {
@Override @Override
public Map<UUID, List<PlayerKill>> processResults(ResultSet set) throws SQLException { public Map<UUID, List<PlayerKill>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<PlayerKill>> allKills = new HashMap<>(); Map<UUID, List<PlayerKill>> allKills = new HashMap<>();
while (set.next()) { while (set.next()) {
UUID killer = UUID.fromString(set.getString("killer_uuid")); UUID killer = UUID.fromString(set.getString(Col.KILLER_UUID.get()));
UUID victim = UUID.fromString(set.getString("victim_uuid")); UUID victim = UUID.fromString(set.getString(Col.VICTIM_UUID.get()));
String victimName = set.getString("victim_name"); String victimName = set.getString("victim_name");
long date = set.getLong(Col.DATE.get()); long date = set.getLong(Col.DATE.get());
String weapon = set.getString(Col.WEAPON.get()); String weapon = set.getString(Col.WEAPON.get());
@ -245,17 +238,16 @@ public class KillsTable extends UserIDTable {
} }
public Map<Integer, List<PlayerKill>> getAllPlayerKillsBySessionID() { public Map<Integer, List<PlayerKill>> getAllPlayerKillsBySessionID() {
String usersIDColumn = usersTable + "." + UsersTable.Col.ID; String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID;
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid";
String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name"; String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name";
String sql = "SELECT " + String sql = "SELECT " +
Col.SESSION_ID + ", " + Col.SESSION_ID + ", " +
Col.DATE + ", " + Col.DATE + ", " +
Col.WEAPON + ", " + Col.WEAPON + ", " +
usersUUIDColumn + ", " + Col.VICTIM_UUID + ", " +
usersNameColumn + usersNameColumn +
" FROM " + tableName + " FROM " + tableName +
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.VICTIM_ID; " INNER JOIN " + usersTable + " on " + usersUUIDColumn + "=" + Col.VICTIM_UUID;
return query(new QueryAllStatement<Map<Integer, List<PlayerKill>>>(sql, 50000) { return query(new QueryAllStatement<Map<Integer, List<PlayerKill>>>(sql, 50000) {
@Override @Override
@ -266,7 +258,7 @@ public class KillsTable extends UserIDTable {
List<PlayerKill> playerKills = allPlayerKills.getOrDefault(sessionID, new ArrayList<>()); List<PlayerKill> playerKills = allPlayerKills.getOrDefault(sessionID, new ArrayList<>());
UUID victim = UUID.fromString(set.getString("victim_uuid")); UUID victim = UUID.fromString(set.getString(Col.VICTIM_UUID.get()));
String victimName = set.getString("victim_name"); String victimName = set.getString("victim_name");
long date = set.getLong(Col.DATE.get()); long date = set.getLong(Col.DATE.get());
String weapon = set.getString(Col.WEAPON.get()); String weapon = set.getString(Col.WEAPON.get());
@ -331,9 +323,16 @@ public class KillsTable extends UserIDTable {
} }
public enum Col implements Column { public enum Col implements Column {
ID("id"),
@Deprecated
KILLER_ID("killer_id"), KILLER_ID("killer_id"),
KILLER_UUID("killer_uuid"),
@Deprecated
VICTIM_ID("victim_id"), VICTIM_ID("victim_id"),
VICTIM_UUID("victim_uuid"),
@Deprecated
SERVER_ID("server_id"), SERVER_ID("server_id"),
SERVER_UUID("server_uuid"),
SESSION_ID("session_id"), SESSION_ID("session_id"),
WEAPON("weapon"), WEAPON("weapon"),
DATE("date"); DATE("date");