sqlite에 존재하지 않는 스키마가 있는지 확인하세요.

sqlite에 존재하지 않는 스키마가 있는지 확인하세요.

일반 텍스트 파일로 비슷한 상황을 설명했습니다.거대한 파일에서 많은 수의 패턴을 Grep합니다.. 많은 사람들이 내가 이 작업을 수행해야 한다고 말했기 때문에 이제 데이터를 sqlite 데이터베이스로 마이그레이션하고 있습니다.

약 10,000개의 패턴을 추출한 파일이 있습니다. 그런 다음 데이터베이스에 해당 스키마가 포함되어 있지 않은지 확인합니다. 그렇지 않은 경우 file추가 처리를 위해 외부에 저장해야 합니다 .

for id in $(grep ^[0-9] keys); do
  if [[ -z $(sqlite3 db.sqlite "select id from main where id = $id") ]]; then
    echo $id >>file
  fi
done

저는 SQL을 처음 접했기 때문에 이 작업을 수행하는 쉬운 방법을 찾을 수 없습니다. 또한 이 루프는 awk위 URL에서 구현한 것보다 20배 느리기 때문에 쓸모가 없습니다.

데이터베이스가 크고 성장하고 있으며 이 루프를 매우 자주 실행하므로 더 빠르게 만들 수 있습니까?

답변1

sqlite각 모드에 대해 데이터베이스에 다시 연결하는 프로그램의 새 인스턴스를 호출합니다. 정말 낭비입니다. 키를 찾는 쿼리를 작성한 다음 해당 쿼리를 실행해야 합니다. 데이터베이스 클라이언트는 대규모 쿼리를 실행하는 데 능숙합니다.

파일의 일치하는 줄에 keys숫자만 포함된 경우 다음과 같이 쿼리를 작성할 수 있습니다.

{
  echo 'select id from main where id in (';
  <keys grep -x '[0-9][0-9]*' |     # retain only lines containing only digits
  sed -e '1! s/^/, /' |             # add ", " at the beginning of every line except the first
  echo ');'
} | sqlite3 db.sqlite

보다 일반적인 입력 데이터의 경우 텍스트 변환을 사용하여 하나의 대규모 쿼리를 작성하는 아이디어를 얻을 수 있습니다. 주의 깊은입력 확인;여기서 쿼리에 삽입한 내용이 구문적으로 유효한지 확인합니다. 위의 예에는 실제로 극단적인 경우가 있습니다. 파일에 일치 항목이 없으면 SQL 구문이 유효하지 않습니다. 파일에 일치 항목이 없으면 SQL 구문이 유효하지 않습니다. 가능하다면 이 상황을 처리해야 합니다. 특별히. null 사례를 처리하는 더 복잡한 코드는 다음과 같습니다.

<keys grep -x '[0-9][0-9]*' |
if read first; then {
    echo 'select id from main where id in (' "$first"
    sed -e 's/^/, /'
    echo ');'
  } | sqlite3 db.sqlite
fi

답변2

먼저 if목록으로 바꾸었습니다. 사실 나는 [[]]s를 s로 바꾼 []다음 실행 dash하거나 더 가벼운 것을 실행할 수도 있습니다 sh. 이것은 모든 것을 삭제 for하고 실행할 수 있을 만큼 간단해 보입니다 xargs(항상 제가 선호하는 것, 더 나은 성능). 예를 들어 다음과 같습니다...

grep ^[0-9] keys | xargs -P0 -I '{id}' \
sh -c '[ -z "$(sqlite3 db.sqlite =\"select id from main where id = '{id}'\")" ] && \
echo '{id}' >> file'

내 탈출은 실패했을 가능성이 크지만, 이것이 당신에게 올바른 방향을 알려줄 것입니다. 적어도 병렬로 실행되기 때문에 이것이 더 빠르게 수행될 것이라고 생각합니다 -P.

어떤 이유로 인해 크롤링 중이더라도 덤프된 sqlite 데이터베이스의 내용을 항상 볼 수 있습니다. 이 접근 방식을 취하면 아마도 스크립트를 작성하게 될 것입니다. 필요한 경우에만 고려하겠습니다.

답변3

ID를 새 테이블로 가져와 이를 사용하여 main테이블을 쿼리합니다. 사용 후 테이블을 버리십시오.

{ echo id; grep '^[0-9]' keys; } |
sqlite3 database.db \
    'CREATE TABLE ids ( id INTEGER UNIQUE )' \
    '.import /dev/stdin ids' \
    'SELECT * FROM main NATURAL JOIN ids' \
    'DROP TABLE ids'

시험:

sqlite> .mode box
sqlite> SELECT * FROM main;
┌────┬─────────────────┐
│ id │      word       │
├────┼─────────────────┤
│ 1  │ concessionaire  │
│ 2  │ goniometrically │
│ 3  │ meshed          │
│ 4  │ Celtic          │
│ 5  │ guiltless       │
│ 6  │ sclerodactylia  │
│ 7  │ spiritism       │
│ 8  │ ratchel         │
│ 9  │ Bajau           │
│ 10 │ semimineral     │
└────┴─────────────────┘
$ cat keys
3
7
78
190

주어진 명령을 실행하면 다음이 출력됩니다( ID만 출력하는 id대신 선택됨).*

3|meshed
7|spiritism

관련 정보