SQL 데이터베이스에 데이터를 로드하는 방법: 단순 삽입에서 대량 로드까지
8734 단어 datasciencesqldatabasepostgres
데이터베이스에 데이터를 삽입하는 첫 번째이자 가장 쉬운 방법은 ORM(Object-Relational Mapping) 도구를 사용하는 것입니다. 이 튜토리얼의 목적을 위해 저는 Rails의 ActiveRecord를 ORM 작업의 데모로 사용할 것입니다. ORM을 통해 데이터를 삽입하면 모든 비즈니스 규칙 및 유효성 검사가 실행되므로 걱정할 필요가 없습니다. 다음과 같이 하면 쉽습니다.
Users.create(username: "John Doe", role: "admin")
이 방법의 단점은 확장되지 않는다는 것입니다. 각 레코드에 대해 모델 객체를 생성하고 검증 및 비즈니스 규칙을 위해 첨부된 콜백을 실행하며 DML 트랜잭션을 실행합니다.
일부 프레임워크는 대신 대량 삽입을 수행하는 방법을 제공합니다. 단일
INSERT
SQL 쿼리가 준비되고 단일 sql 문이 모델을 인스턴스화하거나 모델 콜백 또는 유효성 검사를 호출하지 않고 데이터베이스로 전송됩니다. 예를 들어, Rails 6에서는 다음과 같습니다.result = Users.insert_all(
[
{ id: 1,
username: 'John Doe',
role: 'admin' },
{ id: 2,
username: 'Jane Doe',
role: 'admin' },
]
)
또는 정확히 동일한 효과를 가지므로 원시 SQL로 수행할 수 있습니다.
INSERT INTO
users(id, username, role)
VAULES
(1, "John Doe", "admin"),
(2, 'Jane Doe', "admin");
두 솔루션 모두 충돌(예: 기본 키 고유성 또는 부적합한 데이터 유형 위반)이 있거나 비즈니스 역할 또는 상위 수준 응용 프로그램 유효성 검사 규칙을 위반할 수 있습니다. 두 경우 모두 프로그래머는 데이터베이스 수준 오류를 처리하고 상위 수준 규칙의 실행 또는 준수를 보장하여 문제를 처리해야 합니다. 예를 들어 기본 키 열 열의 중복을 무시하려면 쿼리 끝에 다음과 같이 추가할 수 있습니다.
ON CONFLICT (id) DO NOTHING;
로드된 데이터에 데이터베이스의 기존 행에 대한 업데이트가 포함되어 있으면 어떻게 됩니까? 이 작업을 upsert라고 합니다. 테이블에 행이 이미 있는 경우(기본 키에 따라 존재 여부 판별) 전달된 값으로 행이 업데이트됩니다. 그렇지 않으면 새 행으로 삽입됩니다. Rails 6에서는
insert_all
함수를 upsert_all
로 바꾸는 것만큼 쉽습니다.result = Users.upsert_all(
[
{ id: 1,
username: 'John Doe',
role: 'admin' },
{ id: 2,
username: 'Jane Doe',
role: 'admin' },
]
)
SQL에서는 다음과 같을 것입니다.
INSERT INTO
users(id, username, role)
VAULES
(1, 'John Doe', 'admin'),
(2, 'Jane Doe', 'admin')
ON DUPLICATE KEY
UPDATE id=VALUES(id), username=VALUES(username), role=VALUES(role);
이 방법의 확장성은 여전히 제한적입니다. 대부분의 서버에는 쿼리 길이에 대한 최대 제한이 있으며 제한이 없더라도 네트워크를 통해 기가바이트 단위의 길이로 쿼리를 보내고 싶지는 않을 것입니다. 간단한 해결책은
UPSERT
일괄 처리하는 것입니다. 다음과 같을 것입니다.record_num = records.length
batch = 1000
batch_num = record_num / 1000
(1..batch_num).do |n|
lower_bound = (batch_num - 1) * batch
higher_bound = batch_num * batch
Users.upsert_all(records[lower_bound..higher_bound])
end
또는
upsert_all
함수 대신 원시 SQL을 사용합니다. 같은 것.이 솔루션은 기술적으로 잘 확장됩니다. 그러나 성능을 높이기 위해 대부분의 SQL 데이터베이스에는 파일에서 테이블로 데이터를 로드하는 복사 기능이 있습니다. 해당 기능을 사용하기 위해 데이터는 데이터베이스 엔진이 지원하는 형식(일반적인 형식은 CSV)으로 파일에 덤프됩니다. 그런 다음 테이블은 다음과 같은 SQL 명령으로 파일에서 채워집니다.
COPY users FROM 'path/to/my/csv/file.csv';
이 문은 CSV 파일 내의 모든 데이터를 사용자 테이블에 추가합니다. 이 솔루션은 여러 GB 데이터 규모의 파일에 대해 훨씬 더 나은 성능을 제공할 수 있습니다.
그러나 이 솔루션은 upsert를 처리하지 않습니다. 이렇게 하려면 임시 테이블을 만들고 파일에서 채운 다음 기본 키를 사용하여 원래 테이블에 병합합니다.
CREATE TEMP TABLE tmp_table
...; /* same schema as `users` table */
COPY tmp_table FROM 'path/to/my/csv/file.csv';
INSERT INTO users
SELECT *
FROM tmp_table;
이 솔루션은 데이터베이스에 대한 다중 트랜잭션을 방지하고 더 높은 성능을 보장합니다. 데이터베이스에 GB의 데이터를 로드할 때 조사할 가치가 있습니다.
Reference
이 문제에 관하여(SQL 데이터베이스에 데이터를 로드하는 방법: 단순 삽입에서 대량 로드까지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tariqabughofa/how-to-load-data-into-an-sql-database-from-simple-inserts-to-bulk-loads-4352텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)