대규모 데이터셋을 위한 데이터베이스 설계
저는 현재 데이터베이스 테이블에서 몇 억 개의 레코드를 저장할 수 있는 곳을 설계하는 작업을 하고 있는데, 이를 관리하는 가장 좋은 방법이 무엇인지 궁금합니다.이러한 종류의 데이터셋을 사용하면 결국 테이블 복원이나 테이블 교체에 오랜 시간이 소요되는 등의 유지보수 문제가 발생할 수 있습니다.이제 그것을 어떻게 처리해야 할지 몇 가지 아이디어가 있습니다. 하지만 더 나은 방법이 있을까요?
최신 데이터일수록 관련성이 높기 때문에 짧은 시간 범위(예: 지난 30일)와 이전 데이터 세트(지난 30일보다 오래됨)로 나눌 수 있습니다.이를 위해 저는 두 가지 가능성을 봅니다.
현재 파티션과 이전 데이터 파티션의 두 파티션으로 분할
장점:
- 테이블 복원은 크기가 크지 않기 때문에 현재 데이터 파티션을 빠르게 복원할 수 있습니다.긴급 상황이 발생할 경우 이를 먼저 복구한 후 해당 데이터만 사용하여 시스템을 다시 시작합니다.이것은 사용자에게 허용 가능한 시나리오입니다.
- 정상적으로 테이블을 읽고 쓸 수 있으므로 특정 애플리케이션 로직이 필요하지 않습니다.
단점:
- 마이그레이션 스크립트(온라인에서 사용할 수는 있지만 올바르게 사용하면 모든 사용 사례에서 사용할 수 없음)는 두 파티션 모두에서 실행되기 때문에 오랜 시간이 걸립니다.이에 대한 해결책은 사용자의 기존 데이터 파티션을 오프라인으로 전환하여 백그라운드에서 실행하는 것입니다.따라서 사용자는 그 시간 동안 이전 데이터에 액세스할 수 없지만 괜찮습니다.이런 일이 가능합니까?
수동으로 두 테이블로 분할하고 야간 작업으로 데이터를 이동합니다.위에 데이터를 선택할 수 있는 뷰를 배치합니다.
장점:
- 이전 데이터 테이블을 더 이상 보기에 포함하지 않음으로써 오프라인으로 전환하고 대체 테이블 스크립트를 실행할 수 있습니다.작업이 완료되면 보기로 다시 이동합니다.사용자가 데이터를 더 이상 찾을 수 없기 때문에 수정할 수도 없습니다.
- 테이블 복원은 현재 테이블을 먼저 복원하고 보기를 업데이트한 후 사용자가 다시 사용할 수 있도록 하므로 신속합니다.이전 데이터 테이블을 복원하는 데 시간이 좀 걸릴 수 있지만 괜찮습니다.
단점:
- 뷰이기 때문에 우리는 그것을 통해서만 선택할 수 있습니다.데이터를 수정하는 경우 사용자가 이전 데이터를 업데이트하기를 원하기 때문에 두 테이블 모두에 대한 업데이트 쿼리를 작성해야 합니다.따라서 애플리케이션 관점에서 맞춤형 로직이 필요합니다.
그래서 제 질문은, 이런 종류의 시나리오에서 최선의 방법은 무엇인가 하는 것입니다.어떻게 하면 좋겠습니까?
감사해요.
몇 억이라는 것은 많은 양이지만, 오늘날에는 큰 데이터 세트가 아닙니다.대규모 데이터 세트에는 수십억 개의 레코드가 있습니다.문제는 데이터가 얼마나 빠르게 증가하고 있느냐는 것입니다.어떤 종류의 쿼리를 실행합니까?데이터 증가 속도가 매우 느리면 데이터베이스 소프트웨어가 파티션 없이도 충분히 빠르게 처리할 수 있습니다.빠르게 성장하고 있다면 파티션을 분할하는 것이 좋습니다.
OLTP 워크로드가 너무 작아서 대기 시간이 길지만 쿼리 수가 많은 경우 핫 데이터를 별도의 장소에 보관하는 것이 좋습니다.시간에 따라 다르다면 날짜/시간 열을 기준으로 연도별로 분할된 기본 파티션을 사용하는 것이 좋습니다.이러한 방식으로 최근 데이터를 기반으로 하는 대부분의 쿼리는 최신 파티션과 전체 데이터 세트의 매우 작은 부분만 확인합니다.
최근이 1개월과 같이 매우 짧은 기간을 의미한다면, 위의 방법은 여전히 유용하지만 충분하지 않습니다.그 위에 또 다른 핫 데이터 테이블을 만들 수 있습니다.이제 연도별로 분할된 빅 데이터 테이블(항상 모든 데이터 포함)과 최근 데이터가 포함된 작은 테이블이 있습니다.단점을 극복하기 위해 다음을 수행할 수 있습니다.
- 업데이트/삽입/삭제
- 모든 쿼리는 기본 테이블로 이동합니다. 각 작업에 대한 트리거는 필요한 경우 핫 데이터 테이블의 작업을 복제합니다. (데이터베이스 수준 논리)
또는 두 테이블 모두에 관련 쿼리를 전송하여 애플리케이션 수준(애플리케이션 수준 로직)에서 일관성을 유지할 수 있습니다.mysql 트리거는 데이터베이스 속도를 더 늦출 수 있기 때문에 성능이 더 좋을 수 있습니다.
SELECT 쿼리는 쿼리에 따라 새 테이블로 이동합니다. 그렇지 않으면 주 테이블로 이동합니다(연간 분할이 성능 향상에 도움이 됩니다).유연하게 사용하려면 프록시를 사용하여 쿼리 분할을 수행할 수도 있습니다.Proxysql은 이를 쉽게 처리할 수 있습니다.캐싱 및 연결 다중화와 같은 다른 이점도 있습니다.
핫 데이터 테이블에서 오래된 데이터를 삭제하려면 매일 이벤트를 실행하여 1개월 이상 된 레코드를 삭제할 수 있습니다.삭제할 수만 개의 데이터가 있는 경우 잠금, 지연 및 대량 리소스 사용과 같은 문제를 방지하기 위해 더 작은 청크로 삭제해야 합니다.또 다른 방법은 is_deleted 열을 사용하여 오래된 레코드를 식별하고 이를 통해 파티션을 분할하는 것입니다.언제든지 파티션을 즉시 삭제할 수 있습니다.
비차단 DDL 작업을 위해 성능을 크게 저하시키지 않고 스키마를 온라인으로 마이그레이션할 수 있는 오픈 소스 도구가 있습니다.pt-schema-change 및 고스트를 확인하십시오.
(이전 데이터와 새 데이터에 집중)
테이블이 다소 시간순으로 정렬되어 있고 대부분 "새로운" 데이터에 액세스하는 경우, 테이블이 제공하는 상당한 양의 캐슁 및 성능이 자동으로 내장됩니다.
InnoDB를 사용하고 다음을 수행하십시오.PRIMARY KEY
…이 되다AUTO_INCREMENT
(또는 a로 시작)DATETIME
).
숫자를 몇 개 실행해 보겠습니다.테이블에 300M개의 행이 있고 각 행에 100바이트(간단한 경험의 법칙)가 사용되는 경우 테이블의 데이터는 30GB가 사용됩니다.인덱스 및 기타 테이블에 대한 추가 정보가 있을 것입니다.64GB RAM이 있는 서버에서 실행 중이라면(현재는 무리가 아님) 모든 것이 RAM에 들어맞고 많은 I/O가 필요하지 않을 수 있습니다.
대신 RAM이 8GB에 불과하고 대부분의 작업이 최신 10%의 테이블에 포함된 경우에도 잘 캐시됩니다.
(참고: I/O는 성능의 가장 큰 하드웨어 구성 요소입니다.)
일반적으로 대형 테이블의 설계에 영향을 미치는 것은 인덱싱, 쿼리 공식화 또는 전체 아키텍처입니다.하지만, 당신이 그런 것에 대한 세부사항이 없기 때문에, 저는 그것을 건너뜁니다.
당신은 테이블을 분할하는 조잡하고 수동적인 방법을 언급했습니다.다음과 같은 기능이 기본으로 제공됩니다.PARTITIONing
그러나 삽입, 업데이트 또는 선택에 도움이 될 것 같지 않으므로 추가적인 논의 없이는 권장하지 않습니다.
결국 "이전" 데이터를 삭제할 경우(예: 1년 후),PARTITIONing
좋은 생각입니다.1년 데이터만 저장하는 테이블이라면 주간 파티션을 사용할 것입니다.당신이 필요하다면 우리는 이것에 대해 더 논의할 수 있습니다.그러나 다음을 통해 이전 데이터를 삭제하는 것이 유일한 이점입니다.DROP PARTITION
파티셔닝은.
SUBPARTITIONs
아무 것도 도와주지 마.
언급URL : https://stackoverflow.com/questions/55311779/database-design-for-large-datasets
'programing' 카테고리의 다른 글
파이썬 코드를 효과적으로 난독화하는 방법은? (0) | 2023.07.25 |
---|---|
Oracle에서 문자 집합 불일치 오류 (0) | 2023.07.25 |
인텐트(최적의 솔루션)를 통해 열거나 개체 전달 (0) | 2023.07.25 |
오류로 인한 Gulp Watch 깨짐 (0) | 2023.07.25 |
매우 큰 테이블에서 Mysql 개수 성능 (0) | 2023.07.25 |