2012-03-06 4 views
0

사용자가 추가 한 이미지가 많은 웹 사이트를 만들고 있습니다.이 SQL 쿼리를 가장 효과적으로 만들 수 있습니까?

이 풀에서 하나의 이미지를 임의로 선택하여 사용자에게 표시하고 싶지만 이전에이 이미지를 본 적이없는 사용자인지 확인하고 싶습니다.

그래서 나는 생각했다 : 사용자가 이미지를 볼 때 MYSQL에서 "이 USER가이 이미지를 (시간)에 보았습니다"라는 모든 내용의 INSERT 행을 만듭니다. 그러나 많은 사용자와 많은 이미지가있을 수 있으므로이 테이블은 수천 개의 항목으로 빠르게 빠르게 커질 수 있습니다. 모든 USER에 대해 INSERT 행을 만들려고했는데 하나의 필드에서 사용자가 본 이미지의 모든 ID를 배열에 삽입합니다.

I도 할 수있는 배열에 : base64_encode (gzcompress (직렬화 ($ 배열)

: 그리고 때 unserialize (gzuncompress (base64_decode ($ 배열))

당신은 내가 어떻게 생각하십니까 해야합니까? 인코딩/디코딩 기능이 빠르지 않습니까? 또는 게시물의 시작 부분에 설명했던 기존 방식보다 적어도 빠릅니까?

큰 압축 데이터를 하나의 데이터베이스에만 저장할 수 있습니까? 필드? (상상해 사용하는 경우 r은 수천 개의 이미지를 보여왔다?)

덕분에 많이

+0

사용자가 실제로 이미지를 "본"것을 어떻게 알 수 있습니까? 무작위로 충분할 수도 있습니다. :) 어떻게 임의의 이미지를 선택하고 있습니까? –

답변

2

, 나는이 같은 값을 직렬화하는 나쁜 관행은 모든 ID의

거의 모든 경우에 배열을 삽입합니다. 데이터베이스가 의도 한대로 작업하게하십시오. 많은 양의 데이터를 효율적으로 처리하십시오. 교차 테이블에 사용자 필드에 대한 색인이 있는지 확인하는 한, 사용자가 본 이미지 목록을 검색하면 테이블의 행 수에 관계없이 비용이 많이 드는 작업이되지 않습니다. 수십만 개의 항목은 아무것도 아닙니다.

+0

안녕하세요, Alex. 답변 해 주셔서 감사합니다. 그런 다음 image_id/user_id 메소드로 이동합니다. – eric01

0

당신은 열 user_idimage_id (추가, 당신은 같은 날짜/시간, IP와 같은 뷰에 대한 자세한 정보를 추가 할 수있는 새 테이블 UserImageViews을 작성해야 브라우저).

이렇게하면 "사용자가 본 이미지 (보이지 않는 이미지)"가 훨씬 빨라집니다.

+0

안녕하십니까? 테이블에 10k + 행이있는 경우이 방법이 데이터베이스에 대해 매우 강렬하다고 생각하십니까? 감사합니다. 편집 : 아래 답변이 있습니다. 어쨌든 고마워! – eric01

+1

색인이있는 경우에는 필요하지 않습니다. 이것은 RDBMS가 설계된 것입니다. "한 필드에서 여러 데이터"접근법을 사용하면 더 나 빠질 것입니다. –

0

테이블을 사용해야합니다. DBMS는 데이터가 나타내는 것을 전혀 모르고 어떤 쿼리에서도 사용할 수 없으므로 데이터를 데이터베이스의 단일 필드로 일련 화하는 것은 좋지 않습니다. 예를 들어 어떤 사용자가 이미지를 보았는지 보려면 SQL만으로는 불가능합니다.

수십만 개의 항목이 그다지 많지 않습니다. 우리가 개발하는 주요 응용 프로그램에는 수십만 개의 레코드가있는 다중 테이블이 있으며 그만큼 중요하지 않습니다. 일부 웹 응용 프로그램에는 수백만 개의 행이있는 테이블이 있습니다. 문제가되기 시작하지 않는 한 "너무 많은 데이터"에 대해 걱정하지 마십시오. 해당 문제에 대한 솔루션은 복잡 할 것이며 데이터 양에 도달 할 때까지 쿼리 속도가 느려질 수도 있습니다.

EDIT : 오 그래, 그 100k + 테이블에 대한 조인은 잠시 후에 발생합니다. 그냥 나중에 몇 가지 관점 ... ONE 분야에서

+0

안녕하세요, Ryan, 제안 해 주셔서 감사합니다. 내가 localhost에 있기 때문에 그 안에는 수백 개의 행만 있고 내 쿼리는 0.01보다 적게 걸린다. 1 초가 컴퓨터의 영원한 것처럼 보입니다 :)하지만 진지하게 조언을 구할 것입니다. 고마워요. – eric01

0

수십만 개의 행이 데이터베이스 조회에 문제가 될 것이라고 저는 생각하지 않습니다. 두 번째 방법보다 첫 번째 방법을 사용하는 것이 좋습니다.

0

나는이 풀에서 무작위로 하나의 이미지를 선택하고 사용자에게 그것을 표시 할,하지만 난이 사용자가 이전 이 이미지를 본 적이 있는지 확인하려면.

이는 가치가있는 것으로, 이는 임의 알고리즘이 아닙니다. 그것은 셔플 알고리즘입니다. (그 사실을 알면 Google에 더 자세한 정보가 필요할 때 Google에보다 쉽게 ​​적용될 수 있습니다.)하지만 이것이 가장 큰 문제는 아닙니다.

그래서 나는 생각했다 : 사용자가 이미지를 볼 때, 나는 모든 항목에 대한 말을 MYSQL의 행 INSERT "이 사용자가 (TIME)에서이 이미지를 지켜왔다"를 확인합니다.

좋은 생각. 사용자가 특정 이미지를 본 사실을 저장하는 테이블을 사용하면 귀하의 경우에 적합합니다. 내가 놓친 것이 아니라면 시간을 저장할 필요가 없습니다. (그리고 아마 그렇게해서는 안되며, 유용한 비즈니스 목적을 수행하는 것 같지 않습니다.)이 줄에있는 어떤 것이 잘 작동 할 것입니다.

-- Predicate: User identified by [user_id] has seen image identified by 
-- [image_filename] at least once. 
create table images_seen (
    user_id integer not null references users (user_id), 
    image_filename not null references images (image_filename), 
    primary key (user_id, image_filename) 
); 

시험 및 그 EXPLAIN 출력 본다. image_filename에 보조 색인이 필요한 경우. . .

create index images_seen_img_filename on images_seen (image_filename); 

이것은 여전히 ​​가장 큰 문제는 아닙니다.

가장 큰 문제는 직접 테스트하지 않았다는 것입니다. 스크립팅 언어를 아는 경우 2 ~ 3 분 만에 테스트를 위해 10,000 개의 행을 생성 할 수 있어야합니다. 그렇게했다면, 수백만 줄의 테이블을 가진 테이블도 잘 작동한다는 것을 알게 될 것입니다.

StackOverlow에서 질문에 답하기 전에 때때로 아이디어를 테스트하기 위해 수백만 행을 생성합니다.

테스트 용으로 대량의 랜덤 (ish) 데이터를 생성하는 것을 배우는 것은 데이터베이스 및 응용 프로그램 개발자에게 기본적인 기술입니다.

+0

안녕하세요 Catcall, 위대한 게시자 님과 EXPLAIN의 존재를 전달하는 것에 대해 알려 주신 것에 대해 감사드립니다. user_id를 기본 키로 만 선택하려고했지만 기본 키 (user_id, image_filename)의 제안 이유는 무엇입니까?고마워요 – eric01

+0

@ eric01 : "user_id"가 기본 키의 유일한 열인 경우 사용자 당 하나의 이미지 파일 이름 만 저장할 수 있습니다. –

+0

오, 알았어, 내 첫 번째 생각은 사용자 당 하나 이상의 이미지 파일 이름을 저장하기 위해 "id"라는 다른 열을 Primary (자동 증가)와 같이 사용하고 두 번째 열을 user_id로 사용해야한다는 것입니다. 파일 이름은 세 번째 열에 있습니다. 그러나 나는 그것이 빠르지 않을 것이라고 생각한다. ..? – eric01

관련 문제