/
create-data.go
108 lines (87 loc) · 2.45 KB
/
create-data.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
import (
"database/sql"
"fmt"
"log"
"math/rand"
"time"
sq "github.com/Masterminds/squirrel"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "root@tcp(127.0.0.1:3306)/db-range-query-perf")
if err != nil {
log.Fatal(err)
}
defer db.Close()
for i := 0; i < 10; i++ {
log.Printf("%d: Creating %d users with %d posts", i, 1000, 1000)
CreateNUsersWithPosts(db, 1000, 1000)
log.Printf("%d: Created %d users with %d posts", i, 1000, 1000)
}
}
// CreateNUsersWithJournals は、uCount人のuserを作成し、各ユーザーにpCount個のpostを作成します。それぞれフォロー状態にします。
func CreateNUsersWithPosts(db *sql.DB, uCount int, pCount int) error {
psql := sq.StatementBuilder.PlaceholderFormat(sq.Question)
userIDs := make([]int, uCount)
for i := 0; i < uCount; i++ {
res, err := db.Exec("INSERT INTO users (name) VALUES (?)", fmt.Sprintf("user%d", i+1))
if err != nil {
return err
}
id, err := res.LastInsertId()
if err != nil {
return err
}
userIDs[i] = int(id)
// Create posts with bulk insert using squirrel
insertBuilder := psql.Insert("posts").Columns("user_id", "body", "posted_at", "deleted")
for j := 0; j < pCount; j++ {
insertBuilder = insertBuilder.Values(
userIDs[i],
fmt.Sprintf("Post %d of User%d", j+1, userIDs[i]),
randomPostedAt(),
randomDeleted(),
)
}
query, args, err := insertBuilder.ToSql()
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(query, args...)
if err != nil {
log.Fatal(err)
}
}
// Create followings
for i := 0; i < uCount; i++ {
insertBuilder := psql.Insert("follows").Columns("follower_id", "followee_id")
for j := 0; j < uCount; j++ {
insertBuilder = insertBuilder.Values(userIDs[i], userIDs[j])
}
query, args, err := insertBuilder.ToSql()
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(query, args...)
if err != nil {
log.Fatal(err)
}
}
return nil
}
// 2ヶ月前から現在までの間でランダムに時刻を生成します。
func randomPostedAt() time.Time {
now := time.Now()
twoMonthAgo := now.AddDate(0, -2, 0)
diff := now.Unix() - twoMonthAgo.Unix()
// ランダムな差分を生成
randomDiff := rand.Int63n(diff)
// ランダムな時刻を生成
randomTime := twoMonthAgo.Add(time.Duration(randomDiff) * time.Second)
return randomTime
}
// 0.1%の確率でtrueを返す
func randomDeleted() bool {
return rand.Intn(1000) == 0
}