programing

어느 쪽이 더 효율적인가:MySQL 테이블이 여러 개입니까, 아니면 하나의 큰 테이블입니까?

bestcode 2022. 9. 4. 15:20
반응형

어느 쪽이 더 효율적인가:MySQL 테이블이 여러 개입니까, 아니면 하나의 큰 테이블입니까?

MySQL 데이터베이스에 다양한 사용자 세부 정보를 저장합니다.원래는 다양한 테이블로 설정되어 있었습니다.즉, 데이터는 UserId로 링크되어 있으며, 경우에 따라서는 복잡한 콜을 통해 출력되어 필요에 따라 데이터를 표시 및 조작할 수 있습니다.새로운 시스템을 셋업할 때는 이 모든 테이블을 하나의 큰 관련 콘텐츠 테이블로 통합하는 것이 거의 의미가 있습니다.

  • 이게 도움이 될까요, 아니면 방해가 될까요?
  • 호출, 업데이트 또는 검색/조작 시 고려사항의 신속성

테이블 구조의 예를 다음에 나타냅니다.

  • 사용자 - 사용자 ID, 사용자 이름, 이메일, 암호화된 비밀번호, 등록일, IP
  • user_cookie - cookie 데이터, 이름, 주소, 연락처 상세, 소속, 인구통계 데이터
  • user_activity - 기여, 마지막 온라인, 마지막 표시
  • user_display - 프로파일 표시 설정
  • user_targetable 변수 애드버타이즈
  • user_module - 접근 권한
  • user_module - 조회수, 집계

편집: 지금까지의 답변은 모두 상향 투표했습니다.모든 답변에는 기본적으로 질문에 대한 답변이 포함되어 있습니다.

대부분의 테이블은 1:1의 관계를 가지고 있으며, 이것이 그들을 정규화하지 않은 주된 이유였다.

셀의 대부분이 비어 있을 가능성이 높은 경우 테이블이 100개 이상의 열에 걸쳐 있으면 문제가 발생합니까?

여러 테이블은 다음과 같은 경우에 도움이 됩니다.

(a) 서로 다른 사람들이 서로 다른 테이블을 포함하는 애플리케이션을 개발할 경우 분할하는 것이 타당합니다.

(b) 데이터 수집의 다른 부분에 대해 다른 종류의 권한을 다른 사람에게 부여하고 싶은 경우에는 분할하는 것이 편리할 수 있습니다(물론 뷰의 정의와 적절한 권한 부여를 검토할 수 있습니다).

(c) 데이터를 다른 곳으로 이동할 경우, 특히 개발 중에 테이블을 사용하여 파일 크기를 줄이는 것이 바람직할 수 있습니다.

(d) 작은 풋프린트는 단일 엔티티의 특정 데이터 수집에 대한 응용 프로그램을 개발할 때 편안함을 줄 수 있습니다.

(e) 하나의 가치 데이터로 생각했던 것이, 장래에는 정말로 복수의 가치가 될 가능성이 있습니다.예를 들어, 신용한도는 현재 하나의 가치 필드입니다.그러나 내일은 값을 (날짜, 날짜, 신용 값)으로 변경할 수 있습니다.지금은 분할 테이블이 편리할 것 같습니다.

제 투표는 데이터가 적절히 분할된 여러 테이블에서 이루어집니다.

행운을 빌어요.

테이블을 조합하는 것을 디노멀라이징이라고 합니다.

몇 가지 질문을 하는 데 도움이 될 수도 있고 그렇지 않을 수도 있습니다.JOINs) 유지보수의 어려움을 감수하면서 보다 빠르게 실행할 수 있습니다.

MySQL사용할 수 있는 것은JOIN방법, 즉NESTED LOOPS.

즉, 운전대에 있는 각 레코드에 대해MySQL는 루프 내의 드리븐테이블에 일치하는 레코드를 찾습니다.

레코드를 찾는 작업은 순수한 레코드 스캔의 수십 배에 달하는 비용이 드는 작업입니다.

모든 레코드를 한 테이블로 이동하면 이 작업을 제거할 수 있지만 테이블 자체가 커지고 테이블 스캔 시간이 길어집니다.

다른 테이블에 레코드가 많이 있는 경우 테이블스캔을 늘리면 순차적으로 스캔되는 레코드의 이점이 과중해질 수 있습니다.

반면에 유지보수의 지옥은 보장됩니다.

