2011-11-27 3 views
1

현재 회원으로 활동중인 사이트에서 다른 회원들을 좋아할 수 있습니다. 그런 다음 회원이 즐겨 찾기 페이지로 이동하면 시간이 지남에 따라 즐겨 사용하는 모든 회원을 볼 수 있습니다.데이터베이스를 비정규 화하여이 특별한 방법으로 성능을 향상시킬 수 있습니까?

나는 2 가지 방법으로 이것에 대해 갈 수

:

방법 # 1 : 사용자의 즐겨 찾기 내가 (인덱스가 user_favoriting_id입니다 같이 보이는 favorites 테이블에서 행을 입력 다른

때마다) :

id | user_favorited_id | user_favoriting_id 
------------------------------------------- 

그들은 "즐겨 찾기"페이지를로드 할 때 다음, 나는 user_favoriting_id 값이 presen의 그것과 동일 위치를 즐겨 찾기 테이블에 선택이 모든 행을 찾기 위해 할 로그인 한 사용자. 그런 다음 user_favorited_ids를 사용하여 단일 SELECT 문을 작성하고 별도의 사용자 테이블에서 해당 사용자를 조회합니다.

방법 # 2 :

때마다 사용자의 즐겨 찾기 다른 나는 이런 식으로 뭔가를 보이는 사용자 테이블에서 자신의 행에 즐겨 찾기 필드를 업데이트합니다 (자세한 필드이기는하지만, 인덱스 ID입니다) :이 항목은 다음처럼 쉼표로 구분 된 문자열을 보유 할 수 있도록 I는 사용자의 ID를 CONCAT 것이다

id | username | password | email | account_status | timestamp | favorites 
-------------------------------------------------------------------------- 

favorites 필드 즐겨 찾기되고 :

10,44,67 등 ...

그런 다음 방법 # 1과 같은 즐겨 찾기 페이지를 만들려면 즐겨 찾는 모든 사용자를 한 번만 선택하면됩니다. 그 부분은 동일합니다.

나는 방법 # 1이 그것을하는 정규화 된 방법다는 것을 알고 매우 더 귀엽다. 그러나이 특정 프로젝트에 대한 저의 관심은 무엇보다도 확장 성과 성능입니다.

내가 방법 # 2를 선택하는 경우, 사용자 테이블에 사용자가 로그인하는 즉시 어쨌든 선택해야하므로, 별도의 즐겨 찾기 테이블에 조회하는 것을 줄일 수 있습니다.

을 그리고 난 꽤 확실한 방법 # 2에서 그 CSV 값을 나누기 위해 PHP의 폭발 함수를 사용하여 favorites 테이블에 대한 방법 # 1의 추가 db look up과 거의 같은 시간이 걸릴 것이 아니라, 단지 물어 봐야 할 경우를 대비하여 묻습니다 :

From 순전히 성능 관점, 이러한 방법 중 더 최적화 된?

또한이 웹 사이트에 하루에 수조의 페이지 뷰가 제공됩니다.

+1

방법 2에서 조회하는 작업이 매우 느릴 것입니다 (각 ID를 분석하여 개별적으로 찾아야 함) 평범한 조인을하지 않기 때문에 모든 종류의보고가 빠져 나올 것입니다. ID 만 표시하고 즐겨 찾기에 대한 의미있는 설명은 표시하지 않으시겠습니까? –

+0

@Robert와 동의; 하지만 누가 나를 호감가는 지보기 어려워진다. – pilotcam

+0

@Robert Harvey 실제로'WHERE id = $ split_value'와 같은 문자열을 작성하고 foreach 루프 안에 배치하여 분해 된 CSV 배열을 실행하고 있습니다. 그런 식으로 내가 어쨌든 빌드하려고했던 SELECT SQL 끝에이 추가 할 수 있습니다. 이렇게하면 SQL은 PHP에서 빌드되고 실행되기 전에 하나의 쿼리가됩니다. – TK123

답변

1

확장성에 관심이 있다고합니다. 이것은 사용자가 가질 수있는 즐겨 찾기의 수를 제한하기 때문에 방법 # 2가 작동하지 않는다는 것을 의미합니다. 예를 들어, 사용자 수가 100 만 명인 경우 대부분의 사용자는 5 자리 ID를 갖게됩니다. 의 길이는 얼마입니까? VARCHAR(1000) 인 경우 200 개 미만의 즐겨 찾기가 허용된다는 것을 의미합니다.

또한 실제로 일 때 어떤 사용자가 특정 사용자를 "선호"했는지 알고 싶습니까? 방법 # 2는 O.K 일 수 있습니다. 항상은 "즐겨 찾기"가 아닌 "즐겨 찾기"로 즐겨 찾기를 조회하지만 그렇지 않은 경우 완전히 별개입니다. (그리고 여기서도 사용자 ID와는 별개로 "좋아하는 사람"에 대해 의미있는 것을 찾아 볼 것을 기대하지 않으면 의미가 있습니다; 그렇지 않으면 실제로 "좋아하는 사람"을 검색하면 기본적으로하고있는 것입니다 JOIN의 모든 노력은 MySQL이 지능적으로 JOIN을 수행 할 수있는 기회를 제거하는 것입니다.)

