문제

1 번 테이블:부엌 싱크대를 포함한 모든 것.잘못된 형식의 날짜(최근 연도이므로 해당 열에서 정렬할 수 없음), VARCHAR로 저장된 숫자, 'street' 열의 전체 주소, 이름 열의 이름과 성, 성 열의 도시, 불완전한 주소, 행 수년에 걸쳐 변경된 일부 규칙 세트, 중복 레코드, 불완전한 레코드, 가비지 레코드를 기반으로 한 필드에서 다른 필드로 데이터를 이동하여 앞의 행을 업데이트합니다.원하는대로 말만 해...아, 물론 TIMESTAMP 또는 PRIMARY KEY 열이 보이지 않습니다.

표2:이 아기가 열리자 정상화에 대한 희망은 창밖으로 사라졌습니다.각 항목에 대한 행과 표 1의 행 업데이트가 있습니다.따라서 내일은 없다(800MB 상당)와 같은 중복과 Phone1 Phone2 Phone3 Phone4와 같은 열...Phone15 (전화라고 부르지 않습니다.설명을 위해 이것을 사용합니다.) 외래 키는 ..그럼 추측해 보세요.table1의 행에 어떤 종류의 데이터가 있었는지에 따라 세 가지 후보가 있습니다.

표3:더 나빠질 수 있습니까?바로 이거 야."외부 키는 대시, 점, 숫자 및 문자의 VARCHAR 열 조합입니다!일치 항목을 제공하지 않는 경우(종종 그렇지 않음) 유사한 제품 코드의 두 번째 열이 있어야 합니다.내부 데이터와 상관 관계가 없는 이름이 있는 열과 필수 Phone1 Phone2 Phone3 Phone4...전화15.TIMESTAMP 또는 PRIMARY KEY 열이 아닌 Table1에서 복제된 열이 있습니다.

표4:진행 중인 작업으로 언제든지 변경될 수 있다고 설명되었습니다.그것은 본질적으로 다른 것들과 유사합니다.

1m에 가까운 행에서 이것은 큰 혼란입니다.다행히 그것은 나의 큰 혼란은 아니다.불행하게도 나는 각 "고객"에 대한 종합 기록을 꺼내야 했습니다.

처음에 저는 PRIMARY KEY를 추가하고 모든 날짜를 정렬 가능한 형식으로 변환하는 Table1의 4단계 변환을 고안했습니다.그런 다음 Table1을 사용하여 다른 테이블에서 가져와서 합성을 형성할 수 있을 때까지 필터링된 데이터를 반환하는 몇 가지 추가 쿼리 단계가 있습니다.몇 주 동안 작업한 후 몇 가지 트릭을 사용하여 이 작업을 한 단계로 마무리했습니다.이제 내 앱에서 문제가 있는 부분을 지적하고 깔끔하게 정리된 합성 데이터 테이블을 가져올 수 있습니다.운 좋게도 내 목적에 맞게 전화번호 중 하나만 필요하므로 테이블을 정규화하는 것은 문제가 되지 않습니다.

그러나 이것이 실제 작업이 시작되는 곳입니다. 매일 수백 명의 직원이 상상하고 싶지 않은 방식으로 이 데이터베이스를 추가/업데이트/삭제하고 매일 밤 새 행을 검색해야 하기 때문입니다.

모든 테이블의 기존 행은 변경될 수 있고 TIMESTAMP ON UPDATE 열이 없기 때문에 무슨 일이 일어났는지 알아보려면 로그를 참조해야 합니다.물론 이것은 바이너리 로그가 있다고 가정하지만 그렇지 않습니다!

개념 도입이 납 풍선처럼 내려갔습니다.나는 그들에게 그들의 아이들이 실험적인 수술을 받아야 할 것이라고 말했을 수도 있습니다.그들은 정확히 첨단 기술이 아닙니다 ...혹시 안 모였으면...

우리 회사가 몹시 원하는 귀중한 정보가 있기 때문에 상황은 조금 미묘합니다.나는 대기업의 고위 경영진으로부터 "이것을 실현하라"는 명령을 받았습니다.

야간 업데이트를 처리하는 다른 방법은 또 다른 애플리케이션으로 bin 로그 파일을 구문 분석하여 낮 동안 해당 데이터베이스에 수행한 작업을 파악한 다음 그에 따라 테이블을 합성하는 것 외에는 다른 방법이 없다고 생각합니다.나는 정말로 내 테이블에 무엇을 해야 할지 알아내기 위해 그들의 테이블1만 보면 됩니다.다른 테이블은 레코드를 플러시하는 필드만 제공합니다.(MASTER SLAVE를 사용하면 혼란스러운 내용이 중복되므로 도움이 되지 않습니다.)

