strategy.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package sharding
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. // ShardingStrategy 分表策略接口
  7. type ShardingStrategy interface {
  8. // GetTableName 根据时间获取表名
  9. GetTableName(baseTableName string, t time.Time) string
  10. // GetCurrentTableName 获取当前表名
  11. GetCurrentTableName(baseTableName string) string
  12. // GetTableNamesByRange 根据时间范围获取所有可能的表名
  13. GetTableNamesByRange(baseTableName string, start, end time.Time) []string
  14. // GetNextTableName 根据当前表名获取下一个表名(用于动态分表)
  15. GetNextTableName(currentTableName string) string
  16. // IsNewPeriod 检查是否应该开始新的分表周期
  17. IsNewPeriod(lastTableTime, currentTime time.Time) bool
  18. }
  19. // MonthlyShardingStrategy 按月分表策略 - 每月第一天分表
  20. type MonthlyShardingStrategy struct{}
  21. func NewMonthlyShardingStrategy() ShardingStrategy {
  22. return &MonthlyShardingStrategy{}
  23. }
  24. func (s *MonthlyShardingStrategy) GetTableName(baseTableName string, t time.Time) string {
  25. return fmt.Sprintf("%s_%d%02d", baseTableName, t.Year(), t.Month())
  26. }
  27. func (s *MonthlyShardingStrategy) GetCurrentTableName(baseTableName string) string {
  28. return s.GetTableName(baseTableName, time.Now())
  29. }
  30. func (s *MonthlyShardingStrategy) GetTableNamesByRange(baseTableName string, start, end time.Time) []string {
  31. var tableNames []string
  32. current := time.Date(start.Year(), start.Month(), 1, 0, 0, 0, 0, start.Location())
  33. endMonth := time.Date(end.Year(), end.Month(), 1, 0, 0, 0, 0, end.Location())
  34. for !current.After(endMonth) {
  35. tableNames = append(tableNames, s.GetTableName(baseTableName, current))
  36. current = current.AddDate(0, 1, 0)
  37. }
  38. return tableNames
  39. }
  40. func (s *MonthlyShardingStrategy) GetNextTableName(currentTableName string) string {
  41. // 解析当前表名,生成下一个序号的表名
  42. // 例如: log_202408 -> log_202408_01, log_202408_01 -> log_202408_02
  43. // 简单实现:在表名后添加序号
  44. return fmt.Sprintf("%s_01", currentTableName)
  45. }
  46. func (s *MonthlyShardingStrategy) IsNewPeriod(lastTableTime, currentTime time.Time) bool {
  47. // 检查是否到了新的月份
  48. lastMonth := time.Date(lastTableTime.Year(), lastTableTime.Month(), 1, 0, 0, 0, 0, lastTableTime.Location())
  49. currentMonth := time.Date(currentTime.Year(), currentTime.Month(), 1, 0, 0, 0, 0, currentTime.Location())
  50. return currentMonth.After(lastMonth)
  51. }
  52. // DailyShardingStrategy 按日分表策略 - 每天分表
  53. type DailyShardingStrategy struct{}
  54. func NewDailyShardingStrategy() ShardingStrategy {
  55. return &DailyShardingStrategy{}
  56. }
  57. func (s *DailyShardingStrategy) GetTableName(baseTableName string, t time.Time) string {
  58. return fmt.Sprintf("%s_%d%02d%02d", baseTableName, t.Year(), t.Month(), t.Day())
  59. }
  60. func (s *DailyShardingStrategy) GetCurrentTableName(baseTableName string) string {
  61. return s.GetTableName(baseTableName, time.Now())
  62. }
  63. func (s *DailyShardingStrategy) GetTableNamesByRange(baseTableName string, start, end time.Time) []string {
  64. var tableNames []string
  65. current := time.Date(start.Year(), start.Month(), start.Day(), 0, 0, 0, 0, start.Location())
  66. endDay := time.Date(end.Year(), end.Month(), end.Day(), 0, 0, 0, 0, end.Location())
  67. for !current.After(endDay) {
  68. tableNames = append(tableNames, s.GetTableName(baseTableName, current))
  69. current = current.AddDate(0, 0, 1) // 每次增加一天
  70. }
  71. return tableNames
  72. }
  73. func (s *DailyShardingStrategy) GetNextTableName(currentTableName string) string {
  74. // 日度分表的序号表名
  75. return fmt.Sprintf("%s_01", currentTableName)
  76. }
  77. func (s *DailyShardingStrategy) IsNewPeriod(lastTableTime, currentTime time.Time) bool {
  78. // 检查是否到了新的一天
  79. lastDay := time.Date(lastTableTime.Year(), lastTableTime.Month(), lastTableTime.Day(), 0, 0, 0, 0, lastTableTime.Location())
  80. currentDay := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location())
  81. return currentDay.After(lastDay)
  82. }