2012-02-23 3 views
6

몇 년 전에 학습 프로젝트로 게임을위한 통계 사이트를 개발했습니다. 그것은 오늘도 여전히 사용되고 있으며 조금 정리해야합니다.MySQL의 필드가 너무 많습니까?

데이터베이스는 개선이 필요한 영역입니다. GameID, PlayerID, Kills, Deaths, DamageDealt, DamageTaken 등이있는 게임 통계를위한 테이블이 있습니다. 전체적으로 약 50 개의 필드가 하나의 테이블에 있고 앞으로 더 추가 될 수있는 테이블이 많이 있습니다. 어느 시점에 필드가 너무 많습니까? 현재 57,341 개의 행을 가지고 있으며 그 자체로 153.6 MiB입니다.

또한 동일한 테이블의 BLOB에 배열을 저장하는 몇 가지 필드가 있습니다. 배열의 예는 Player vs Player matchups입니다. 배열은 플레이어가 게임에서 다른 플레이어를 몇 번 죽였는지를 저장합니다. 이것은 파일 크기가 더 큰 필드입니다. BLOB에 배열을 저장하는 것이 좋습니다.

 [Killed] => Array 
      (
       [SomeDude] => 13 
       [GameGuy] => 10 
       [AnotherPlayer] => 8 
       [YetAnother] => 7 
       [BestPlayer] => 3 
       [APlayer] => 9 
       [WorstPlayer] => 2 
      ) 

이 10 명 이상의 플레이어를 초과하지 않는 경향이

배열처럼 보인다.

답변

2

필자는 더 많은 수의 열을 가진 하나의 테이블을 가지지 않고 레이블과 값의 연관된 테이블을 가지므로 각 사용자는 ID를 가지며 그 ID를 키로 사용합니다. 라벨과 값의 테이블. 그렇게하면 사용자 당 필요한 데이터 만 저장할 수 있습니다. 나는이 접근법이 EAV (Triztian의 의견대로)라고 불렀고 의료 데이터베이스가 유지되는 방법이라고 생각합니다. 주어진 환자는 실제 데이터가있는 필드의 수가 매우 적기도하지만 개별 환자에 대해 가능한 많은 필드가 있으므로 .

그래서, 당신은 사용자 당 필요로하는

user: 
id | username | some_other_required_field 

user_data: 
id | user_id | label | value 

지금 당신은 많은 또는 몇 _ 데이터 행을 가질 수있을 것입니다.

[편집]

는 배열에 관해서는, 나뿐만 아니라 관계형 테이블이 치료 것이다. 당신이 상호 작용을했고, 그 상호 작용의 유형을했던 두 선수를 저장하는 것입니다 여기

player_interraction: 
id | player_id | player_id | interraction_type 

:처럼 뭔가.

+0

EAV 또는 [Entity-Attribute-Value] (http://en.wikipedia.org/wiki/Entity-attribute-value_model)라고합니다. – Triztian

+0

아! 고마워 ... 내 대답을 편집 할게. –

+0

통계 요약표로, 나는 "앞으로 나아갈 것"이라는 역동적 인 것이 없다고 추측하고, 미래에 추가하고 싶은 열의 수가 제한되어 있다고 생각합니다. 또한 모든 플레이어가 모든 열을 사용하게 될 것입니다. 따라서 EAV의 모든 유연성은 필요하지 않습니다. EAV가이 상황에서 쉽게 작동 할 수 있다고 동의합니다. – Prescott

1

테이블 디자인은 대부분 괜찮아 보입니다. 저장중인 열이 같은 행의 다른 열에서 계산 될 수없는 한. IE에서는 SelfKills, OtherDeath 및 TotalDeaths를 저장하지 않습니다 (여기서 TotalDeaths = SelfKills + OtherDeath). 그건 말이 안되고 테이블에서자를 수 있습니다.

BLOB에 배열을 저장하는 방법에 대해 자세히 알고 싶습니다. BLOB에서 어떤 용도로 사용합니까? 쉬운 데이터 변환 및 분석을 위해 테이블로 정규화되지 않은 이유는 무엇입니까? (또는 그들이 최종 사용자에게 데이터를 쉽게 표시 할 수 있도록 여기에 배열로 저장됩니다.)

또한 BLOB가 차지하는 데이터의 양과 테이블의 나머지 데이터가 궁금합니다. 일반적으로 행의 크기는 행의 개수만큼 크지 않으며 ~ 60K는 전혀 중요하지 않습니다. 모든 컬럼 값을 검사해야하는 쿼리를 작성하지 않는 한 (where 절을 작성하려고 할 때 blob을 무시하는 것이 이상적입니다).

+0

나는 배열을 보여주기 위해 나의 대답을 편집했다. – Motive

+0

"그건 이해가 안 돼서 식탁에서 벗어날 수있어." 꼭 그런 것은 아닙니다. 'TotalDeaths'에 의해 많은 쿼리를 한 경우 계산 된 버전을 테이블에 저장하면 쿼리를 실행할 때마다 ** 모든 57,000 행 **에서 계산을 실행할 필요가 없습니다. – ceejayoz

+0

당신은 절대적으로 맞습니다. 나는 두 가지 분리 된 생각을 가지고있었습니다. "정보의 저장"은 하나였습니다. 그리고 나는 "큰 행을 쿼리하는 것"을 가지고 있었고, 함께 생각하지도 않았습니다. – Prescott

1

mysql을 사용하면 행당 대략 4000 개의 열 (필드) 및 총 65Kb의 저장 용량을 가질 수 있습니다. 큰 문자열을 저장해야하는 경우 텍스트 필드를 사용하면 디스크에 저장됩니다. BLOB는 실제로 비 텍스트 데이터 용으로 예약해야합니다 (필요한 경우).

db의 크기는 걱정하지 마시고 구조와 구성 및 색인 방법에 대해 생각하십시오. 나는 작은 DB가 쓰레기처럼 굴는 것을 보았다.

숫자를 원한다면 전체 DB가 GB 범위 또는 몇 십만 행을 단일 테이블로 가져온 다음 60KB 행의 150M이 그리 많지는 않지만 일에 대해 더 걱정할 것입니다. 테이블 스캔은 성능면에서별로 비용이 들지 않습니다. 그러나 이제는 자주 사용되는 쿼리에 대해 양호한 커버 인덱스를 작성해야합니다.

1

시간이 지남에 따라 데이터베이스 테이블에 열을 추가해도 문제가 없습니다. 데이터베이스 디자인은 항상 변합니다. 명심해야 할 것은 데이터가 그룹화되는 방법입니다. 필자는 항상 데이터베이스 테이블을 비슷한 항목의 모음으로 취급했습니다. 내가 생각

상황은 다음과 같습니다

널 얼마나 많은 열이 행에 데이터를 삽입 할 때?
이 새로운 열은 이미있는 데이터의 80 %에 적용됩니까?
이 표의 몇 가지 열에 대한 몇 가지 업데이트가 있습니까?
그렇다면 나는 previos 값이 어떤 경우인지 추적해야합니까?

이와 같은 데이터를 생각해 보면 테이블을 외래 키로 연결된 여러 개의 작은 테이블로 나누어야한다는 것을 알 수 있습니다.

관련 문제