2014-06-17 2 views
2

저는 Person과 Company의 두 엔티티가있는 간단한 데이터 모델을 가지고 있습니다. 한 사람을 여러 회사에 배정 할 수 있고 한 회사를 여러 사람에게 배정 할 수 있습니다. 필자는 데이터베이스 1 개와 회사 2 개를 채우고 모든 사람을 회사에 할당했습니다. 데이터베이스를 작성하는 과정에서, 코어 데이터 생성 로그는 아래에 제시 :코어 데이터의 관계에서 오브젝트를 삭제하는 올바른 방법

CoreData: sql: INSERT INTO ZCOMPANY(Z_PK, Z_ENT, Z_OPT, ZNAME) VALUES(?, ?, ?, ?) 
CoreData: sql: INSERT OR REPLACE INTO Z_1PERSONS(Z_1COMPANIES, Z_2PERSONS) VALUES (1, 2) 
CoreData: sql: INSERT OR REPLACE INTO Z_1PERSONS(Z_1COMPANIES, Z_2PERSONS) VALUES (1, 1) 
CoreData: sql: INSERT INTO ZPERSON(Z_PK, Z_ENT, Z_OPT, ZNAME) VALUES(?, ?, ?, ?) 
CoreData: sql: INSERT INTO ZPERSON(Z_PK, Z_ENT, Z_OPT, ZNAME) VALUES(?, ?, ?, ?) 

다음 나는 다시 시작하고 회사를 삭제하고, 응용 프로그램을 닫습니다. 핵심 데이터는 다음 작업을 수행 :

CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1PERSONS t1 JOIN ZPERSON t0 ON t0.Z_PK = t1.Z_2PERSONS WHERE t1.Z_1COMPANIES = ? 
CoreData: annotation: sql connection fetch time: 0.0009s 
CoreData: annotation: total fetch execution time: 0.0018s for 2 rows. 
CoreData: annotation: to-many relationship fault "persons" for objectID 0x8d281e0 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Company/p1> fulfilled from database. 
Got 2 rows 
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME FROM ZPERSON t0 WHERE t0.Z_PK = ? 
CoreData: annotation: sql connection fetch time: 0.0008s 
CoreData: annotation: total fetch execution time: 0.0016s for 1 rows. 
CoreData: annotation: fault fulfilled from database for : 0x8e19940 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p1> 
CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1PERSONS t1 JOIN ZCOMPANY t0 ON t0.Z_PK = t1.Z_1COMPANIES WHERE t1.Z_2PERSONS = ? 
CoreData: annotation: sql connection fetch time: 0.0009s 
CoreData: annotation: total fetch execution time: 0.0022s for 1 rows. 
CoreData: annotation: to-many relationship fault "companies" for objectID 0x8e19940 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p1> fulfilled from database. 
Got 1 rows 
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME FROM ZPERSON t0 WHERE t0.Z_PK = ? 
CoreData: annotation: sql connection fetch time: 0.0006s 
CoreData: annotation: total fetch execution time: 0.0014s for 1 rows. 
CoreData: annotation: fault fulfilled from database for : 0x8e18f90 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p2> 
CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1PERSONS t1 JOIN ZCOMPANY t0 ON t0.Z_PK = t1.Z_1COMPANIES WHERE t1.Z_2PERSONS = ? 
CoreData: annotation: sql connection fetch time: 0.0006s 
CoreData: annotation: total fetch execution time: 0.0015s for 1 rows. 
CoreData: annotation: to-many relationship fault "companies" for objectID 0x8e18f90 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p2> fulfilled from database. 
Got 1 rows 
CoreData: sql: BEGIN EXCLUSIVE 
CoreData: sql: DELETE FROM ZCOMPANY WHERE Z_PK = ? AND Z_OPT = ? 
CoreData: sql: DELETE FROM Z_1PERSONS WHERE Z_1COMPANIES = 1 
CoreData: sql: UPDATE ZPERSON SET Z_OPT = ? WHERE Z_PK = ? AND Z_OPT = ? 
CoreData: sql: UPDATE ZPERSON SET Z_OPT = ? WHERE Z_PK = ? AND Z_OPT = ? 
CoreData: sql: COMMIT 

