- PR -

レコードの表示順序をカスタマイズするには

投稿者投稿内容
nikori
会議室デビュー日: 2008/03/13
投稿数: 11
投稿日時: 2008-03-13 03:15
はじめまして。
現在、Webアプリケーションの作成について勉強しています。


次のようなBOOKMARKテーブルを作成しました(HSQLDB)。
一覧を表示する時にレコードの表示順序をカスタマイズできるように
DISPLAY_ORDERカラム(表示する順番に1から振っていく)を設けました。

コード:
CREATE TABLE BOOKMARK (
  ID bigint generated by default as identity (start with 1),
  URL varchar(256) not null,
  LABEL varchar(64) not null,
  DISPLAY_ORDER integer not null, 
  primary key(ID)
);



コード:
【一覧取得時のSQL】
select
  *
from
  BOOKMARK
order by
  DISPLAY_ORDER
;

【取得したレコードのイメージ】
(ID, URL, LABEL, DISPLAY_ORDER) =
(5, 'eee.co.jp', 'eee', 1), 
(3, 'ccc.co.jp', 'ccc', 2), 
(2, 'bbb.co.jp', 'bbb', 3), 
(4, 'ddd.co.jp', 'ddd', 4), 
(1, 'aaa.co.jp', 'aaa', 5), 



ただ、上記のようにレコードが登録されていて、
ID=1のレコードを5番目から2番目に表示するように変更する場合、
4回のupdate文が必要になります。
レコード数が多くなると、その分updateの回数も多くなるケースが出てくるのですが、
これは仕方がないことなのでしょうか?
それとも、テーブル設計がおかしいのでしょうか?

初歩的な質問で申し訳ありませんが、教えてください。
よろしくお願いします。
m.m.
常連さん
会議室デビュー日: 2003/04/22
投稿数: 20
投稿日時: 2008-03-13 08:36
DISPLAY_ORDERの値を3桁くらいにしてみるとかはどうですかね。

コード:
(5, 'eee.co.jp', 'eee', 100), 
(3, 'ccc.co.jp', 'ccc', 200), 
(2, 'bbb.co.jp', 'bbb', 300), 
(4, 'ddd.co.jp', 'ddd', 400), 
(1, 'aaa.co.jp', 'aaa', 500)

UPDATE BOOKMARK SET DISPLAY_ORDER=150 WHERE ID=1

(5, 'eee.co.jp', 'eee', 100), 
(1, 'aaa.co.jp', 'aaa', 150),
(3, 'ccc.co.jp', 'ccc', 200), 
(2, 'bbb.co.jp', 'bbb', 300), 
(4, 'ddd.co.jp', 'ddd', 400), 



#昔のBASICでは、ステートメント行を挿入するのにこういう事をやりましたね。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-03-13 09:49
引用:

nikoriさんの書き込み (2008-03-13 03:15) より:
レコード数が多くなると、その分updateの回数も多くなるケースが出てくるのですが、
これは仕方がないことなのでしょうか?
それとも、テーブル設計がおかしいのでしょうか?


これ自体は仕方がないことであり、テーブル設計は間違っていないと思います。

ただ、アプリケーションにおいて、列の表示順序の制御は良くやりますが、レコードの表示順序を制御するためにそれ用の列を設けるという設計は、それほど頻繁にはやらないと思います。
普通は、ソート列を指定することでおこなうことが多いでしょう。すなわち、提示された例だと URL, LABEL 列でソートします。

なお DISPLAY_ORDER 列のようなものを使いたいと思う場合、レコードをあたかも列として使っている可能性もあります。データーベースの構造を見ないと一概に言えませんが。

まず、レコードの表示順序を制御したいという要求仕様がどこから出てきたのか(アプリケーションの仕組みでおのずと必要なのか、それとも、口うるさいお客さんが言っているのか、など)、を再検討されたほうが良いと思います。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-03-13 09:56
引用:

unibonさんの書き込み (2008-03-13 09:49) より:
引用:

nikoriさんの書き込み (2008-03-13 03:15) より:
レコード数が多くなると、その分updateの回数も多くなるケースが出てくるのですが、
これは仕方がないことなのでしょうか?
それとも、テーブル設計がおかしいのでしょうか?


これ自体は仕方がないことであり、テーブル設計は間違っていないと思います。


もちろん、実装のしかたはいろいろあり、たとえばリンクリスト方式で管理する方法も考えられます。たとえば DISPLAY_ORDER 列をなくして、代わりに BEFORE_ID および AFTER_ID 列で順序を制御するなどが考えられます。ソートのテクニックにバリエーションがあるのと同じことです。(ただし RDB に入れるデーターである以上、オンメモリーのようには使えないでしょう。)
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2008-03-13 09:56
DISPLAY_ORDERの代わりに
コード:
  PREVIOUS_ID bigint references BOOKMARK(ID)


みたいな列にして、Linked Listっぽくすればいい? とかふと思いましたが、ORDER BYが使えなくなりますね・・・。(ちなみにHSQLDBが外部キー制約をサポートしているかどうかは知りません)
アプリケーション側でどうにかできるのなら、それでもいいんでしょうけど。

でも、関連する全レコードUPDATEでもいいんじゃないでしょうか。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-03-13 10:06
引用:

unibonさんの書き込み (2008-03-13 09:49) より:

ただ、アプリケーションにおいて、列の表示順序の制御は良くやりますが、レコードの表示順序を制御するためにそれ用の列を設けるという設計は、それほど頻繁にはやらないと思います。



マスタメンテではそれなりに使っています。
リストで項目を選ぶときに、よく使うものは上に出るようにしたいといった要望がありまして。

# 表示順で999を入れると選択肢から出なくしてくれ、といった要望も過去あったのは余談
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-03-13 10:28
引用:

nikoriさんの書き込み (2008-03-13 03:15) より:
ただ、上記のようにレコードが登録されていて、
ID=1のレコードを5番目から2番目に表示するように変更する場合、
4回のupdate文が必要になります。


この点についてだけ書きますが、
UPDATE BOOKMARK SET DISPLAY_ORDER = DISPLAY_ORDER + 1 WHERE DISPLAY_ORDER >= 2
UPDATE BOOKMARK SET DISPLAY_ORDER = 2 WHERE DISPLAY_ORDER = 6
のようにして複数レコードを一括更新することで、UPDATE 文をレコード数にかかわらず常に2回で済ませられるような妄想も頭の中をよぎったのですが、こういうことってできるのでしょうかね?
もっとも、たとえできたとしても、DBMS の仕様に踊らされそうであんまりやりたくないような気もします。
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-03-13 10:37
件数と頻度の問題もあるので、少なければ
Updateでもいいのでは。。。。
(マスタメンテナンス毎日するわけでもないし?)

  unibonさん・カーニーさんと同じですが
    件数が多ければリンクリストにすればよいと思います。
    但し、表示の時は工夫が入りますね。
    (OnMemoryで並び替え、更新を考えれば片方向リンクがよいのでは?)

-------------------------------------------------------------
私ならUpdateで、おそらくトランザクション系は動作していないと
思われるので5秒もあれば通常数千件はUpdateできますよ。
(DisplayOrderを変更したらを条件に入れたらBetter)

スキルアップ/キャリアアップ(JOB@IT)