社交閱讀平台中,「我的書架」功能需支援使用者自建書架、書籍分類管理、拖曳排序等複雜互動。本文詳細解析基於MySQL的書架系統資料庫設計與核心操作邏輯。
採用序列化陣列儲存於單一text欄位,結構如下:
CREATE TABLE bookshelf (
uid INT(11),
shelf TEXT
);
shelf欄位儲存PHP序列化後的二維陣列:Key為書架名稱,Value為20位置的字串(如0-0-5-12-0...),0表示空位,非0為書籍ID。
$arr = array('預設書架' => '0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0');
$text = serialize($arr);
INSERT INTO bookshelf (uid, shelf) VALUES ('$uid', '$text');
$shelfs = SELECT shelf FROM bookshelf WHERE uid = '$uid';
$a = unserialize($shelfs);
foreach ($a as $key => $val) {
if ($key == $new_shelf_name) return '書架已存在';
}
if (count($a) >= 10) return '超過最大書架數';
// 新增空書架陣列...
$pk = explode('-', $shelf_data);
$book_count = 0;
$has_book = false;
$empty_pos = -1;
for ($i = 0; $i < count($pk); $i++) {
if ($pk[$i] != 0) {
$book_count++;
if ($pk[$i] == $book_id) $has_book = true;
} elseif ($empty_pos == -1) $empty_pos = $i;
}
if ($has_book) return '書架已有此書';
if ($book_count >= 20) return '書架已滿';
$pk[$empty_pos] = $book_id;
UPDATE bookshelf SET shelf = '$new_serialized' WHERE uid = '$uid';
$start = 2; $end = 8; // 位置索引
if ($start < 0 || $start > 20 || $end < 0 || $end > 20 || $start == $end) exit;
$temp = $array[$start];
$array[$start] = $array[$end];
$array[$end] = $temp;
UPDATE bookshelf SET shelf = '$updated' WHERE uid = '$uid';
$arr = array();
foreach ($shelves as $name => $data) {
$count = 0;
foreach (explode('-', $data) as $book_id) {
if ($book_id != 0) $count++;
}
$arr[$name] = $count;
}
序列化儲存雖簡化表結構,但存在查詢效能差、無法利用索引、並發控制困難等缺點。生產環境建議採用正規化設計:
shelves表:id, uid, name, sort_ordershelf_books表:id, shelf_id, book_id, position, added_time並透過觸發器或應用層邏輯維護位置唯一性與順序完整性。