코어 데이터는 데이터베이스에서 삭제 된 회사에 할당 된 사람을 가져옵니다. 다음으로 모든 사람을위한 회사 모음을 가져옵니다. 결국 예상 삭제 작업이 데이터베이스에서 실행됩니다 : 나는 회사를 삭제하면

DELETE FROM ZCOMPANY WHERE Z_PK = ? AND Z_OPT = ? 
DELETE FROM Z_1PERSONS WHERE Z_1COMPANIES = 1 

하는 managedObjectContext이 분명하다 (그 안에 등록 된 개체 없음), 그래서 메모리 때문에의 관계를 무효화 지우는 이유가 없다 메모리에 객체가 없습니다. 수행해야 할 유일한 작업은 위에 나열된 데이터베이스 레벨 삭제 작업입니다.

회사에 1000 명의 직원이 할당되어있는 경우 회사 삭제 작업에 너무 많은 시간 (초 단위로 계산)이 걸리기 때문에 상황이 문제가됩니다.

필요한 작업 만 수행하고 데이터 일관성을 보장하는 회사를 삭제하는 올바른 방법은 무엇입니까? Xcode project

답변

2

코어 데이터는 데이터베이스되지 않습니다 : 여기에

당신은 존재하는 문제에 대한 준비된 Xcode 프로젝트를 다운로드 할 수 있습니다. 핵심 데이터는 데이터베이스에 지속되는 개체 계층 구조입니다.

이렇게 중요한 경우가 있습니다. 무언가를 삭제하면 Core Data는 참조 무결성이 유지되도록 관계의 양쪽에있는 객체를 검색합니다. SQLite에서는 비효율적 인 것처럼 보입니다. 상점이 다른 것일 때, 이중 점검이 필요합니다.

이 문제를 해결하는 방법은 무엇입니까? 하나는 삭제가 약간의 시간이 걸리고 삭제를 처리하기 위해 백그라운드, 개인 대기열을 회전시킬 것임을 인정하는 것입니다. 최적이 아닙니다.

또 다른 옵션은 두 테이블간에 소프트 참조를 사용하는 것입니다. 다시는 이상적이지 않습니다.

iOS 8까지 기다릴 수 있다면 일괄 업데이트를 통해 관계를 삭제할 수 있습니다.

0

CoreData의 성능 문제를 해결하는 일반적인 방법은 백그라운드 스레드에서 처리하는 것입니다. 불행히도이 작업은 쉬운 일은 아니며 CoreData는 스레드로부터 안전하지 않습니다.

MagicalRecord과 같은 타사 구성 요소를 사용하면 "백그라운드 스레드에 저장"하는 방법에 대한 자세한 내용은 look at this document을 참조하십시오.

+1

코어 데이터는 절대 안전한 스레드입니다. 항상있었습니다. 사람들은 "thread safe"와 "multi-thread accessible"을 종종 혼동합니다. 컨텍스트는 여러 스레드에서 액세스 할 수 없지만 Core Data는 다중 스레드 환경에서 잘 사용됩니다.MagicalRecord와 같은 것들은 핵심 데이터의 스레드 안전성을 향상시키지 못합니다. 개념과 혼란스럽고 기본 라이브러리를 이해하는 것을 더 어렵게 만듭니다. –

+0

그러면 애플도 혼란 스럽습니다. "관리 대상 자체는 스레드로부터 안전하지 않습니다." > https://developer.apple.com/library/ios/documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html ... –

+0

관리 객체는 스레드로부터 안전하지 않습니다. ** 핵심 데이터 **는 스레드로부터 안전합니다. 두 가지. 관리 대상 객체는 스레드로 제한됩니다. –