2008-09-19 2 views
0

나는 새 항목의 주문을 결정하는 방법은 무엇입니까?

CREATE TABLE `members` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `name` varchar(65) collate utf8_unicode_ci NOT NULL, 
    `order` tinyint(3) unsigned NOT NULL default '0', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

MySQL의

에서 회원 테이블이 그리고 사용자가 원하는 방법 멤버를 주문할 수 있도록하고 싶습니다. order 열에 주문을 저장하고 있습니다.

새 사용자를 삽입하여 목록 맨 아래에 추가하는 방법을 궁금합니다.

$db->query('insert into members VALUES (0, "new member", 0)'); 
$lastId = $db->lastInsertId(); 
$maxOrder = $db->fetchAll('select MAX(`order`) max_order FROM members'); 
$db->query('update members 
      SET 
       `order` = ? 
      WHERE 
       id = ?', 
      array(
       $maxOrder[0]['max_order'] + 1, 
       $lastId 
     )); 

그러나 동시에 새 멤버를 추가하는 여러 사용자가있는 경우,이 같은 값을 반환합니다 MAX(order) 일어날 수있는 반면이 정말 정확하지입니다 : 이 오늘이 무슨이다.

어떻게 이러한 사례를 처리합니까?

답변

4

당신은 같은 삽입의 일부로 선택을 할 수 있습니다.

또한 255 개의 주문 만 예상하지 않는 한, 주문에 대한 tinyint를 다시 고려할 수도 있습니다.

또한 주문은 예약어이기 때문에 항상 '주문'으로 작성해야하므로 해당 열의 이름을 바꿀 수도 있습니다.

+1

backticks는 mysql에서 필드 이름을 피하는 방법이다. – nickf

2

새 회원마다 이미 ID가 자동으로 증가하므로 ID로 주문할 수 있습니다.

0

잘 모르겠습니다. 각 사용자가 다른 순서를 원할 경우 "회원"테이블의 단일 필드에 개별 사용자 기본 설정을 저장하는 방법은 무엇입니까?

일반적으로 필드의 자연 순서에 따라 사용자를 주문할 수 있습니다. 주문 입력란의 목적은 무엇입니까?

0

일반적으로 나는 모든 select 문을 "order, name"으로 정렬합니다. 그런 다음 Order에 대해 항상 같은 값을 삽입합니다 (처음 또는 마지막에 따라 0 또는 9999999). 그런 다음 사용자는 원하는 순서로 정렬 할 수 있습니다.

+0

동시에 삽입하면 동일한 '주문'값을 가진 2 개의 항목을 갖는 것을 방지하려고합니다. 'order'가 '0'인 항목을 삽입하고 아직 가져 오지 않은 새로운 'order'값을 찾으려고 시도하지만 2 명의 사용자가 동시에 처리하면 2 개의 동일한 값이됩니다. –

0

InnoDB는 트랜잭션을 지원합니다. 삽입하기 전에 '시작'문을 수행하고 완료되면 완료하십시오. mySql의 트랜잭션에 대한 설명은 this article을 참조하십시오.

INSERT INTO members SELECT 0, "new member", max(`order`)+1 FROM members;

당신이 최적화 된 부품 선택을 할 수있는 order 컬럼에 인덱스를 갖고 싶어거야 유의 사항 :

+0

트랜잭션이 정상입니다. 하지만 여전히 하나의 선택 쿼리와 하나의 업데이트 쿼리 만있는 것과 같은 '주문'을 가진 2 개의 아이템을 갖는 것을 방지하지는 못합니다. 여러 개의 삽입/업데이트를 수행하면 트랜잭션이 다른 경우에 도움이됩니다 ... –

+0

완전히 옳았습니다. 내 대답은 당신의 문제를 해결하지 못합니다. 댓글 주셔서 감사합니다. – boes

0

다른 member_id에 매핑되는 키 (member_id, position)가있는 테이블을 만들 수 있습니다. 그런 다음 해당 테이블에 멤버 목록 자체와 별도로 순서를 저장할 수 있습니다. 이 같은 멤버 테이블이 있다고 가정하면

(? 각 구성원이 나는 ... 당신이 원하는 가정 무엇인가 자신의 목록 순서를 유지합니다) : 다음

+-----------+--------------+ 
| member_id | name   | 
+-----------+--------------+ 
|   1 | John Smith | 
|   2 | John Doe  | 
|   3 | John Johnson | 
|   4 | Sue Someone | 
+-----------+--------------+ 

을, 당신은 주문 테이블을 가질 수있다 다음과 같이하십시오 :

+---------------+----------+-----------------+ 
| member_id_key | position | member_id_value | 
+---------------+----------+-----------------+ 
|    1 |  1 |    4 | 
|    1 |  2 |    1 | 
|    1 |  3 |    3 | 
|    1 |  4 |    2 | 
|    2 |  2 |    1 | 
|    2 |  3 |    2 | 
+---------------+----------+-----------------+ 

내부 조인을 사용하여 저장된 순서대로 구성원 목록을 선택할 수 있습니다.예를 들면 : 예를 들어

SELECT name 
FROM members inner join orderings 
    ON members.member_id = orderings.member_id_value 
WHERE orderings.member_id_key = <ID for member you want to lookup> 
ORDER BY position; 

, 존 스미스의 목록이 쿼리를 실행 한 결과 (즉, WHERE member_id_key = 1)과 같다 :

+--------------+ 
| name   | 
+--------------+ 
| Sue Someone | 
| John Smith | 
| John Johnson | 
| John Doe  | 
+--------------+ 

당신은에 추가 할 위치를 계산할 수 있습니다 주어진 id에 대한 최대 위치 값에 1을 더하여 목록의 맨 아래에.

관련 문제