※ 引述《gpmm (銀色)》之銘言:
: 如果講相片排序會覺得規模較小的話,可以考慮看看以下的情境,
: .一個每日有一萬人瀏覽的網站
: .網站的管理後台提供了一個檔案管理的系統,在全覽模式下,
: 可分頁瀏覽和排序所有的 PDF 電子書檔案和 DOC 文件檔。
相片、檔案兩者的排序情境有些差異
相片排列可以有故事性、時間性、(縮圖)設計感、層次與主題,
因此我可能要排很久、很多次,才會有滿意的結果,甚至最後排
出來不滿意.或只是好玩,按下「取消」。我認為這種情況適合
「延後處理」:最後階段再一次性的批次處理,也就是說,最後
一次送n個。
檔案排列就比較死、沒有感情,我就是要檔案怎麼排,比較合「
邏輯」。我認為這種情況適合「即時處理」:使用者每移動一個
檔案就馬上處理,整個操作過程中多次性的單次處理,也就是說
,一次送一個,共送n次。
: 以小弟有見過的排序用資料庫結構大概就幾種,
: 一般排序(就是前篇講到的 order 1 2 3 4 5),
: 表記排序(專門開一個 table 的欄位來儲存排序),例如
: user-id order-target order-content
: ------------------------------------
: 1 pdf-file 1,3,7,9,44,2,3
: 表示使用者編號為 1 的 pdf 檔案共有 7 筆,
: 7 筆資料的 pk 依序為 1,3,7,9,44,2,3
: 表記法乍看之下好像很好用,但其實很多地方會撞壁(不很實用)
表記排序不符合第一正規化 不過這方法有時候很好用
它等於是把原本要給db處理的事情 轉價給程式處理
: : a.移動單筆時
: id order
: ---------
: x 1
: y 2
: z 3
: 此處的 SQL 都先以一般排序法來說:
: .將單筆資料刪除 SQL 數量 2 ,異動筆數 1 + 2
: DELETE FROM `Files` WHERE `id`='x'
: UPDATE `Files` SET `order`=`order`-1 WHERE `order`>1
: 上面這邊列出一般常見可排序資料的操作,
: 有興趣的可以算算看用夾擊法和表記法所消耗的 SQL 數量、異動筆數
: 其實重點不在於 connection,而是在於 DB SQL 的數量(當然建連線也耗時沒錯)
connection重要在於connection數是有限的(看RAM, CPU有多大)
被拿光了後面晚到的是要排隊拿的(等前面的free掉)
當然你說連線建立,做點事,馬上就free,秒殺。…我想規模大的系統是有差的。
此外,連線建立、關閉既費時也耗資源;這點可用連線池改善,避免多次開關。
(php可用persistent connection)
sql數會影響,但影響比較大的應該是該sql指令所涉及的資料筆數,
例如 WHERE `order`>1
這語法要掃過整個table(可能很大,萬筆以上) 再篩選出符合的筆數
相較之下 WHERE `order`=2 的效率就會高很多
: 畢竟連線只要不刻意 free 掉,同一隻 php 是可以從頭用到尾的,
用同一個連線比較省:P
省還要更省 讀取db次數最好介於0~1次
寫入db應該也盡量不超過1次 (善用外鍵FK 可一次寫入多個table)
: 另外在寫 code 時,小弟一般都是不信任前端,
: 不僅僅是為了 injection,同時也是避免暴露過多的 URL 變數操作,
: 所以鮮少會用到像前端指定移動位置這種…
這確實該考量 不過用session就可以知道使用者是誰 及限制他能做的動作
我是覺得多用前端 後端可以少一次query 不無小補XD
: 您可以提看看什麼情況下 connection 會不易控制,說不定是我沒搞清楚…
: 但一般來說有幾種常見的設計模式都有利於處理 connection
: 這已經完全可以另開一篇來討論了 XDD
如我開頭所說 多次(連線)單筆(sql指令) 與單次多筆 的差別
: 這邊您點到了另一個重點,也就是一開始所提到的「門檻」,
: 以小弟的經驗,在覆載較大的系統上,往往最需要避免的都是 SQL 的數量,
: 一道 SQL 命令永遠比兩道好,兩道 SQL 能處理的永遠比 10 道好,
同上 原則上如此 但還是要看該sql影響的範圍、複不複雜
: 再來則是從結構上考慮,怎麼樣的結構可以以最少的異動量,達到相同的目的,
沒錯!
我想到一個方法 只是個概念 還不確定可不可行:
除了原order外 多一個change
order都固定存初始的位置 change則是存改變的值,如+1, -1, +99
新增一個view 計算、儲存新的order
原table: view:
id order change id neworder
------------------ ------------
a 1 f 1
b 2 +5 (底) a 2
c 3 b 3
d 4 e 4
e 5 -1 (上移) d 5
f 6 -5 (頂) b 6
都只query view,更新都只更新原table的change欄位一次(一個sql指令),
例如往上移一格:
update files set change = change -1 where id = 'e' limit 1;
置底:
update files set change = change +5 where id = 'b' limit 1;
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.122.76.198