fix stat_user unique key with record_type and deduplicate before index
This commit is contained in:
@@ -129,7 +129,7 @@ class StatUserJob implements ShouldQueue
|
|||||||
'created_at' => time(),
|
'created_at' => time(),
|
||||||
'updated_at' => time(),
|
'updated_at' => time(),
|
||||||
],
|
],
|
||||||
['user_id', 'server_rate', 'server_id', 'server_type', 'record_at'],
|
['user_id', 'server_rate', 'server_id', 'server_type', 'record_at', 'record_type'],
|
||||||
[
|
[
|
||||||
'u' => DB::raw("u + VALUES(u)"),
|
'u' => DB::raw("u + VALUES(u)"),
|
||||||
'd' => DB::raw("d + VALUES(d)"),
|
'd' => DB::raw("d + VALUES(d)"),
|
||||||
@@ -152,7 +152,7 @@ class StatUserJob implements ShouldQueue
|
|||||||
|
|
||||||
$sql = "INSERT INTO {$table} (user_id, server_rate, server_id, server_type, record_at, record_type, u, d, created_at, updated_at)
|
$sql = "INSERT INTO {$table} (user_id, server_rate, server_id, server_type, record_at, record_type, u, d, created_at, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
ON CONFLICT (user_id, server_rate, server_id, server_type, record_at)
|
ON CONFLICT (user_id, server_rate, server_id, server_type, record_at, record_type)
|
||||||
DO UPDATE SET
|
DO UPDATE SET
|
||||||
u = {$table}.u + EXCLUDED.u,
|
u = {$table}.u + EXCLUDED.u,
|
||||||
d = {$table}.d + EXCLUDED.d,
|
d = {$table}.d + EXCLUDED.d,
|
||||||
|
|||||||
@@ -28,17 +28,19 @@ return new class extends Migration {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->mergeDuplicateRows();
|
||||||
|
|
||||||
$this->dropUniqueIfExists(self::TABLE, self::OLD_UNIQUE_INDEX);
|
$this->dropUniqueIfExists(self::TABLE, self::OLD_UNIQUE_INDEX);
|
||||||
$this->dropIndexIfExists(self::TABLE, self::OLD_COMPOSITE_INDEX);
|
$this->dropIndexIfExists(self::TABLE, self::OLD_COMPOSITE_INDEX);
|
||||||
|
|
||||||
$this->addUniqueIfNotExists(
|
$this->addUniqueIfNotExists(
|
||||||
self::TABLE,
|
self::TABLE,
|
||||||
['user_id', 'server_rate', 'server_id', 'server_type', 'record_at'],
|
['user_id', 'server_rate', 'server_id', 'server_type', 'record_at', 'record_type'],
|
||||||
self::NEW_UNIQUE_INDEX
|
self::NEW_UNIQUE_INDEX
|
||||||
);
|
);
|
||||||
$this->addIndexIfNotExists(
|
$this->addIndexIfNotExists(
|
||||||
self::TABLE,
|
self::TABLE,
|
||||||
['user_id', 'server_id', 'server_type', 'record_at'],
|
['user_id', 'server_id', 'server_type', 'record_at', 'record_type'],
|
||||||
self::NEW_COMPOSITE_INDEX
|
self::NEW_COMPOSITE_INDEX
|
||||||
);
|
);
|
||||||
$this->addIndexIfNotExists(self::TABLE, ['server_id'], self::NEW_SERVER_ID_INDEX);
|
$this->addIndexIfNotExists(self::TABLE, ['server_id'], self::NEW_SERVER_ID_INDEX);
|
||||||
@@ -132,4 +134,42 @@ return new class extends Migration {
|
|||||||
default => false,
|
default => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge historical duplicates before adding the new unique index.
|
||||||
|
* Duplicate criteria is aligned with the new unique key columns.
|
||||||
|
*/
|
||||||
|
private function mergeDuplicateRows(): void
|
||||||
|
{
|
||||||
|
$duplicateRows = DB::table(self::TABLE)
|
||||||
|
->selectRaw(
|
||||||
|
'MIN(id) AS keep_id, user_id, server_rate, server_id, server_type, record_at, record_type, ' .
|
||||||
|
'SUM(u) AS total_u, SUM(d) AS total_d, MIN(created_at) AS min_created_at, MAX(updated_at) AS max_updated_at'
|
||||||
|
)
|
||||||
|
->groupBy('user_id', 'server_rate', 'server_id', 'server_type', 'record_at', 'record_type')
|
||||||
|
->havingRaw('COUNT(*) > 1')
|
||||||
|
->orderBy('keep_id')
|
||||||
|
->cursor();
|
||||||
|
|
||||||
|
foreach ($duplicateRows as $row) {
|
||||||
|
DB::table(self::TABLE)
|
||||||
|
->where('id', $row->keep_id)
|
||||||
|
->update([
|
||||||
|
'u' => (int) $row->total_u,
|
||||||
|
'd' => (int) $row->total_d,
|
||||||
|
'created_at' => (int) $row->min_created_at,
|
||||||
|
'updated_at' => (int) $row->max_updated_at,
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::table(self::TABLE)
|
||||||
|
->where('user_id', $row->user_id)
|
||||||
|
->where('server_rate', $row->server_rate)
|
||||||
|
->where('server_id', $row->server_id)
|
||||||
|
->where('server_type', $row->server_type)
|
||||||
|
->where('record_at', $row->record_at)
|
||||||
|
->where('record_type', $row->record_type)
|
||||||
|
->where('id', '!=', $row->keep_id)
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user