MySQL-구조는 같지만 데이터가 다른 여러 테이블에서 데이터 선택


79

좋아, 여기에 내 딜레마가있다. 정확히 동일한 데이터 구조를 가진 약 5 개의 테이블로 데이터베이스를 설정했다. 데이터는 지역화를 위해 이러한 방식으로 분리되고 총 약 450 만 개의 레코드를 분할합니다.

대부분의 경우 하나의 테이블 만 필요하며 모든 것이 정상입니다. 그러나 때로는 두 개 이상의 테이블에서 데이터가 필요하며 사용자 정의 열을 기준으로 정렬해야합니다. 여기에 문제가 있습니다.

데이터 열 :

id, band_name, song_name, album_name, genre

MySQL 문장 :

SELECT * from us_music, de_music where `genre` = 'punk'

MySQL은이 오류를 내 보냅니다.

#1052 - Column 'genre' in where clause is ambiguous

분명히 나는 ​​이것을 잘못하고 있습니다. 누구든지 나를 위해 이것에 대해 밝힐 관심이 있습니까?

답변:


177

나는 당신이 UNION 절을 찾고 있다고 생각합니다.

(SELECT * from us_music where `genre` = 'punk')
UNION
(SELECT * from de_music where `genre` = 'punk')

@ mihai-limban-불편을 끼쳐 드려 죄송합니다. 결과 집합에서 "어떤 결과가 어떤 테이블에서 왔는지"를 인식하는 방법이 있습니까? 이 결과 집합에서 레코드를 업데이트 / 삭제해야하는 경우 알 수있는 방법이 없기 때문입니다.
— web-nomad 2012

7
모든에 고유 한 문자열 식별자를 추가 @Pushpesh SELECT, 예를 들면 :(SELECT 'us_music' AS from_table, * FROM us_music WHERE genre = 'punk') UNION ...
— jkrcma

장르의 가치는 알 수 없지만 ID가 두 테이블에서 일치해야하는 것은 무엇입니까? 이런 식으로 할 수 있습니까? (SELECT 1) AS select1 UNION (SELECT 2) AS select2 WHERE select1.id=select2.id
— ZurabWeb

완벽합니다. 정확히 내가 Stack을 좋아하는 이유입니다! Google, 이미 여기에서 스택 질문과 답변을 찾아보세요! 감사!
— Rocco The Taco

결과 집합의 UNION을 기준으로 그룹화 한 다음 정렬 기준을 수행하는 구문은 무엇입니까? 매월 하나의 DB가 viewCount있고 movieTitle어디에 있다고 가정 해 봅시다 . 12 개의 테이블을 모두 합쳐도 괜찮지 만 출력에 12 개의 개별 결과 세트가 표시됩니다. 당신은 단지 모든 결과에 의해 그룹화 된 하나 개의 결과 집합을 원하는 경우 movieTitle와 viewCount값이 각각 요약 한 movieTitle행?
— anon58192932

19

하나의 테이블을 가지고있는 것처럼 들리 네요. 5 개는 동일한 스키마를 가지며 때로는 하나의 테이블 포인트에서 모든 것을 하나의 테이블에 넣는 것처럼 표시되어야합니다.

5 개 언어를 구분하는 데 사용할 수있는 새 열을 추가합니다 (현지화 용이라고 말 했으므로 표간에 다른 언어라고 가정합니다). 450 만 개의 레코드가있는 것에 대해 걱정하지 마십시오. 실제 데이터베이스는 문제없이 해당 크기를 처리 할 수 ​​있습니다. 올바른 인덱스를 추가하면 단일 테이블로 처리하는 데 문제가 없습니다.


원래는 모든 데이터가 단일 테이블에 있었지만 약 350 만 개의 레코드가 있은 후 거의 5-10 초 동안 크롤링하기 시작했습니다. 나는 그것을 나누는 것이 훨씬 더 빠르기 때문에 나에게 가장 효과적이라는 것을 알았습니다. 지금 새 웹 호스트가 있으므로 더 좋을 수도 있지만 결합하기에는 너무 번거로운 것 같습니다
— Jayrox

26
테이블에 인덱스를 추가해야하는 것 같습니다.
— Ned Batchelder

1
예, 핵심 문제 (부적절 / 불충분 한 인덱싱)를 해결하지 않고 문제의 증상을 근본적으로 치료했습니다. 5 개 테이블 중 하나가 450 만 행에 도달하고 다시 크롤링을 시작하면 다음에 어떻게 되나요?
— Lo-Tan

5

위의 답변 중 하나라도 유효하거나 다른 방법은 데이터베이스 이름도 포함하도록 테이블 이름을 확장하는 것입니다. 예 :

SELECT * from us_music, de_music where `us_music.genre` = 'punk' AND `de_music.genre` = 'punk'

이는 매우 잘못 정의 된 결과 집합을 제공합니다. 가능한 모든 us_ 및 de_ punk 쌍입니다.
— David Schmitt

4

열은 두 테이블 모두에 나타나기 때문에 us_music.genre 또는 de_music.genre와 같이 where (또는 정렬) 필드를 완전히 지정해야하지만 일반적으로 두 테이블을 함께 조인하려면 두 테이블을 지정해야하기 때문에 모호합니다. 어떤 패션. 일반적으로 데이터 세트를 임의로 분할하기보다는 데이터 세트를 별개의 파일로 분리하기 위해 처리하는 구조를 분할 된 테이블이라고도합니다. 데이터베이스 구조를 담당하고 있고 데이터를 분할 할 이유가없는 경우 국가 코드가 포함 된 추가 "원산지"필드가있는 하나의 큰 테이블을 만들 겠지만 합법적 인 성능상의 이유로 수행 할 것입니다. . http : //dev.mysql에 관심이있는 테이블을 결합하려면 공용체를 사용 하십시오.또는 병합 데이터베이스 엔진 http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html 을 사용합니다 .


3

두 테이블을 모두 확장하려는 원래 시도는 암시 적 JOIN을 생성합니다. 이것은 어떻게 조건과 결합 될 테이블을 분리하기 때문에 가장 숙련 된 SQL 프로그래머들에게는 눈살을 찌푸리게합니다.

이것은 UNION테이블에 대한 좋은 솔루션이지만 적절한 인덱싱으로 하나의 테이블에 넣을 수없는 이유가 없어야합니다. 큰 테이블에 올바른 인덱스를 추가하면 쿼리 속도가 3 배 증가하는 것을 보았습니다.


3

이 union진술은 거대한 데이터에서 거래 시간을 유발합니다. 선택은 2 단계로 수행하는 것이 좋습니다.

  1. 아이디를 선택하세요
  2. 그런 다음 기본 테이블을 선택하십시오.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.