대안은 테이블의 모든 행에 대해 고유한 해시를 생성하고 해시 테이블을 구축하는 것입니다.그런 다음 매일 밤 전체 데이터베이스를 검토하여 해시가 일치하는지 확인합니다.그렇지 않은 경우 해당 레코드를 읽고 내 데이터베이스에 존재하는지 확인하고, 존재하는 경우 데이터베이스에서 업데이트하고, 그렇지 않은 경우 새 레코드를 삽입합니다.이는 추악하고 빠르지도 않지만 바이너리 로그 파일을 구문 분석하는 것도 좋지 않습니다.

나는 문제를 명확히 하는 데 도움을 주기 위해 이 글을 썼습니다.종종 다른 사람에게 이야기하면 문제를 명확하게 하여 해결책을 더 명확하게 만드는 데 도움이 됩니다.이 경우에는 두통이 더 커집니다!

귀하의 의견에 크게 감사하겠습니다.

도움이 되었습니까?

해결책

로그 파일(바이너리 로그)도 제가 처음으로 생각한 것이었습니다.그들이 어떻게 일을 했는지 안다면 당신은 몸서리칠 것입니다.각 행마다 조각이 추가되고 변경됨에 따라 로그에 많은 항목이 있습니다.정말 거대해요!지금은 해시 접근 방식을 선택했습니다.영리한 파일 메모리 페이징을 사용하면 매우 빠릅니다.

다른 팁

저는 MySQL 사용자가 아니기 때문에 이것은 좌익수에서 나온 것입니다.

하지만 내 생각엔 로그 파일이 답이 될 수도 있을 것 같아.

다행히도 로그에서 2가지 사항만 알면 됩니다.

레코드/rowid가 필요하고 작업이 필요합니다.

대부분의 DB에는(MySQL이라고 가정) 각 행에 rowid나 Recordid 등과 같은 암시적 열이 있습니다.데이터베이스에서 사용하는 내부 행 번호입니다.이것이 "무료" 기본 키입니다.

다음으로 수술이 필요합니다.행에 대한 삽입, 업데이트 또는 삭제 작업인지 여부가 특히 중요합니다.

이 모든 정보를 시간 순서대로 통합한 다음 이를 실행합니다.

삽입/업데이트할 때마다 원본 DB에서 행을 선택하고 대상 DB에 해당 행을 삽입/업데이트합니다.삭제인 경우 행을 삭제합니다.

필드 값은 중요하지 않으며 중요하지 않습니다.행 전체를 수행하십시오.

바이너리 로그 파일을 "파싱"할 필요는 없기를 바랍니다. MySQL에는 이미 이를 수행하는 루틴이 있어야 하며, 이를 사용하는 방법을 찾아서 알아내기만 하면 됩니다(사용할 수 있는 편리한 "덤프 로그" 유틸리티가 있을 수도 있음) ).

이를 통해 시스템을 매우 단순하게 유지할 수 있으며 전체 DB 크기가 아닌 하루 동안의 실제 활동에만 의존해야 합니다.마지막으로 나중에 "더 스마트하게" 만들어 최적화할 수 있습니다.예를 들어 행을 삽입한 다음 업데이트하고 삭제할 수 있습니다.리플레이에서 해당 행을 완전히 무시할 수 있다는 것을 알고 계실 것입니다.

실제로 로그 파일을 읽으려면 약간의 난해한 지식이 필요하지만 나머지는 간단해야 합니다.로그 파일에도 타임스탬프가 표시되어 "오늘부터" 행 또는 원하는 날짜 범위에서 작업하는 방법을 알 수 있다고 생각하고 싶습니다.

이 데이터베이스에 액세스하는 기존 코드를 사용하여 필요에 맞게 조정할 수 없습니까?물론 코드가 형편없겠지만, ~할 것 같다 당신을 위해 데이터베이스 구조를 처리해 주세요. 그렇죠?그러면 고고학자 역할을 하는 대신 작업을 완료하는 데 집중할 수 있기를 바랍니다.

maatkit의 mk-table-sync 도구를 사용하여 스테이징 데이터베이스를 동기화할 수 있습니다(결국 데이터베이스는 매우 작습니다).이것은 "혼란을 복제"할 것입니다

그런 다음 동기화 후에 다양한 쿼리를 수행하여 보고할 수 있는 보다 정상적인 테이블 집합을 생성하는 내용을 작성할 수 있습니다.

나는 이것이 성능 문제 없이 매일 수행될 수 있다고 상상한다.

다른 서버에서 이 모든 작업을 수행하면 원본 데이터베이스에 영향을 주지 않습니다.

내가 볼 수 있는 유일한 문제는 일부 테이블에 기본 키가 없는 경우입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top