2009-08-23 8 views
4

내 웹 앱의 각 사용자에 대해 n 관련 위젯이 있습니다. 각 위젯은 위젯 테이블의 데이터베이스에 표시됩니다. 사용자는 자신의 위젯을 정렬 할 수 있으며, 12 개 이상의 위젯을 가질 수 없으며 종종 위젯을 정렬합니다.사용자 정렬 가능 레코드

고유 한 순서가있는 데이터베이스 항목을 자주 다루지 않았습니다. 주문하기에 적합한 전략은 무엇입니까? 처음에는 간단한 "sortIndex"열이 잘 작동한다고 생각했지만이 값을 초기화하는 방법에 대해 궁금해하기 시작했습니다. 그것은 아마도 고유 한 값이어야하며, 다른 모든 정렬 색인보다 크거나 작아야합니다. 새로운 위젯을 만들 때마다 그 사용자의 다른 정렬 색인을 모두 확인하지 않아도됩니다. 그건 불필요한 것 같습니다.

아마도 "기본 우선 순위"정렬 색인을 가질 수 있습니까? 그렇다면 어떻게 구별 할 수 있습니까? 나는 창조 날짜 플래그를 사용할 수 있다고 가정하지만, 사용자가 그 최하위 우선 위젯 모두의 중간에 위젯을 삽입하고 싶다면 어떻게해야할까요?

이런 종류의 문제를 처리하는 표준 방법은 무엇입니까?

답변

3

사용자가 편집 가능한 정렬을위한 가장 좋은 방법은 linked listid 년대를 유지하는 것입니다 :

user_id widget_id prev_widget_id 
    ----  ----   ---- 
     1   1    0 
     1   2    8 
     1   3    7 
     1   7    1 
     1   8    3 
     2   3    0 
     2   2    3 

이이 순서로 user 1에 대한 5 위젯을 만들 것입니다 : 1, 7, 3, 8, 2; 이 순서에 user 2에 대한 2 위젯 : 3, 2

당신은 (user_id, widget_id)(user_id, prev_widget_id)UNIQUE 인덱스를해야한다.

의도 한 순서대로 위젯을 얻으려면, 당신은 Oracle에서 말하자면, 다음과 같이 조회 할 수 있습니다

SELECT w.* 
FROM (
     SELECT widget_id, level AS widget_order 
     FROM widget_orders 
     START WITH 
       user_id = :myuser 
       AND prev_widget_id = 0 
     CONNECT BY 
       user_id = PRIOR user_id 
       AND prev_widget_id = PRIOR widget_id 
     ) o 
JOIN widgets w 
ON  w.widget_id = o.widget_id 
ORDER BY 
     widget_order 

이 순서를 업데이트하려면, 당신은 대부분의 3 행에 업데이트해야합니다 (당신이 전체를 이동하는 경우에도 위젯 블록).

SQL ServerPostgreSQL 8.4 재귀 CTE의를 사용하여이 기능을 구현 :

:

WITH  
-- RECURSIVE 
-- uncomment the previous line in PostgreSQL 
     q AS 
     (
     SELECT widget_id, prev_widget_id, 1 AS widget_order 
     FROM widget_orders 
     WHERE user_id = @user_id 
     UNION ALL 
     SELECT wo.widget_id, wo.prev_widget_id, q.widget_order + 1 
     FROM q 
     JOIN wo.widget_orders wo 
     ON  wo.user_id = @user_id 
       AND wo.prev_widget_id = q.widget_id 
     ) 
SELECT w.* 
FROM q 
JOIN widgets w 
ON  w.widget_id = q.widget_id 
ORDER BY 
     widget_order 

MySQL에서이 기능을 구현하는 방법에 내 블로그에서이 문서를 참조하십시오

4

당신이 자신의 개인적인 취향에 대한 위젯을 정렬 사용자가있는 경우, 당신과 같이, 조회 테이블을 만들려면 :

select 
    w.* 
from 
    widgets w 
    inner join widgets_sorting s on 
     w.WidgetID = s.WidgetID 
    inner join users u on 
     s.UserID = u.UserID 
order by 
    s.SortIndex asc 

이를 :

create table widgets_sorting 
(
    SortID int primary key, 
    UserID int, 
    WidgetID int, 
    SortIndex int 
) 

그런 다음, 사용자의 위젯을 정렬 새로운 사용자를 위해해야 ​​할 일은 테이블에 새 행을 추가하는 것입니다. WidgetID 및 UserID 열 모두에 외래 키 제약 조건과 인덱스를 넣었는지 확인하십시오.

이러한 조회 테이블은 이러한 맞춤형 목록과 공통적 인 다 대다 관계를 실제로 해결하는 가장 좋은 방법입니다. 바라기를 이것은 바라는 방향으로 당신을 지시한다!

1

두 테이블 접근법을 사용하고 싶습니다. 다소 혼란 스럽지만 ActiveRecord와 같은 ORM을 사용하면 쉽고, 똑똑한 코드를 작성하여 관리 할 수 ​​있습니다.

하나의 표를 사용하여 사용자를 정렬에 연결하고, 하나의 표를 사용하여 위젯과 위치를 연결하고 정렬합니다. 이 방법을 통해 훨씬 더 명확한 작업을 수행 할 수 있으며 SQL 조인 또는 별도의 쿼리를 사용하여 다양한 테이블의 다양한 데이터를 가져올 수 있습니다. 귀하의 구조는 다음과 같아야합니다

//Standard user + widgets table, make sure they both have unique IDs 
CREATE TABLE users; 
CREATE TABLE widgets; 

//The sorting tables 
CREATE TABLE sortings (
    id INT, //autoincrement etc, 
    user_id INT 
) 

CREATE TABLE sorting_positions (
    sorting_id INT, 
    widget_id INT, 
    position INT 
) 

는 희망이 당신은 여전히 ​​혼란스러워하는 경우,이 메시지에 대한 의견과 나는 몇 가지 기본적인 코드를 당신을 쓸 것이다, 의미가 있습니다. 제이미

1

각 사용자가 위젯에 자신의 정렬 순서를 할당하는 것을 의미하는 경우

후 에릭의 대답은 올바른 것입니다. 아마도 사용자는 정렬 값을 할당하는 방법을 사용자에게 제공해야 할 것입니다. 그러나 만약 당신이 말한대로 그 숫자가 적당하다면, 당신은 그에게 모든 위젯들을 나열한 스크린을 줄 수 있고, 주문 번호를 타이핑하게하거나, 순서대로 표시하고, 당신 옆에있는 버튼들을 위아래로 표시 할 수 있습니다. 공상에 들고 싶고, 끌어다 놓을 수있는 방법을 제공하십시오.

모든 사용자가 주문이 동일하면 질문은 '이 주문은 어디에서 제공됩니까?'가됩니다. 임의적 인 경우 새 위젯이 생성 될 때 시퀀스 번호를 지정하십시오.

관련 문제