이 ASP.NET Core CRUD 시리즈가 곧 끝납니다. 지금까지 다룬 내용은 다음과 같습니다. 설정(1부), SQL++로 읽기(2부), 키-값으로 읽기(3부)및 생성/업데이트(4부). 이 마지막 게시물에서는 다음과 같이 D in CRUD: 삭제.
SQL++ 또는 키-값으로 삭제하기
패턴을 눈치채셨길 바랍니다. 읽기, 만들기, 업데이트와 마찬가지로 삭제에도 여러 가지 경로가 있습니다. SQL++를 사용할 수 있습니다. 삭제 문을 사용합니다:
|
1 2 |
DELETE FROM demo._default.wishlist w WHERE META(w).id = "1c3de2e7-70ea-4ee2-803b-425bbf6251cb" |
또는 키-값 삭제 작업(일명 "제거“):
|
1 |
await collection.RemoveAsync("1c3de2e7-70ea-4ee2-803b-425bbf6251cb"); |
그리고 이전과 마찬가지로 어떤 것을 사용할지 결정하는 데 도움이 되는 매우 유사한 가이드라인이 있습니다:
| 사용 사례 | 키 값? | 왜 또는 왜 안 될까요? |
| 키 "73892"로 사용자 삭제하기 | 예 | 직접 액세스 |
| 키가 "73892", "47212", "90491"인 사용자 그룹을 삭제합니다. | 예 | 이 경우 여러 키-값 연산이 필요할 수 있지만 여전히 SQL을 사용하는 것보다 빠를 수 있습니다. 삭제 ... 어디서 ... 에서 쿼리. |
| "Ohio"에서 모든 사용자 삭제 | 아니요 | 사용자의 상태는 키가 아닌 '보조' 속성일 가능성이 높습니다(여러 사용자가 오하이오에 있을 수 있음). 이는 SQL++의 좋은 사용 사례입니다. 삭제 |
ASP.NET Core용 엔드포인트 삭제
이를 염두에 두고 다음과 같이 삭제 엔드포인트를 만드세요:
|
1 2 3 4 5 6 7 8 9 10 11 |
[HttpDelete] [Route("api/delete")] public async Task<IActionResult> Delete(Guid id) { var bucket = await _bucketProvider.GetBucketAsync("demo"); var collection = await bucket.CollectionAsync("wishlist"); await collection.RemoveAsync(id.ToString()); return Ok(new { success = true }); } |
이 엔드포인트를 OpenAPI/Swagger와 함께 사용해 보면 예상대로 작동합니다.

정말 삭제해야 하나요?
많은 사용 사례에서 다음을 원하지 않을 수 있습니다. 실제로 데이터를 삭제합니다. '소프트' 삭제라고 하는 작업을 수행할 수 있습니다. 여기에는 데이터베이스에 여전히 존재하지만 최종 사용자에게 더 이상 표시되지 않도록 데이터를 이동하거나 표시하는 작업이 포함됩니다. 이 방법은 검색, 복구 및 보고가 가능하다는 장점이 있습니다.
또한 JSON NoSQL 데이터베이스의 유연성을 보여줄 수 있는 좋은 기회이기도 합니다.
소프트 삭제
위시리스트 항목에 '삭제됨' 필드를 도입해 보겠습니다. 이 필드에는 항목이 삭제된 날짜/시간이 포함됩니다. 이 필드가 존재하면 나머지 엔드포인트는 이 항목을 삭제된 것으로 간주해야 합니다. 그러나 필요한 경우 여전히 해당 항목을 쿼리하고, 보고하고, 복구할 수 있습니다.
관계형 데이터베이스의 경우, 이 작업을 수행하려면 ALTER. 데이터의 크기에 따라 약간의 다운타임이 필요하거나 많은 NULL 값이 필요할 수 있습니다. JSON 데이터베이스에서는 새 필드에 대해 데이터베이스에 아무 것도 알릴 필요가 없습니다.
사용해보겠습니다. 하위 문서 API 를 추가하려면 "삭제됨' 필드를 문서에 추가합니다. 하위 문서는 문서에 대한 부분 을 제거하고 나머지는 그대로 둡니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
[HttpDelete] [Route("api/softDelete")] public async Task<IActionResult> SoftDelete(Guid id) { var bucket = await _bucketProvider.GetBucketAsync("demo"); var collection = await bucket.CollectionAsync("wishlist"); await collection.MutateInAsync(id.ToString(), options => options.Upsert("deleted", DateTime.Now)); return Ok(new { success = true }); } |
(다음 사항을 확인하세요. 사용 Couchbase.KeyValue; 가 맨 위에 있습니다. 선물 컨트롤러 파일)
이 코드는 Couchbase에 명령을 보냅니다: 라는 필드를 삽입하여 해당 ID를 가진 문서에 대해 "삭제됨"를 입력하고 현재 날짜/시간을 값으로 지정합니다..
하위 문서를 사용하면 기존 문서를 먼저 로드할 필요가 없고, 수정된 문서 전체를 유선으로 다시 보낼 필요도 없습니다.
소프트 삭제된 데이터
최종 결과는 다음과 같은 문서가 됩니다:
|
1 2 3 4 |
{ "name": "Digital Photo Frame", "deleted": "2022-04-21T11:05:26.1766248-04:00" } |
위시리스트에 있는 다른 문서들은 not 를 삭제됨 필드입니다. 여전히 다음과 같이 보입니다:
|
1 2 3 |
{ "name": "Skyline Chili 2XL T-Shirt" } |
그리고
|
1 2 3 |
{ "name": "Joey Votto jersey" } |
이들은 "삭제됨": null 필드에 “삭제됨“ 필드를 전혀 사용하지 않습니다.
소프트 삭제된 SELECT
데이터는 다음과 같습니다. 표시 가 삭제된 것으로 표시되지만 여전히 데이터베이스에 남아 있습니다. 데이터베이스에서 GetAll 엔드포인트 (자세한 내용은 2부를 참조하세요. GetAll)를 사용하여 이를 고려합니다:
|
1 2 3 |
SELECT META(w).id, w.* FROM demo._default.wishlist w WHERE w.deleted IS MISSING |
여기에 SQL++ 구문을 몇 가지 더 소개했습니다: 누락. 이것은 관계형 데이터베이스에는 존재하지 않는 개념입니다. 관계형에서는 쿼리에 지정된 모든 열이 정의되어야 하며 값이 있어야 합니다(null인 경우에도). JSON NoSQL 문서 데이터베이스에서는 이러한 제약이 없습니다.
색인 개선
마지막으로 논의해야 할 사항은 인덱싱입니다. 다시 파트 2를 사용하여 시작하기 위해 기본 인덱스를 만들었습니다. 하지만 이 인덱스가 가장 효율적이지는 않습니다. 인덱스 생성 및 조정 는 관계형 데이터베이스 세계에서와 마찬가지로 심도 있는 주제입니다.
다행히도 Couchbase Capella에는 내장된 조언 도구 를 클릭하면 더 나은 인덱스를 추천할 수 있습니다. 클릭하기만 하면 조언 을 사용하거나, 쿼리 워크벤치에서 조언 구문).

