CleanupSqlBackup.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. namespace App\Module\Cleanup\Models;
  3. use UCore\ModelCore;
  4. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  5. /**
  6. * SQL备份记录模型
  7. *
  8. * 存储INSERT语句到数据库表中
  9. */
  10. class CleanupSqlBackup extends ModelCore
  11. {
  12. /**
  13. * 数据表名
  14. */
  15. protected $table = 'cleanup_sql_backups';
  16. // field start
  17. * @property int $id 主键ID
  18. * @property int $backup_id 备份记录ID
  19. * @property string $table_name 表名
  20. * @property string $sql_content INSERT语句内容
  21. * @property int $records_count 记录数量
  22. * @property int $content_size 内容大小(字节)
  23. * @property string $content_hash 内容SHA256哈希
  24. * @property array $backup_conditions 备份条件
  25. * @property \Carbon\Carbon $created_at 创建时间
  26. * field end
  27. /**
  28. * 字段类型转换
  29. */
  30. protected $casts = [
  31. 'backup_conditions' => 'array',
  32. 'records_count' => 'integer',
  33. 'content_size' => 'integer',
  34. ];
  35. /**
  36. * 隐藏字段
  37. */
  38. protected $hidden = [
  39. 'sql_content', // 默认隐藏SQL内容,避免大量数据传输
  40. ];
  41. /**
  42. * 关联备份记录
  43. */
  44. public function backup(): BelongsTo
  45. {
  46. return $this->belongsTo(CleanupBackup::class, 'backup_id');
  47. }
  48. /**
  49. * 获取格式化的内容大小
  50. */
  51. public function getFormattedSizeAttribute(): string
  52. {
  53. $size = $this->content_size;
  54. if ($size < 1024) {
  55. return $size . ' B';
  56. } elseif ($size < 1024 * 1024) {
  57. return round($size / 1024, 2) . ' KB';
  58. } elseif ($size < 1024 * 1024 * 1024) {
  59. return round($size / (1024 * 1024), 2) . ' MB';
  60. } else {
  61. return round($size / (1024 * 1024 * 1024), 2) . ' GB';
  62. }
  63. }
  64. /**
  65. * 获取SQL内容预览(前100个字符)
  66. */
  67. public function getSqlPreviewAttribute(): string
  68. {
  69. if (empty($this->sql_content)) {
  70. return '';
  71. }
  72. $preview = substr($this->sql_content, 0, 100);
  73. if (strlen($this->sql_content) > 100) {
  74. $preview .= '...';
  75. }
  76. return $preview;
  77. }
  78. /**
  79. * 验证内容哈希
  80. */
  81. public function verifyContentHash(): bool
  82. {
  83. if (empty($this->sql_content) || empty($this->content_hash)) {
  84. return false;
  85. }
  86. $currentHash = hash('sha256', $this->sql_content);
  87. return $currentHash === $this->content_hash;
  88. }
  89. /**
  90. * 作用域:按备份ID筛选
  91. */
  92. public function scopeByBackup($query, int $backupId)
  93. {
  94. return $query->where('backup_id', $backupId);
  95. }
  96. /**
  97. * 作用域:按表名筛选
  98. */
  99. public function scopeByTable($query, string $tableName)
  100. {
  101. return $query->where('table_name', $tableName);
  102. }
  103. /**
  104. * 作用域:按记录数量排序
  105. */
  106. public function scopeOrderByRecords($query, string $direction = 'desc')
  107. {
  108. return $query->orderBy('records_count', $direction);
  109. }
  110. /**
  111. * 作用域:按内容大小排序
  112. */
  113. public function scopeOrderBySize($query, string $direction = 'desc')
  114. {
  115. return $query->orderBy('content_size', $direction);
  116. }
  117. /**
  118. * 获取统计信息
  119. */
  120. public static function getStats(): array
  121. {
  122. return [
  123. 'total_count' => static::count(),
  124. 'total_records' => static::sum('records_count'),
  125. 'total_size' => static::sum('content_size'),
  126. 'avg_records_per_backup' => static::avg('records_count'),
  127. 'avg_size_per_backup' => static::avg('content_size'),
  128. ];
  129. }
  130. /**
  131. * 获取按表名分组的统计
  132. */
  133. public static function getTableStats(): array
  134. {
  135. return static::selectRaw('
  136. table_name,
  137. COUNT(*) as backup_count,
  138. SUM(records_count) as total_records,
  139. SUM(content_size) as total_size,
  140. AVG(records_count) as avg_records,
  141. AVG(content_size) as avg_size
  142. ')
  143. ->groupBy('table_name')
  144. ->orderBy('total_size', 'desc')
  145. ->get()
  146. ->toArray();
  147. }
  148. }