SQLite 빅데이터 증가/수정 효율성 향상 방법

신규
SQLite의 새로운 기본값은 하나의 사무 제어입니다. 한 번의 추가는 데이터베이스 조작이고 한 번의 사무입니다.만약 수천 번의 for 순환 조작을 한다면 반드시 효율 문제가 존재할 것이다.다음 코드는 트랜잭션 제어를 통해 효율성을 향상시킵니다.
public void addList(List<GroupMember> listMember) {
	StringBuffer sbSQL = new StringBuffer();
	
	SQLiteDatabase db = super.getDatabase();
	db.beginTransaction();
	for (int i = 0; i < listMember.size(); i++) {
		GroupMember groupMember = listMember.get(i);
		if(i == 0) {
			//       id   id      
			del(groupMember.getUserId(), groupMember.getGroupId());//               
		}
		
		if(i != 0) {
			sbSQL.delete(0, sbSQL.length());
		}
		sbSQL.append(" INSERT INTO ").append(TABLE).append(" (user_id, group_id, member_id, role_id) VALUES");
		sbSQL.append(" (").append(groupMember.getUserId())
			.append(",").append(groupMember.getGroupId())
			.append(",").append(groupMember.getMemberId())
			.append(",").append(groupMember.getRole())
			.append(");");
		db.execSQL(sbSQL.toString());
	}
	db.setTransactionSuccessful();
	db.endTransaction();
}

가능한 한 아래의 SQL 문법을 사용하지 마라. 일부 기종에서는 오류가 발생할 수 있다.(샤오미, 삼성S3).위의 글씨는 이미 수요를 만족시킬 수 있다..
INSERT INTO table(column1, column2) VALUES(val1, val2), (val1, val2)

대량으로 추가된 쓰기 방법은 설명할 것이 없으니, 아래의 대량 수정을 공유합니다.
2. 대량 수정
수요의 출현: 예를 들어 N개의 채팅방이 존재하고 그 안에 N명의 멤버가 있다.매번 링에 들어갈 때마다 백엔드 라인은 링 구성원의 최신 데이터를 다운로드하고 데이터베이스를 업데이트한다.이때 세 개의 시계가 존재한다. 바로 동그라미, 동그라미-구성원 관계표, 사용자표이다.
사용자표는 모든 범위의 사용자로 저장할 때 존재 여부를 판단하고 존재하면 새로 추가한다. 그렇지 않으면 일부 데이터를 수정한다.(사용자가 상세한 자료를 가지고 있기 때문에 범위 구성원이 되돌아오는 것은 이름, 계정, 이미지 세 필드만 있고 위의 방법으로 모든 데이터를 먼저 삭제한 다음에 대량으로 추가할 수 없다)
SQL 크리티컬 쓰기 방법은 다음과 같습니다(SQLiteDatabase.insertWithOnConflict의 사용법에 중점을 두었습니다).
public void insertOrReplace(List<GroupMember> listMember) {
	SQLiteDatabase db = super.getDatabase();
	db.beginTransaction();
	for (int i = 0; i < listMember.size(); i++) {
		BaseUserInfo baseUserInfo = listMember.get(i).getBaseUserInfo();
		ContentValues cv = new ContentValues();
		cv.put("user_id", baseUserInfo.getUserId());
		cv.put("name", baseUserInfo.getName());
		cv.put("logo", baseUserInfo.getLogo());
		
		//    sql  INSERT INTRO OR REPLACE INTO     (             .             ,       userId).             
		db.insertWithOnConflict(TABLE, null, cv, SQLiteDatabase.CONFLICT_REPLACE);
	}
	db.setTransactionSuccessful();
	db.endTransaction();
}

중요한 부분:
insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm)
부분 매개변수 소개(매개변수 table과 initialValues 무시, 그건 다들 아시죠--):
1)null Column Hack:values 매개 변수가 비어 있거나 안에 내용이 없을 때, 우리 insert는 실패합니다. (밑바닥 데이터베이스에 빈 줄을 삽입할 수 없습니다.) 이러한 상황을 방지하기 위해서, 우리는 여기에 열 이름을 지정합니다. 삽입할 행위가 비어 있는 줄을 발견하면 이 열 이름의 값을null로 설정합니다.그리고 데이터베이스에 삽입하세요.(실제 개발에서는 일반적으로null로 설정하면 됩니다.)
예를 들어values가 비어 있으면 마지막에 생성된 SQL이'INSERT INTO table'일 것이다. 그러면 이것은 잘못된 SQL이므로 삽입에 실패할 것이다.그러나 null Column Hack을 지정하면 최종적으로 SQL "INSERT INTO TABLE ("+ null Column Hack + ")"VALUES (null) "가 생성됩니다. 데이터가 없는 줄을 삽입하지만 SQL은 잘못 보고하지 않습니다.
실제 안드로이드 소스는 다음과 같습니다.
public long insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm) {
	acquireReference();
	try {
		StringBuilder sql = new StringBuilder();
		sql.append("INSERT");
		sql.append(CONFLICT_VALUES[conflictAlgorithm]);		//     ,     
		sql.append(" INTO ");
		sql.append(table);
		sql.append('(');

		Object[] bindArgs = null;
		int size = (initialValues != null && initialValues.size() > 0) ? initialValues.size() : 0;
		if (size > 0) {
			bindArgs = new Object[size];
			int i = 0;
			for (String colName : initialValues.keySet()) {
				sql.append((i > 0) ? "," : "");
				sql.append(colName);
				bindArgs[i++] = initialValues.get(colName);
			}
			sql.append(')');
			sql.append(" VALUES (");
			for (i = 0; i < size; i++) {
				sql.append((i > 0) ? ",?" : "?");
			}
		} else {
			sql.append(nullColumnHack + ") VALUES (NULL");
		}
		sql.append(')');

		SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
		try {
			return statement.executeInsert();
		} finally {
			statement.close();
		}
	} finally {
		releaseReference();
	}
}

2) conflictAlgorithm:
이 매개 변수는 int 값입니다. 위 원본에서도 사용되었습니다. (CONFLICT VALUES [conflict Algorithm]) 그러면 CONFLICTVALUES 의 값은 무엇입니까?Android 소스는 다음과 같습니다.
public static final int CONFLICT_ROLLBACK = 1;

public static final int CONFLICT_ABORT = 2;

public static final int CONFLICT_FAIL = 3;

public static final int CONFLICT_IGNORE = 4;

public static final int CONFLICT_REPLACE = 5;

public static final int CONFLICT_NONE = 0;

private static final String[] CONFLICT_VALUES = new String[]{"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};

자, 결합 방법인 insert With On Conflict의 원본 코드와 함께 알 수 있습니다. 이 인자를 지정하면 최종적으로 얻을 수 있는 SQL은 "INSERT OR REPLACE INTO table(column1,column2...)"입니다.VALUES(val1, val2...)"이런 격식은...
이렇게 하면 처음에 말한 수요 발생 장면에서 겪은 성능 병목을 해결할 수 있다.
나눠서 필요한 사람에게 도움이 되었으면 좋겠습니다.

좋은 웹페이지 즐겨찾기