0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【並び替え】人生で一番舐めてかかったロジック

0
Last updated at Posted at 2025-12-19

この記事は何?

私がエンジニア2年目の時に「これ実装して」と頼まれた時の思い出です

何を実装したの?

下記の要件を満たす新機能を実装することになりました

  • 最大5個のテキストカードをDnDで並べ替えができる(最大枚数は今後増える
  • 並べ替えは複数人同時に操作ができる
  • 更新頻度は高め(1日に数回は行う)
  • 文字数は100文字まで(ここはそんなに重要ではない)

image.png

私は上記機能のDB設計とバックエンドの実装を担当することになりました。

私「こんなん余裕やん!」

DB設計 ver1

テキストカードの情報を保存するためのテーブルをまずは設計してみました

cardsテーブル

カラム名 データ型
id unsigned int
text varchar(100)
order_index int

id, textを持ったレコードにorder_indexに0~4の値を持たせて、order byすれば順序も保存できるやないか!
と、思っていましたがアウトでした。

何がダメだったのか

order_indexを0~4の値にしてしまったことです。
この状態で末尾のCard5を先頭に持ってくると
Card5: order_index 4→0 にUpdate
Card1: order_index 0→1 にUpdate
Card2: order_index 1→2 にUpdate
Card3: order_index 2→3 にUpdate
Card4: order_index 3→4 にUpdate

と全てのカードをUpdateしなくてはなりません。

image.png

複数人が高頻度で並べ替えを行うので毎回毎回複数レコードの更新が走るのは設計上良くないです(下手するとデッドロックが起きるかも)

先人を調査

では順序(order_index)をどう持ったらいいのか?
DnDでアイテムを並び替えるシステムを思い浮かべたとき、カンバン形式のタスク管理システムが真っ先に思い浮かびました。
そこで、trelloさんのタスク管理ボードを調査した結果、順序はposというプロパティをfloatで持っていました。なるほど〜!!

DB設計 ver2

cardsテーブル

カラム名 データ型
id unsigned int
text varchar(100)
pos float

posについては、0~4ではなく、1024〜5120で値を持たせるようにしました。
Card間のposに一定の数値間隔を空けることでUpdateコストを下げることができます。

  1. 末尾のカード(Card5)を3番目に移動
  2. 元々2番目(Card2)と3番目(Card3)のposの平均値を計算
  3. Card5のposを2.の平均値に設定

こうすることで更新するのはCard5のposのみになりました!🎉

image.png

ただし、平均値を取り続けるといつか隣のカードとposの値が同値になってしまうので、その時は1024などの数値で再採番してあげれば問題なしです!(これが面倒なのですが

終わりに

複数人同時&高頻度でなければver1の設計でも問題ないかと思いますが、DBやロジックを考える際は更新コストも考えないと。。。と学ぶ良い機会になりました💦
最後まで読んでいただきありがとうございました!

参考

こちらに他の手法含めて色々解説されていました!(感謝🙌

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?