mysql에서 읽지 않은 기사를 가져오기 위한 데이터베이스 설계(1억 개 이상의 행 테이블)
이 정보는 매우 요약되어 있다.
테이블이 두 개 있어요.
기사
-----------------------------------
|id | weight | text |
-----------------------------------
|1 | 10 | blah |
|2 | 100 | blah |
|3 | 50 | blah |
|4 | 1000 | blah |
-----------------------------------
읽어주세요
-----------------------------------
| user_id | article_id |
-----------------------------------
| 1 | 4 |
| 1 | 2 |
| 1 | 3 |
| 2 | 3 |
| 2 | 4 |
-----------------------------------
아래 쿼리를 사용하여 읽지 않은 기사를 가져오고 싶다(매우 요약됨)
SELECT
a.*
FROM
article a LEFT OUTER JOIN read r ON r.article_id = a.id and r.user_id = 1
WHERE
r.id IS NULL
ORDER BY
a.weight DESC
LIMIT 10
중요한 정보
- 개수
read table
행은 사용자당 1000 미만입니다.(오래된 데이터 삭제)- 기사 테이블의 가중치 열이 자주 변경됩니다. (순서가 고정되지 않은 것을 의미합니다.)
문제는..(사용자 수: 100만 이상일 때)
- 읽기 표를 사용하여 읽지 않은 문서를 가져오는 방법(내부 조인은 중요하지 않습니다)
- 의 수
read table
행은 1G를 넘습니다.
- 의 수
지금까지는 잘 되고 있지만(현재 읽기 테이블 행 수 : 100M), 사용자가 급증하고 있어 다음 단계를 준비해야 합니다.
이 경우 대규모 서비스를 위한 최선의 방법은 무엇입니까?
(샤딩? 칸막이 테이블?)아키텍처를 재설계할 수 있습니까?)
잘 부탁드립니다
- 컬럼 추가
article
기사를 읽었는지 읽지 않았는지 여부를 나타내는 플래그가 됩니다.(사용자 수나 타임스탬프로 하지 마십시오.그렇게 하면 이후의 스텝이 느려집니다.) - 사용자가 기사를 읽을 때마다 플래그를 확인하고 필요에 따라 변경합니다.
- INDEX(flag, weight, id)가 있습니다.이것에 의해, 쿼리가 거의 즉시 실행됩니다.저 백만 줄 테이블 위에서는 이 정도면 될 거야.
문제:(1000 이후) 삭제 중이기 때문에 일부 "읽기" 기사는 "읽지 않음"이 될 수 있습니다.이 문제를 해결하려면 삭제를 배치하고 제거된 개별 문서 목록을 수집하십시오.그런 다음 플래그를 재계산하는 지루한 작업을 수행합니다. 단, 기사만 해당됩니다. INDEX(article_id)
도움이 되다; 사용하다EXISTS ( SELECT * FROM read WHERE article_id = $aid )
(이는 한 번에 한 가지 보조가 아닌 배치 조작으로 전환될 수 있습니다.)
또 다른 문제: 10억 행 테이블의 보조 키는 비용이 많이 듭니다. 많은 I/O가 발생할 수 있습니다.이 문제에 대처하기 전에 다음을 제공하십시오.SHOW CREATE TABLE
두 테이블 모두에 대해, 그리고 다른 공통에 대해SELECTs
. 적절한 인덱스와 데이터형을 선택하는 것은 10억 행 테이블에서의 퍼포먼스에 매우 중요합니다.
포인트는 가능한 한 인덱스를 사용하는 것입니다.
SELECT a.*
FROM a
LEFT JOIN read r
ON r.article_id = a.id and r.user_id =1
WHERE r.id IS NULL
ORDER BY a.weight DESC
LIMIT 10
편집: 관심사는 데이터 크기입니다.read
데이터 크기를 줄여야 합니다.그러기 위해서는 여러 가지 옵션이 있습니다.
- MySQL 파티션: user_id 범위에 파티션을 만듭니다(파티션당 사용자 수는 10만 명일 수 있습니다.
- 여러 테이블 만들기:분할과 비슷하지만, 데이터는 다른 데이터베이스(다른 DB 서버에도 있음)에 있습니다.user_id에 따라 가입할 테이블/데이터베이스를 결정합니다.
또한 오래된 데이터를 정기적으로 아카이브하는 것을 고려할 수 있습니다.어플리케이션은 아카이브된 테이블을 조회해야 하는지 라이브 테이블을 조회해야 하는지 결정할 수 있을 정도로 스마트해야 합니다.
언급URL : https://stackoverflow.com/questions/31553462/database-design-for-getting-unread-article-in-mysql-over-100m-row-table
'programing' 카테고리의 다른 글
문자열이 Unix 타임스탬프인지 확인합니다. (0) | 2022.09.15 |
---|---|
Vue CLI 3: 정의된 출력 경로 (0) | 2022.09.15 |
MDB(Access) 파일을 MySQL(또는 일반 SQL 파일)로 변환하려면 어떻게 해야 합니까? (0) | 2022.09.15 |
URL 개체(이미지)에서 파일 개체를 만드는 방법 (0) | 2022.09.15 |
최적의 GWT 위젯 라이브러리? (0) | 2022.09.15 |