릴레이셔널 데이터베이스의 행을 삭제해야 합니까, 비활성화해야 합니까?
공간이 그다지 중요하지 않은 새로운 프로그램에서는 행을 삭제하는 것이 좋을까요, 아니면 부울 "비활성화"를 사용하여 행을 비활성화하는 것이 좋을까요?
예를 들어 프로그램에서 사용자를 삭제하려는 경우.
삭제하지 않으면 이후 모든 쿼리에 대해 새로운 버그 클래스가 생성됩니다.쿼리 작성은 파워 유저(IT프로패셔널 이외)나 하급 개발자에 의해서 행해지는 경우가 많습니다.따라서 BIT 액티브플래그만으로 마킹된 비활성 데이터가 있는 모든 테이블은 지금부터 영원히 모든 쿼리에 대해 WHERE 절에 AND를 추가해야 합니다.이를 통해 사용자는 성공이 아닌 실패의 구렁텅이에 빠질 수 있습니다.다만, 이러한 플래그 시스템을 도입하는 것을 강하게 추천합니다.왜냐하면, 나쁜 설계가 없으면, 유지보수 개발자가 많은 버그를 수정할 필요가 없기 때문입니다.
과거 데이터를 표에 포함시키는 것이 얼마나 중요합니까?비즈니스가 장래를 내다보고 있는 경우, 테이블에 오래된 데이터가 있는 것은 부담이 될 수 있습니다.이는 제약조건을 작성할 때 문제를 일으킬 수 있습니다(모든 제약조건을 수정하여 존재하지 않는 데이터를 제외해야 합니다).데이터 품질 보장은 "삭제하기는 두렵지만 다시는 사용하거나 업데이트하고 싶지 않은 오래된 쓰레기"와 우리가 관심을 갖는 새로운 것들을 지속적으로 다시 식별해야 하기 때문에 복잡합니다.
실수로 삭제되는 건가요?행이 실제 엔티티에 해당하는 경우 "증발", "사망", "건물 왼쪽" 플래그를 유지하고 설정하는 것이 흥미로울 수 있습니다.실생활에서 엔티티가 없는 행을 잘못 삽입한 경우에도 DELETE는 나쁘지 않습니다.지금까지 존재하지 않았던 상상 속의 고객이 고객 테이블에 남아 있는 것이 중요한가?
그리고 마지막으로, 성격이 큰 역할을 합니다.사람들은 데이터를 가지고 떠돌이일 수도 있다.DBA가 30년 전의 모든 신문을 보관하고 데이터를 삭제하는 것을 좋아하지 않는 경우, DBA는 자신의 개인적 선호가 아닌 장점을 바탕으로 데이터 설계를 결정해야 합니다.
경우에 따라 다르죠. (하지만 이미 짐작하셨겠죠.)
실제로 여기서의 적절한 사용법 위반은 거의 항상 삭제 방향으로 진행됩니다.
삭제의 주된 나쁜 결과는 부모 레코드가 없어졌을 때 참조 무결성이 손실되는 다른 테이블에 종속 레코드가 얼마나 자주 존재하는가 하는 것입니다.
삭제를 방어하기 위해 사용된 한 가지 문제(스토리지 용량 문제를 무시하여 이미 적절하게 처리한 문제)는 쿼리 효율성에 큰 차이가 있을 것으로 예상합니다.
사용자 또는 소프트웨어 문제로 인해 누군가가 큰 "Undo" 버튼을 눌러야 하는 경우가 너무 많습니다.삭제하면 (적어도 특별한 도움을 받거나 친절하게 대해주고 싶은 사람들을 화나게 하지 않으면) 운이 나빠집니다.
제가 주로 사용하는 용어는 "Active"와 "Inactive"입니다.
(토토필에 의해) 고려해야 할 몇 가지 사항:
- 일부 데이터베이스에서 레코드를 삭제해도 디스크 공간이 자동으로 확보되지 않습니다.
- 더 이상 필요하지 않은 중요한 정보를 삭제하면 보안 위험을 피할 수 있습니다.
데이터 보호 법규에 따라 특정 상황에서 개인에 대한 식별 가능한 정보를 삭제해야 할 수 있습니다.법률은 국가마다 다르며, 몇 가지 포인트는 다음과 같습니다.
- EU http://ec.europa.eu/justice_home/fsj/privacy/law/index_en.htm
- 영국 http://www.ico.gov.uk/what_we_cover/data_protection.aspx
- 에스토니아 http://www.riigiteataja.ee/ert/act.jsp?id=748829
한편, 특정 정보를 보관하도록 법에 의해 요구될 수 있습니다.
시간 데이터베이스 설계에 관한 책을 읽고 시간적 중요성에 대한 모든 레코드는 최소 4개의 타임스탬프 열이 있어야 한다는 철학을 믿게 되었습니다.이 네 가지는 created, deleted, start, end입니다.작성 및 삭제된 타임스탬프는 매우 알기 쉬운 것입니다.시스템에서 삭제한 레코드는 현재() 전에 보지 마십시오.시작 열과 끝 열에 따라 데이터가 시스템에 적용되는 시기가 결정됩니다.변화의 역사를 기록하기 위한 것입니다.레코드를 갱신할 필요가 있는 경우는, 종료 시각을 「지금」으로 설정해, 카피하고, 카피를 갱신해, 카피의 개시 시간을 「지금」으로 설정합니다.이렇게 하면 과거의 방식을 살펴볼 필요가 있을 때 시스템이 이를 파악하도록 할 수 있습니다.또, 그 시점에서 변경이 자동적으로 행해지도록 시작점을 장래의 어느 시점으로 설정하거나, 그 시점에서 자동적으로 종료하도록 종료를 설정할 수도 있습니다.생성/삭제된 타임스탬프를 미래로 설정하는 것은 의미가 없습니다.
삭제됨, 표시됨, 활성 열 등을 사용하는 경우 보기를 사용하여 열을 사용해야 하는 번거로움에서 벗어날 수 있습니다.
고객님과 고객님의 요건에 따라 달라집니다(기록이 존재하면 어려워지는 경우도 있습니다).
하지만 부울은 잘못된 선택이라고 말할게요.타임스탬프를 null로 합니다.특히 너무 많이 삭제해서 삭제의 일부를 취소하고 싶을 때, 어떤 것이 삭제되었는지 아는 것이 매우 편리합니다.
사정에 따라 다르겠지.디세이블의 경우는, 삭제를 취소하거나, 누군가가 (감사용으로) 실제로 레코드를 삭제한 것을 보다 쉽게 확인할 수 있습니다.
레코드를 삭제하지 않는 기술 요건이 있는 경우도 있습니다.예를 들어 변경된 레코드를 보내는 것만으로 데이터베이스를 다른 사용자와 동기화하려는 경우 실제로 삭제된 경우에는 이 작업을 수행할 수 없습니다.
기능상의 요건에 따라 필요한 것입니다.거기에 분명히 언급되어 있지 않다면, 당신은 스스로 그것을 알아내야 할 것입니다.
대부분의 경우 이러한 레코드는 별도의 테이블에 저장하는 것이 좋습니다.그런 다음 한 테이블이 다른 테이블을 참조하고 두 번째 테이블의 레코드도 삭제 처리 여부를 결정해야 하는 다양한 상황을 피할 수 있습니다.
테이블에 "DELETED" 열을 추가하고 행을 삭제하는 대신 표시하면 더 많은 작업을 수행할 수 있지만 이점이 거의 없습니다.이제 쿼리를 작성할 때마다 "WHERECTED is NOT NULL"(또는 다른 항목)을 포함해야 합니다.
더 나은 방법은 데이터를 삭제해야 할 때 데이터를 삭제하고 정기적인 백업 프로세스에 의존하여 데이터가 손실되지 않도록 하는 것입니다.어떤 이유로 삭제된 데이터를 보관해야 하는 경우(검색 등을 위해), 이 목적으로 작성된 다른 테이블에 데이터를 복사한 후 원본을 삭제하는 것이 좋습니다.
저는 수년간 많은 데이터베이스를 상속받아 왔습니다만, 레코드를 삭제하는 대신 플래그를 붙이는 이러한 전략은 유감스럽게도 매우 일반적이며, 적어도 제 경험상으로는 항상 큰 문제가 발생합니다.
삭제된 데이터가 필요한 경우가 있지만 자주 필요하지 않은 경우: 레코드를 별도의 데이터베이스/테이블로 이동할 수 있습니다(예:users ★★★★★★★★★★★★★★★★★」users_deleted 보다 나은 「」를 참조해 주세요.somedb.users ★★★★★★★★★★★★★★★★★」somedb_deleted.users를 참조해 주세요.
이렇게 하면 일반 데이터베이스처럼 단순하지는 않지만 쿼리를 통해 데이터에 액세스할 수 있습니다. 그러나 원래 데이터베이스를 복잡하게 만들지 않고 데이터를 코드화할 필요가 없습니다.
자신의 삭제를 관리할 필요가 없는 한 행을 삭제하는 것이 좋습니다.
(대부분의 국가에서) 법적 이유로 레코드를 삭제할 수 없는 유스케이스가 있습니다.물론 업계와 데이터에 의존합니다.
이 경우 베스트 프랙티스의 가이드라인은 MatthewMartin에서 설명한 실제 삭제의 이점을 얻을 수 있는 "삭제된" 데이터를 섀도우 테이블로 표시하는 것이라고 생각합니다.또, 이 패턴은, 데이터 테이블 전체에 「액티브」비트 플래그를 작성하는 것보다, 자주 선호되고 있습니다.
이는 어플리케이션의 요구에 따라 결정되어야 합니다.나는 그것을 양쪽 다 해봤다.행 삭제 비용 및 이로 인해 발생하는 계단식 삭제 비용이 너무 많이 들기 때문에 실행을 취소해야 하는 응용 프로그램이 있습니다.다만, 통상, 지금까지 실행한 애플리케이션에서는, 유저가 삭제를 확인한 후, 유저가 요구한 대로 실행하도록 요구되고 있습니다.프라이버시 문제로 인해 데이터를 삭제해야 하는 경우도 있습니다.즉, 사용자가 삭제를 요청할 경우 최신이 아닌 것으로 표시할 뿐만 아니라 실제로 삭제해야 합니다.그 밖의 경우(세금 관련 거래 등)에는 더 이상 법률이 요구하지 않을 때까지 데이터를 비현황 상태로 유지해야 할 이유가 있을 수 있다.두 가지 카테고리에 모두 맞는 어플리케이션을 가지고 있습니다.
아카이브 데이터를 보관해야 하는 경우 다양한 전략을 사용할 수 있습니다.즉시 사용할 수 있어야 하는지 여부에 따라 정기적으로 백업 및 정리되는 아카이브 테이블에 푸시할 수 있습니다.실행 취소가 필요한 경우 현재 테이블에 저장하고 플래그를 설정하여 표시할 수 있습니다.스키마의 복잡성, 애플리케이션의 요건 및 개인의 취향에 따라 달라집니다.
CRUD를 만들고 있는데 같은 문제에 직면해 있습니다.
해결책 : CRUD의 D는 삭제가 아니라 비활성화해야 합니다.
문제:
- "모든" 쿼리는 레지스트리가 비활성화되었는지 확인해야 합니다(예: disabled=1).좀 더 구체적으로 말하면, *를 선택하면 체크해야 합니다.
- 기본적으로 모든 삽입이 레지스트리(syslog=1)를 활성화해야 합니다.
- 업데이트해도 플래그가 변경되지 않습니다.
- Disable은 flag=0으로 표시되는 위장 업데이트입니다.
큰 문제
- 가비지 콜렉터기존 레지스트리 삭제, 참조되지 않은 레지스트리 삭제 또는 혼합 전략의 3가지 전략이 존재합니다.
이것은 판단 콜이지만, 이전에는 행을 삭제할 수 있다고 생각했던 테이블에 「비활성」컬럼을 추가했습니다.대부분의 경우엔 장애인 칼럼을 추가하는 게 더 안전할 거예요그러나 n:n 관계에서는 이 문제가 까다로워질 수 있으므로 고려해야 할 사항입니다.
"삭제된" 열을 추가하고 삭제된 항목을 다시 삭제하거나 삭제하도록 사용자에게 제공하는 것이 가장 좋습니다.
데이터베이스의 기능에 따라 다릅니다.그것이 모든 진실의 근원인가?문제가 있는 경우 삭제가 아니라 비활성화합니다.부정한 조작(사용자 에러)으로부터 회복하기 쉽기 때문입니다.데이터베이스가 일부 업스트림 데이터 원본에서 공급되는 경우 사용되지 않은 데이터를 삭제합니다.모든 재생/복구 작업은 업스트림 시스템에서 수행할 수 있습니다.
이미 많은 사람들이 말했듯이, 애플리케이션 요구는 여러분이 원하는 것을 지시합니다.하지만 제게는 행 표시는 올바른 도구를 사용하지 않는 것처럼 보입니다.삭제는 논리적으로 DELETE라고 생각하기 때문에 법적 이유로 삭제가 허용되지 않는 경우에는 처음부터 삭제하지 않습니다.동시에, 저는 모든 내부 데이터 구조의 유지와 인덱스에 대해 생각합니다.데이터 취득을 위해 수행할 수 있는 모든 최적화는 말할 것도 없고, (뷰 또는 쿼리에서) 해당 검사를 추가하면 데이터베이스의 복잡성과 엔티티의 관계에 따라 성능에 기하급수적으로 영향을 미칩니다.
한마디로 사용자 오류를 방지하기 위해 UI 계층에 삭제 논리를 넣고 삭제할 수 있는 사용자에게 삭제 권한을 부여합니다.아카이브를 보관하기 위해 정기 백업을 사용합니다.애플리케이션에 엄격한 감사 이력이 필요한 경우는, 트리거에 실장해, 감사를 오프 사이트의 데이타베이스에 격납해, 실가동으로부터의 트래픽, 체크, 및 폐기를 회피합니다.
이 문제를 해결하기 위한 두 가지 추가 솔루션이 있습니다.나는 그것이 정말로 당신의 데이터의 요건에 달려있다고 게시한 다른 사람들의 의견에 동의한다.
외부 키 제약 조건을 사용하여 참조 무결성 문제가 발생할 경우 사용자가 레코드를 삭제하지 않도록 할 수 있습니다(RDBMS가 레코드를 지원하는 경우).몇 번인가 최종 사용자에게 "이 <개체>와 어소시에이트를 해제할 때까지 삭제할 수 없습니다."라는 메시지를 제공했습니다.다른 테이블 또는 테이블과의 연관성이 매우 높을 것으로 예상하지 않는 한 이 방법은 사용할 수 있습니다.
또 다른 접근법은 삭제되지 않은 레코드와 관련지어져 있는 모든 레코드를 이동하는 것입니다.예를 들어, 10개의 개별 수업 시간이 연관된 과정이 있다고 가정합니다.과정을 삭제할 경우, 사용자가 10개 클래스가 모두 삭제되는지 또는 새 과정 또는 기존 과정과 연관되는지 여부를 결정할 수 있습니다.
언급URL : https://stackoverflow.com/questions/347160/should-i-delete-or-disable-a-row-in-a-relational-database
'programing' 카테고리의 다른 글
| TS를 사용하는 Redx DevTools 확장과 관련된 오류: "속성 '_REDUX_DEVTOOLS_EXTION_COMPOSE__'이(가) '윈도' 유형에 없습니다." (0) | 2023.03.01 |
|---|---|
| React에서 하위 상태의 상위 상태 액세스 (0) | 2023.03.01 |
| 인덱스와 함께 .map을 사용하여 반응합니다. (0) | 2023.03.01 |
| 0이 아닌 1페이지부터 시작하는 스프링 부트 페이지 설정을 하는 방법 (0) | 2023.03.01 |
| Laravel5 Json 파일 내용 가져오기 (0) | 2023.03.01 |