Asopitech With · フィットネスSNS
Strava with Alopex DB & Alopex Skulk
Stravaは、ランニングやサイクリングを記録して共有するフィットネスSNSです。これをAlopex DBとAlopex Skulkを使って再現すると…?
更新: 2026/10/12
どんなサービスか
Stravaは、ランニングやサイクリングのアクティビティを記録して共有するサービスです。道の決まった区間はセグメントとして登録され、同じ区間を走った人どうしで記録を比べられます。扱うデータは、アクティビティ、走っている間の心拍や速度や位置、セグメントです。
データの置き場所
- Skulkの時系列:心拍、速度、ケイデンス、標高を、アクティビティのタグを付けてSkulkに追記します。区間ごとの平均や最大は、時間で区切る集計で出します。
- Alopex DBのテーブル:アクティビティ、ギア、セグメント、セグメントの記録をテーブルに持ちます。セグメントの順位は、記録のテーブルのSQLで出します。
機器から届いた記録を書き込むのも、セグメントを通ったかを判定するのも、アプリのコードです。
配置の形
SkulkとAlopex DBを、端末のアプリに組み込みます。走っている間の記録は端末の中にたまり、電波のない山道でも途切れません。セグメントの順位をみんなで比べる部分は、Alopex DBのサーバーで受けます。
Alopex DBとAlopex Skulkが合う理由
ワークアウトの記録は、細かい時系列と、アクティビティの一覧の両方です。Skulkは時系列の取り込みと集計を、Alopex DBはアクティビティとセグメントを受け持ち、端末とサーバーで同じSQLを使えます。
コードで見る
アクティビティとセグメントはAlopex DBが持ちます(走行中の心拍・速度の時系列はSkulkが集計)。セグメントの順位を出す中心だけを取り出したコードです。
import alopex
# アクティビティとセグメントは Alopex DB(走行中の時系列は Skulk が受け持つ)
db = alopex.Database.open("strava.alopex")
db.execute_sql("CREATE TABLE IF NOT EXISTS segments (id INTEGER PRIMARY KEY, name TEXT)")
db.execute_sql("""
CREATE TABLE IF NOT EXISTS efforts (
segment_id INTEGER,
athlete TEXT,
elapsed INTEGER
)
""")
db.execute_sql("INSERT INTO segments (id, name) VALUES (?, ?)", [1, "多摩川土手 5km"])
for athlete, elapsed in [("Aya", 1180), ("Ken", 1095), ("Mio", 1240)]:
db.execute_sql("INSERT INTO efforts (segment_id, athlete, elapsed) VALUES (?, ?, ?)", [1, athlete, elapsed])
# セグメントの順位(記録の速い順)を SQL で出す
rows = db.execute_sql("""
SELECT athlete, elapsed
FROM efforts
WHERE segment_id = ?
ORDER BY elapsed ASC
""", [1])
for i, row in enumerate(rows, 1):
print(i, row["athlete"], f'{row["elapsed"]}秒')記録を速い順に並べれば、そのまま順位表になります。走行中の心拍・速度・位置の時系列は、Skulkがアクティビティのタグ付きで取り込んで集計します。
走っている間の時系列はAlopex Skulk、アクティビティとセグメントはAlopex DB。この組み合わせで、ワークアウトのアプリを作ってみよう。