전반적으로 정규화와 같은 베스트 프랙티스로 시작하고 성능이 향상 될 때만 이동하는 것이 좋습니다 그것을 필요로합니다. 그렇지 않으면 성능 최적화와 같은 결과가 발생하여 부정적인 결과를 초래할 수 있습니다. - 최적 코드를 추가로 작성해야합니다.

+0

정상화되었습니다. – TK123

1

JOINs 시간이 걸리지 만 필요하다고 제안하는 데이터가있을 때까지 변경하지 않습니다.

정상화는 여러 가지 이유로 좋습니다. 그것은 학문적 인 운동이 아닙니다.

열에 ID를 연결하는 것은 정규화에 대한 가증스러운 범죄입니다. 하지 마.

관계형 데이터베이스를 최적화하기 위해 수행 된 모든 작업보다 코드가 빠르다고 가정하고 있습니다. 그것은 큰 실수입니다.

JOIN에 참여하는 기본 및 외래 키에 대한 색인이 있는지 확인하십시오.

실제 성능 문제가있을 때 응용 프로그램을 프로파일하십시오. 짐작하지 마라.

앱에 실제 문제가 없는지 확인하십시오. 불필요한 정보를 너무 많이 가져 오면 정규화 된 스키마보다 성능이 저하됩니다.

0

데이터 정규화, 유지 보수성 및 데이터 무결성 관점에서 Both (One) (표준화 된 접근법)를 사용하는 것이 좋습니다. 다른 이유로도이 접근법을 항상 선호해야합니다.

그러나 정규화 된 접근 방식이 읽기 성능에 적합하지 않은 경우 다른 접근 방식을 사용하지 않아도됩니다. 대개의 경우 비정규 화 된 접근 방식이 읽기 성능을 향상시키는 경우가 많습니다. 따라서 첫 번째 데이터를 "마스터"로 사용하여 데이터를 추적하고 데이터 무결성을 확인한 다음 다른 구조에서 데이터의 비정규 화 된 "복사본"을 읽기 액세스 용으로 유지합니다. 마스터에서 복사본을 업데이트합니다 변경 될 때마다 (업데이트 삽입, 삭제).

그러나 측정을 보장하기 위해 당신의 다른 방법의 성능은 참 빨리, 그리고 그것의 사용을 정당화하기에 충분한 차이로.

0

제가 아는 한 dernomalization을 mysql에서 사용하는 것은 정말 사소한 일입니다. 하지만 RDBMS가 아닌 couchdb 또는 mongoDB와 같은 DB를 사용한다면 전체 엔진이 안전한 방법으로 데이터를 조작하는 방법이 있습니다. 그리고 그것은 예를 들어 MySQL의를 사용하여 웹 애플리케이션을 최적화 선호

유일한 방법은 테이블을 dernomalize 다음 PHP 몇 가지 작업을 제공하는 것입니다 .. 정말 확장 성, 비 관계형 데이터베이스가 정말 빨리 당신을 위해 일 것입니다 , 그리고 당연히 HipHop을 사용하면 거기에 몇 가지 정말 큰 최적화를 얻을 것입니다. 왜냐하면 당신이 MySQL을 오프로드하고 PHP를로드했기 때문에 HipHop은 최대 50 %까지 최적화 될 것입니다!

0

아마도 그렇지는 않지만 다른 사람들이 이미 인용 한 이유로 데이터베이스를 완전히 망칠 수 있습니다.

쉼표로 구분 된 ID 목록 패턴을 사용하지 마십시오. 그것은 단지 빤다.

페이스 북을 사용하지 않는 한 1 백만 명이 넘지는 않을 것이므로 충분히 중요하지 않다고 생각합니다. 대부분의 사용자는 해당 기능을 사용하지 않는 일반 사용자가 될 것이므로 대부분의 사용자는 아무도 자신이 좋아하는 사용자로 선택하지 않습니다.

두 개의 열만있는 극히 작은 테이블 (1M 사용자의 경우 즐겨 찾기가 평균적으로 1M 행, 대부분이 기능을 전혀 사용하지 않지만)은 매우 작습니다. 기본 키를 가장 일반적으로 검색하고자하는 것으로 시작함으로써 이노 보브의 스캔을 향상시킬 수 있지만, 여전히 다른 인덱스에 보조 인덱스를 추가 할 수 있고 합리적인 조회 시간을 얻을 수 있습니다 테이블이 가장 작은 서버의 메모리에 맞을 때 매우 빠릅니다!)