다 1:1 관계인가요?즉, 예를 들어 사용자가 다른 사용자 수준에 속할 수 있거나 사용자의 관심사가 사용자 관심 테이블에 여러 레코드로 나타나는 경우 이러한 테이블을 병합하는 것은 즉시 불가능합니다.

정규화에 관한 이전의 답변에 대해서는 데이터베이스 정규화 규칙은 퍼포먼스를 완전히 무시하고 깔끔한 데이터베이스 설계만을 검토하고 있다고 말할 필요가 있습니다.그것은 종종 여러분이 성취하고 싶은 것이지만, 성과를 추구하기 위해 적극적으로 정규화를 해제하는 것이 이치에 맞을 때가 있습니다.

대체로 테이블에 필드가 몇 개 있는지, 액세스 빈도가 얼마나 되는지에 따라 결정됩니다.사용자 액티비티가 그다지 흥미롭지 않은 경우가 많은 경우 퍼포먼스와 유지보수를 위해 항상 같은 레코드에 사용자 액티비티를 기록하는 것은 귀찮은 일일 수 있습니다.설정 등 일부 데이터에 매우 자주 액세스하지만 필드가 너무 많은 경우 테이블을 병합하는 것이 편리하지 않을 수도 있습니다.성능 향상에만 관심이 있는 경우 설정을 분리하여 세션 변수에 저장하여 데이터베이스를 자주 쿼리할 필요가 없도록 하는 등의 다른 방법을 고려할 수 있습니다.

모든 테이블에는1-to-1관계요?예를 들어, 각 사용자 행에는 대응하는 행이1개만 있습니까?user_stats또는user_levels그렇다면 이들을 한 테이블로 묶는 것이 타당할 수 있습니다.관계가 그렇지 않은 경우 1 to 1하지만 둘을 합친다는 것은 말이 되지 않을 겁니다.

수십만 또는 수백만 개의 사용자 레코드가 없는 한 하나의 테이블이 아닌 다른 테이블로 배치하는 것은 성능에 거의 영향을 미치지 않을 것입니다.실제로 얻을 수 있는 유일한 이점은 쿼리를 조합하여 단순화하는 것입니다.

도착 예정일:

너무 많은 것이 걱정되는 경우 일반적으로 어떤 것을 함께 사용하고 나머지는 별도의 테이블(필요한 경우 여러 개의 테이블)에 남겨두는지 생각해 보십시오.

데이터 사용 방식을 살펴보면 쿼리의 80%가 해당 데이터의 20%를 사용하고 나머지 80%는 가끔만 사용한다는 것을 알 수 있습니다.사용 빈도가 높은 20%를 1개의 테이블로 정리하고, 잘 사용하지 않는 80%를 다른 테이블로 정리하면 좋은 타협을 얻을 수 있을 것입니다.

대규모 테이블을 1개 작성하는 것은 관계형 데이터베이스 원칙에 위배됩니다.나는 그것들을 모두 한 테이블에 합치지는 않을 것이다.반복된 데이터의 여러 인스턴스를 가져옵니다.예를 들어 사용자가 3개의 관심사를 가지고 있는 경우, 3개의 다른 관심사를 저장하기 위한 동일한 사용자 데이터가 포함된 3개의 행이 있습니다.확실히 다중 '정규화된' 테이블 접근 방식을 선호합니다.데이터베이스의 정규화에 대해서는, 이 Wiki 페이지를 참조해 주세요.

편집: 질문을 업데이트했으므로 답변을 업데이트했습니다....이후 처음 대답에 더욱 동의한다.

이들 세포의 대부분은 비어 있을 가능성이 높다

예를 들어 사용자에게 관심이 없는 경우 정규화하면 해당 사용자의 관심 테이블에 행이 표시되지 않습니다.하나의 거대한 테이블에 모든 것이 있는 경우 NULL만을 포함하는 컬럼(그리고 많은 컬럼)이 있습니다.

저는 전화 회사에서 일했는데, 테이블이 너무 많아서 데이터를 얻으려면 많은 가입이 필요할 수 있습니다.이들 테이블에서 판독하는 퍼포먼스가 중요한 경우 보고서가 가리키는 조인이나 계산 등을 필요로 하지 않는 플랫테이블(비정규화 테이블)을 생성할 수 있는 절차를 작성해야 합니다.그런 다음 SQL Server 에이전트와 함께 사용하여 특정 간격으로 작업을 수행합니다(일부 통계의 주간 보기가 일주일에 한 번 실행되는 등).

