• 締切済み

ユーザーが画面上からDB上のデータの並び替えをする際、効率的な実装方法は?

EC サイトを構築しており、 店舗管理者が商品の並びを自由に替えるようにしたいです。 例えば、以下のようなテーブルが DB 内にあるとします。 +---+-------+ |ID | name | +---+-------+ | 1 | 商品1 | | 2 | 商品2 | | 3 | 商品3 | | 4 | 商品4 | | 5 | 商品5 | +---+-------+ ユーザーが 商品1 - 商品4 - 商品2 - 商品3 - 商品5 という順で並べ替えを行う機能を実装するには 以下の 2 つの方法が考えられます。 【方法1】 rank というカラムを追加して +---+-------+------+  +---+-------+------+ |ID | name | rank |  |ID | name | rank | +---+-------+------+  +---+-------+------+ | 1 | 商品1 |  1 |  | 1 | 商品1 |  1 | | 2 | 商品2 |  2 | => | 2 | 商品2 |  3 | | 3 | 商品3 |  3 |  | 3 | 商品3 |  4 | | 4 | 商品4 |  4 |  | 4 | 商品4 |  2 | | 5 | 商品5 |  5 |  | 5 | 商品5 |  5 | +---+-------+------+  +---+-------+------+ と rank を更新し、rank の昇順で表示させる 【方法2】 next_id というカラムを追加して +---+-------+---------+  +---+-------+---------+ |ID | name | next_Id |  |ID | name | next_id | +---+-------+---------+  +---+-------+---------+ | 1 | 商品1 |    2 |  | 1 | 商品1 |    4 | | 2 | 商品2 |    3 | => | 2 | 商品2 |    3 | | 3 | 商品3 |    4 |  | 3 | 商品3 |    5 | | 4 | 商品4 |    5 |  | 4 | 商品4 |    2 | | 5 | 商品5 |     |  | 5 | 商品5 |     | +---+-------+---------+  +---+-------+---------+ と next_id を更新し、 ID と next_id を交互に見ながら画面に並べる 【方法2】では、どんなにデータ数が多くなっても 3 レコードだけ更新すれば済みますが 【方法1】だと、データ数が多くなれば かなりの数のレコードを更新する必要があります。 ところが、 【方法1】だと SQL の order by rank でソートできるのに対し、 【方法2】だと全データを取得してからプログラムで並べ替えを行わなくてはならない と思います。 そこで、【方法2】を使い、かつ SQL で簡単に取得できる方法はないか探しています。 【方法2】で、素直にプログラムで並べ替えればいいという意見もあるかと思いますが ページ送りのある一覧画面で並べ替えもさせたいと思っており、 DB 側でで並べ替えられたデータを limit で 1 画面に表示する件数分だけ取得する ということを行いたいのです。 もし、うまい方法があれば宜しくお願い致します。 DB は MySQL を使っていますが、他の DB にすることも可能で、 バージョンも問いません。

みんなの回答

noname#259269
noname#259269
回答No.1

方法2はどう考えても、NGだと思うのですが。。。素直に方法1を取るべきです。 ■理由 ・SQL の order by だけで利用できる列と、プログラムを介在させないと利用できない列があった場合、前者の方が「データ」としての価値が高い(活用度が高い)。言い換えるとデータベースに格納しているデータなのに扱いが煩雑であることはマイナス。 ・一度に並び替える個数が多くなった場合、方法2でも修正するデータ量が増えていく。つまり方法2としてのメリットが薄れる。

Perler
質問者

お礼