이 경우 다음과 같은 권장 사항을 제공합니다:
|
1 2 3 4 5 6 7 8 9 10 11 |
"recommended_indexes": { "indexes": [ { "index_statement": "CREATE INDEX adv_deletedISMISSING ON `default`:`demo`.`_default`.`wishlist`(`deleted` IS MISSING) WHERE `deleted` IS MISSING", "index_statement_relative": "CREATE INDEX adv_deletedISMISSING ON `wishlist`(`deleted` IS MISSING) WHERE `deleted` IS MISSING", "keyspace_alias": "wishlist_w", "query_context": "default:demo._default", "recommending_rule": "Index keys follow order of predicate types: 2. equality/null/missing." } ] } |
위시리스트 데이터의 양이 매우 적은 경우에는 이 인덱스를 만들 가치가 없을 수도 있습니다. 하지만 예를 들어 전체 전자상거래 사이트의 위시리스트를 관리하는 경우라면 이 인덱스가 좋은 출발점이 될 수 있습니다.
CRUD의 종말
Couchbase를 사용하여 매우 간단한 ASP.NET Core CRUD 애플리케이션을 만드는 작업이 끝났습니다. 최종 API 표면은 다음과 같습니다:

다음은 이 시리즈의 개념에 대한 분석이며, 더 자세히 알아볼 수 있는 문서 링크도 함께 제공됩니다:
-
- 아카펠라 설정
- NET 종속성 주입 설정
- SQL++ (여전히 "N1QL"이라고도 함)
-
-
- 키-값 CRUD 연산
- 하위 문서 작업
-
이 시리즈의 전체 소스 코드는 GitHub에서 확인할 수 있습니다..
다음 단계는 무엇인가요?
아카펠라 무료 체험 신청하기. Couchbase Capella DBaaS는 Couchbase를 시작하는 가장 쉬운 방법이며 신용 카드가 필요하지 않습니다.
다음 내용을 확인하세요. .NET용 카우치베이스 플레이그라운드 브라우저에서 바로 실행할 수 있는 예제입니다.
가입하기 카우치베이스 디스코드 를 통해 CouchBase 엔지니어 및 다른 CouchBase 커뮤니티 구성원들과 질문하고 의견을 교환할 수 있습니다.