Wordpress와 같은 접근방식을 사용하면 누구나 가지고 있는 기본 사용자 정보가 포함된 사용자 테이블을 만들고 사용자 ID와 관련된 모든 키, 값 쌍이 될 수 있는 "user_meta" 테이블을 추가할 수 있습니다.따라서 사용자의 모든 메타 정보를 찾아야 할 경우 쿼리에 해당 정보를 추가할 수 있습니다.또한 로그인 등에 필요하지 않은 경우 항상 추가 쿼리를 추가할 필요는 없습니다.이 접근방식의 이점은 사용자의 트위터 핸들 저장이나 개별 관심사 저장 등 새로운 기능을 추가할 수 있는 테이블도 열어둔다.또한 모든 메타데이터를 관리하는 테이블이 1개 있고 50개가 아닌 1개의 연관성으로 제한되므로 미로처럼 얽힌 ID를 처리할 필요가 없습니다.

Wordpress는 특히 플러그인을 통해 기능을 추가할 수 있도록 하기 위해 이 기능을 수행하므로 프로젝트의 확장성이 향상되고 새로운 기능을 추가해야 할 경우 데이터베이스 전체를 점검할 필요가 없습니다.

저는 이것이 "상황에 따라 달라지는" 상황 중 하나라고 생각합니다.테이블이 여러 개 있는 것이 더 깨끗하고 이론적으로 더 나을 수 있습니다.그러나 한 명의 사용자에 대한 정보를 얻기 위해 6-7개의 테이블을 결합해야 하는 경우 이 방법을 재고하기 시작할 수 있습니다.

다른 테이블이 무엇을 의미하느냐에 따라 다르다고 말할 수 있습니다.user_details에 1명 이상의 사용자가 더 포함됩니까?요구에 가장 적합한 정규화 수준은 요구에 따라 달라집니다.

인덱스가 좋은 테이블이 하나 있으면 더 빠를 것 같아요.하지만 다른 한편으로 아마 유지하기가 더 어려울 것이다.

User_Details는 사용자와의 1:1 관계이기 때문에 생략할 수 있을 것 같습니다.하지만 나머지 부분은 사용자당 행이 많을 수 있습니다.

큰 테이블에서의 퍼포먼스에 관한 고려 사항

"좋아요" 및 "보기" (등)는 성능 면에서 1:1 관계에 유효한 몇 안 되는 케이스 중 하나입니다.이것은 매우 빈번하게 유지된다.UPDATE ... +1다른 활동에 간섭하지 않도록 하고 그 반대도 마찬가지입니다.
결론: 빈도가 높은 카운터를 매우 큰 테이블과 비지 테이블로 구분합니다.

다른 가능한 경우로는 드물게 나타나는 열 그룹이 있습니다.여러 개의 Null을 갖는 대신, 1:1에 관련된 별도의 테이블을 사용하거나 "1: 희귀"이라는 표현이 더 적합합니다.그 후 사용LEFT JOIN필요한 경우에만 사용할 수 있습니다.그리고 사용COALESCE()방향을 틀어야 할 때NULL안으로0.
결론:사정에 따라 다르겠지.

검색 조건을 한 테이블로 제한합니다.INDEX서로 다른 테이블의 열을 참조할 수 없습니다.WHERE여러 열에서 필터링하는 절은 한 테이블의 인덱스를 사용할 수 있지만 다른 테이블의 필터링 열을 계속하려면 더 많은 작업을 수행해야 합니다.이 문제는 특히 '범위'가 관련되어 있는 경우에는 더욱 심각합니다.
결론:이러한 열을 다른 테이블로 이동하지 마십시오.

TEXT 열과 BLOB 열은 부피가 클 수 있으며, 이는 특히 불필요한 경우 성능 문제를 일으킬 수 있습니다.SELECT *. 이러한 열은 "Off-record"(InnoDB)로 저장됩니다.즉, 이러한 데이터를 가져오는 데 드는 추가 비용이 디스크 적중률을 증가시킬 수 있습니다.
결론:이미 이노DB는 성능 '문제'를 해결하고 있다.

언급URL : https://stackoverflow.com/questions/1125004/which-is-more-efficient-multiple-mysql-tables-or-one-large-table

반응형