回答ありがとうございます。 もしかしたらエレガントなロジックが存在するのかなと思ったりもしたのですが、やっぱり素直に必要な数だけ更新する方がよさそうですね。 更新よりも参照の方が圧倒的にトラフィックは多いわけですし。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PHPのPEAR:DBでPostgreSQLを使用時、カラム名でデータが取得できない

    PHPのPEAR::DBのサンプルを公開しているサイトから以下のソースを引っ張ってきて、試してみました。すると、少しおかしな現象が発生したので、ご質問させていただきます。 ------------------------------ $dsn = "pgsql://postgres:pass@localhost/postgres"; $db = DB::connect($dsn); if (PEAR::isError($db)) { die($db->getMessage()); } print('接続に成功しました<br>'); $sql = 'select * from "USER_TBL"'; $res =& $db->query($sql); if (PEAR::isError($res)) { die($res->getMessage()); } while ($row =& $res->fetchRow()) { print($row['ID']); print($row['NAME'].'<br>'); } ------------------------------ 接続は問題なかったのですが、データベースからデータを取得する「print($row['ID']);」の部分が動かず、<br>だけ出力されてしまいます。IDのカラム名をダブルクォーテーションで囲っても、値が出てきません。ところが、print($row[0]);などのように、数値を指定してやると、その部分が出力されます。 また、カラム名を小文字に変えてみたりもしましたが、やはりそれでもデータは取得できませんでした。 理由がよく判らないのですが、カラム名でデータを引っ張ってきたいと思います。解決方法はありませんでしょうか?

    • ベストアンサー
    • PHP
  • java strust 動的にDBのデータをJSP画面で表示する 方法

    --エラー内容 致命的: サーブレット action のServlet.service()が例外を投げました javax.servlet.jsp.JspException: Bean array のプロパティ dBBookTitle に対するゲッターメソッドがありません --JSPソース-- <logic:notEmpty property="bookId" name="RETURNSCREEN"> <logic:iterate id="array" name="RETURNSCREEN" property="bookId" > <bean:write name="array" property="dBBookId"/> </logic:iterate> </logic:notEmpty> --Javaアクション-- ReturnScreenForm rsf = ( ReturnScreenForm ) form ; ReturnScreenFormDB rsfd = new ReturnScreenFormDB( ) ; // = ( ReturnScreenFormDB ) form ; //ArrayListクラスは大きさが決まっていない配列となる,その為動的にオブジェクト配列を宣言できる ArrayList<ReturnScreenFormDB> array = new ArrayList<ReturnScreenFormDB>( ) ; //DB接続処理の呼び出し DatabaseAccess.Open( ); rs = DatabaseAccess.executeQueryMethod( SQL_CODE ) ; String stmember_id ; //DBデータ(member_id )取得して格納する受け皿 String ststatus ; //DBデータ(status )を取得して格納する受け皿 String stbook_id ; //DBデータ(book_id )を取得して格納する受け皿 String stbook_title ; //DBデータ(book_title )を取得して格納する受け皿 int flg_Retrieval = 0 ; int CountNo = 0; //検索された行数文ループ while( rs.next( ) ) { flg_Retrieval = 1 ; stmember_id = rs.getString("member_id"); //DBのmember_idを格納 ststatus = rs.getString("status"); //DBのmember_idを格納 stbook_id = rs.getString("book_id"); //DBのmember_family_nameを格納 stbook_title = rs.getString("book_title"); //DBのmember_family_name_kanaを格納 //セッターに取得データをセットする rsfd.setDBBookId( stbook_id ) ; rsfd.setDBBookTitle( stbook_title) ; array.add( rsfd ); rsf.setBookId( array ); } //END while( rs.next( ) ) --JSP画面Bean-- private String memberId; // ="0003"; //会員ID private ArrayList<ReturnScreenFormDB> bookId; // ="0041"; //本ID private ArrayList<ReturnScreenForm> bookTitle; // = "御徒町"; //本タイトル //セット本ID public void setBookId( ArrayList<ReturnScreenFormDB> array ) { this.bookId = array ; } //ゲット本ID public ArrayList<ReturnScreenFormDB> getBookId( ) { return this.bookId ; } //セット本タイトル public void setBookTitle( ArrayList<ReturnScreenForm> bookTitle ) { this.bookTitle = bookTitle ; } //ゲット本タイトル public ArrayList<ReturnScreenForm> getBookTitle( ) { return bookTitle ; } //セット会員ID public String getMemberId( ) { return memberId ; } //ゲット会員ID public void setMemberId( String memberId ) { this.memberId = memberId; } --JSPDBBean-- private String dbbookTitle; // = "御徒町"; //DB本タイトル private String dbbookId; // ="0041"; //DB本ID //セット本タイトル public void setDBBookTitle( String dbbookTitle ) { this.dbbookTitle = dbbookTitle ; } //ゲット本タイトル public String getDBBookTitle( ) { return this.dbbookTitle ; } //セット本ID public void setDBBookId( String dbbookId ) { this.dbbookId = dbbookId ; } //ゲット本ID public String getDBBookId( ) { return this.dbbookId ; } --struts-config.xml-- <form-beans> <form-bean name="RETURNSCREEN" type="rentalPackage.ReturnScreenForm"> </form-bean> </form-beans> <action path="/Return" type="rentalPackage.ReturnScreenAction" name="RETURNSCREEN" scope="request" parameter="submitPropertyReturnScreen" validate="false"> <forward name="successReturnScreen" path="/ReturnScreen.jsp"/> </action> --質問-- JSPの画面表示はできました。 しかし、番号を入力後検索をDBにかけると エラーが出力されます。Beanのプロパティに対するゲッターエラーと感じています。 大変申し訳ありませんが本当に助けてほしいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 異なるサーバのDBデータ同士を結合するには?

    全く違うサーバに載っているDBのデータ同士を結合するいい手段はないでしょうか? DBは両者ともOracleですが9と10という違いがあります。 SERVER1に載っているDBは商品管理のためのものです。主キーは「品ID」です。 SVR2に載っているDBは、保証期間の管理をするためのものです。主キーは「品ID&メーカーID」です。 唯一データのつながりを作れそうなのは両者の主キーのみです。 あとのデータには何にもつながりはありません。 どちらかのサーバに片方のDBのテーブルを作るとかビューを作ればいいかと思いましたが、その方法についてはNGとされています。 (とりあえずその方法でやる場合できますでしょうか???) DBに何かを作ることなくデータの結合をさせれないでしょうか? SQLplusなりSQLクリエイトツールなりどんな方法でもDB自体汚さない限り問題はありません。

  • データの取得方法

    失礼いたします。 SQL文でDBからデータを取得して、それを 表示したいのですがうまくいきません。 どこを間違っているか、どうしたらいいか コメントお願いします。 //他のページからIDを取得 <?php $aid=htmlspecialchars($_GET["id"]); ?> //SQL <?php $sql = "SELECT A.USERID,A.NAME,B.BIL_ID,B.B.BIL_NAME FROM USER A,BIL B WHERE A.BIL_ID=B.BIL_ID AND USER_ID=".intval($_GET["aid"]); !$an = mysql_query($sql,$db) $user = mysql_fetch_row($an); mysql_free_result($an); ?> //データの表示 //SQLで実行した'BIL_ID'を表示したい。 <TD><INPUT type="text" name="bid" value="<?php print(intval($_GET["$user[2]"])) ?>"></TD>

    • ベストアンサー
    • PHP
  • データの並び替え

    こんにちは。 AccessVBAでつまづいてしまったので、ご教授お願いします。 以下にプログラムの動作手順を書きます。 1、CDに入っている4つのCSVファイルをそれぞれ別のテーブルにインポート。 2、その4つのテーブルのデータをグループ化して「wkマスタ」に追加クエリを利用して追加。 3、全て追加されたら、商品ID の昇順で「wkマスタ」のレコードを並び替え。 3の並び替えを下のように書きました。 DoCmd.RunSQL "SELECT 商品ID,商品名称カナ,商品名称漢字 FROM wkマスタ ORDER BY 商品ID ASC;" そしたら「"RunSQL/SQLの実行"アクションを実行するには、 SQLステートメントからなる引数を指定する必要があります」 と注意されました。 これはどういう意味でしょうか?またどうしたら問題なく並べ替えできますか?教えてください。

  • 【エクセルVBA】DBのデータをCSVに

    VBA初級者です。 oracleDBのデータをCSVへ出力するマクロをVBAで作成中ですが、実装方法が分からず困っています。 ・DB接続はoo4o ・エクセルは2010 ・SQLで取得したデータを1レコードづつCSVに書き出したい ・カラム名をヘッダーとして書き出したい 以下のような実現方法でできるか…?と考えたものの、 肝心のマクロ(VBA)でのDBデータの取得⇒CSVへの書き込み方法がいくら調べてもわかりません。 CSVからDBへのインポートはたくさんあったのですが…。 そもそも取得したレコードを配列で保持して書き出す、という考え方が合っているのか?ヘッダー(カラム名)はどのように書き出せばいいか? など疑問が尽きません。何卒お力添え頂ければ幸いです。 --ボタンクリック時のアクション-- (1)変数定義 (2)DB接続情報確認 (3)DB接続 'DB接続 Set oraSession = CreateObject("OracleInProcServer.XOraSession") Set oraDatabase = oraSession.OpenDatabase(dbSid, dbUser & "/" & dbPass, ORADB_DEFAULT) (4)書き込み用のCSVファイルを作る (5)SQLを実行し返ってきた結果をsplit関数で配列としてwriteListにAddする (5)作成したCSVファイル内にwriteListのデータをPrint #で書き出す (6)完了メッセージを表示 MsgBox "完了しました " (7)DBの切断 'DBクローズ Set oraDatabase = Nothing Set oraSession = Nothing --SQLを実行するメソッド-- (8)SQLを記述、SELECT結果を(5)に返す 恐れ入りますがよろしくお願いいたします。

  • データの取得方法

    Aテーブル{ id char(3) not null, name varchar(10), a_no char(5), b_no char(5), c_no char(5), date timestamp } Bマスタ{ no char(5), name char(10) } 上記のようなDBがあるのですがAテーブルのa_no、b_no、c_noに入るのはBマスタのnoになります。 下記のようにデータを取得したい場合、どうすればうまく取得できるのでしょうか。 A.id, A.name, A.a_no, カラム名をname1としてB.name, b_no, カラム名をname2としてB.name, c_no, カラム名をname3としてB.name そんなに難しいことではないと思うのですが、考えれば考えるだけ頭の中でこんがらがってきて困っています。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • MySQLでvarchar型のデータの最大値を取得する方法

    お世話になります。 どなたかご回答&アドバイスをよろしくお願い致します。 MySQLで、以下のように登録されているデータがあるとします。 ID(varchar) | name(varchar) 0000001 | ああああ 0000002 | いいいい 0000004 | ううううう それで、登録されているIDの最大値+1を取得したいのです。 IDのカラムのデータ型がIntならmaxで取得できると思うのですが、データ型がvarcharなので…。 レコードの数+1というのは、IDが必ずしも1から飛びがなく登録されているとは限らないので、 その方法は危ないのでできません。 上の例だと、「0000005」を取得したいです。 どうぞご教授お願い致します。

    • ベストアンサー
    • PHP
  • MySQLに評価の集計をしている場合CSVでの更新

    例としまして、下記のようなテーブルがあるとします。 ┼─┼───┼──┼────┼ │ID│NAME│KAZU│HYOUKA│ ┼─┼───┼──┼────┼ │0 │アイドル│30 │1500   │ ┼─┼───┼──┼────┼ │1 │アクター│15 │2000   │ ┼─┼───┼──┼────┼ │2 │オペラ│5  │4000  │ ┼─┼───┼──┼────┼ カラム:ID・NAME・KAZU のデータは、更新の際、CSVでインポートを考えています。 カラム・HYOUKA は、外部からクリックで評価してもらった数を集計しようと考えています。 データのみのDB、評価の集計のみのDBはできるのですが、 これを両方兼ねたデータベースを作ってPHPで表示し、更新があったらCSVでインポートした場合、 「HYOUKA」の数をそのままでということは可能なのでしょうか。 こういった場合、テーブルを別に作って…など、上記とは違った方法を取るのが正しいのでしょうか。

    • ベストアンサー
    • MySQL
  • 画面上のデータをDBに更新する時に楽な方法は

    .Netの開発で、画面の値をDBに更新する場合、 INSERT(UPDATE)のSQLの構文を作成して実行しているのですが、 画面の場合はアダプタを使って、SQLの生成から任せてしまった方が楽なんじゃないかと思ってます 何度か自分でそういったものを作って試したこともあるのですが、 自分が作成する以外で、そのような作り方をしているシステムに出会ったことが無く、どれもコツコツとSQLを書いているものばかりです Delphiなどで慣れているのもあってか、とても面倒に感じています もう少し楽な書き方を実践されている方は、いますでしょうか?