기록 상태를 저장하는 방법 (예 : 보류, 완료, 초안, 취소…)


18

상당히 많은 응용 프로그램에서는 테이블에 '완료', '초안', '취소'와 같은 상태를 갖는 레코드가 필요합니다. 이러한 상태를 저장하는 가장 좋은 방법은 무엇입니까? 내가 여기서 얻고있는 것을 설명하는 것은 * 매우 짧은) 예입니다.

간단한 블로그 응용 프로그램이 있으며 각 게시물의 상태는 게시, 초안 또는 보류 중입니다.

내가 보는 방법은 데이터베이스에서 이것을 모델링하는 두 가지 방법이 있습니다.

  1. Post 테이블에는 상태 텍스트가 포함 된 텍스트 필드가 있습니다.
  2. Post 테이블에는 PostStatus 테이블의 레코드 ID가 포함 된 상태 필드가 있습니다.

여기 블로그 예는 매우 간단한 예입니다. 열거 형 (지원되는 경우)으로 충분할 수있는 곳. 그러나 언제든지 상태 목록이 변경 될 수 있으므로 질문에 대한 답변을 원하므로 더 추가하거나 제거 할 수 있습니다.

누구든지 각각의 장단점을 설명 할 수 있습니까?

건배!

이것에 대한 나의 초기 견해는 다른 테이블을 사용하는 것이 더 좋으며 정상화에 대한 상태로 상태를 찾는 것이 좋으며 항상 정규화가 데이터베이스에 적합하다는 것을 배웠습니다.



"언제나"는 무엇을 의미합니까? 이는 사용자 활동의 일부 또는 소프트웨어 릴리스주기의 일부입니까?
케빈 클라인

두 경우 모두 여기에 언급 된 방법 중 가장 적합한 방법이 있습니다. 따라서 사용자가 새로운 상태를 추가 할 수 있거나 프로젝트에서 나중에 새로운 상태를 추가하는 경우
veganista

데이터베이스에 텍스트를 저장하면 비정규 화가 잘 될 수 있습니다. 조직이 프로세스를 얼마나 자주 변경 하는가 (예 : 상태 변경 가능성)?
Jaydee 2012

사용자가 새로운 상태를 추가 할 수 있다면 또 다른 것입니다. 작성중인 사용자 등을 상태로 기록하고 다른 테이블이 필요합니다.
케빈 클라인

답변:


14

다른 테이블에 인덱스로 상태를 저장하는 것은 불필요한 복잡성입니다. 읽을 수있는 방식으로 테이블에 직접 상태를 저장하십시오. 응용 프로그램 코드에서 상수 또는 열거 유형을 사용하십시오. 이로 인해 애플리케이션 코드가 단순 해지고 데이터 계층의 디버깅이 쉬워집니다.

이것은 데이터를 비정규 화하지 않으며 표현을 변경하기 만합니다. 데이터베이스가 열거를 직접 지원하는 경우이를 사용하십시오. 그렇지 않으면 제약 조건을 사용하여 열 값을 제한하십시오. 열 값에 대한 직접 제약 조건 또는 외래 키 제약 조건 중 하나를 사용하여 제약 조건을 갖습니다.

예, 다른 사용자에게 상태를 다르게 표시해야 할 수도 있습니다. 이는 지속성 레이어가 아니라 프리젠 테이션 레이어에서 해결되어야하는 프리젠 테이션 문제입니다.


1
+1, db에 상태 목록을 유지해야하는 특정 요구를 제외하고 , 일반적으로 가장 단순하고 복잡하지 않은 방법입니다.
GrandmasterB

2
상태 아키텍처를 변경하거나 돌연변이 날짜를 저장하지 않는 한 괜찮습니다
LastTribunal

10

상태 텍스트를 저장하는 것은 IMO가 아닙니다. 누군가가 "완료"를 "완료"라고 대신 결정할 수 있으므로 데이터베이스를 업데이트하고 누군가가 텍스트를 하드 코딩 한 경우 프로그램을 살펴 봐야합니다.

많은 프로그램에서 본 것은 숫자 코드 (1 = 신규, 2 = 초안, 3 = 검증 중, 4 = 완료, 99 = 취소) 또는 짧은 영숫자 코드 ( "NEW", "DRA", "INV)입니다. ","COM ","CAN "). 나중에 코드 (프로그램 또는 데이터베이스)를 사람이 읽을 수있게 만드는 것이 일반적으로 좋은 일입니다. 반면에 숫자 코드를 사용하면 "보다 큼"또는 "보다 작음"비교를 쉽게 수행 할 수 있습니다.

select * from myrecords where status < Status.Complete;

일부 바보도 ID를 하드 코어 할 수 있습니다.
Morons

ID의 또 다른 장점은 현지화를 제공해야한다는 것입니다. ID를 사용하여 리소스 문자열을 조회하고 표시 할 수 있습니다. 하드 코딩 된 문자열로는 불가능합니다
armitage

3
당신이 보여준 것처럼 "보다 큼"또는 "보다 작음"비교를 사용하여 상태를 수행하는 것이 좋은 생각이라고 생각하지 않습니다. 여기에는이 예제와 같은 간단한 응용 프로그램을 위해 일하지만 더 복잡한 애플 리케이션을위한 좋은하지 않습니다 수 있습니다 (비록 메신저 것을 확신하여 인식)
veganista

1
@armitage : 문자열을 사용하여 조회를 수행하는 것이 완벽하게 가능합니다. 자원 이름은 문자열입니다.status.draft=Draught
kevin cline

veganista : 물론, 비교보다 크거나 작은 어려움이있을 수 있지만, 그렇게하고 살아가는 크고 복잡한 시스템을 보았습니다.
user281377

4

관계형 데이터베이스의 세 가지 규칙 :

  1. 정규화
  2. 정규화
  3. 정규화

그래서 당신의 질문은 스스로 대답합니다. 자체 테이블 내부의 상태를 유지하고 GUID / UUID를 id로 사용하십시오 . 인덱싱 된 GUIDS는 매우 빠르며 증가하는 숫자의 본질적인 문제를 해결합니다. ID를 사용하면 ID를 사용하여 DB에 완료된 모든 게시물을 요청하는 것과 같은 멋진 작업을 수행 할 수 있으며 관계형 DB 패러다임 내에서 작업하기 때문에 매우 빠릅니다. 필드가있는 경우 DB는 모든 단일 행을 반복하고 텍스트 비교를 수행해야합니다. 어두울 수도 있습니다. 매우 느립니다.

게시물 상태 이름은 변경 될 수 있으며 게시물 상태에 대한 자세한 정보는 테이블로 이동할 수 있으며 정규화하면 모든 것이 작동합니다 .

예를 들어, 상태 정보를 추가 정보로 추가하면 ammoQ 언급을 비교할 수 있습니다. 그러나 이들은 포지셔닝 키에 의존하지 않으므로 DB 무결성을 손상시키지 않으면 서 상태 수준을 재정렬 할 수 있습니다. 자동 증분 키와 관련된 레벨이있는 ​​경우 추가 레벨을 삽입 할 수도 있습니다.


당신이 여기에 언급 한 이유는 정확하게 다른 테이블을 사용하여 내 보관소를 저장 한 이유입니다. 내가이 질문을 한 주된 이유는 때로는 간단한 텍스트 필드를 사용하는 것이 좋은지 여부를 보는 것입니다.
veganista

@Liam 텍스트 필드로 정규화되는 경우에만 해당됩니다. 즉, 텍스트 필드가 기본 키에만 의존 하고 텍스트 필드가 나오는 기본 키를 기반으로 검색하는 경우 입니다. 관계형 DB는 관계에 관한 것이며 여기에는 관계가 있으므로 정의해야합니다. 몇 가지 예외 중 하나는 외부 소스에서 더티 데이터를 처리하고 있으며 완전히 모델링 할 시간이없는 경우입니다. 가능하면 이것을 피하십시오.
스펜서 Rathbun

돌아 오지 않을 GUID를 애도하는 눈을 숨 깁니다
sq33G

" 관계형 데이터베이스의 세 가지 이론 "을 작성해야합니다 . 이론이 항상 실용적이지는 않습니다. 상태 코드를 관련 레코드에 직접 저장하는 것이 종종 더 효율적입니다. 이를 사용하기 위해 찾아 볼 필요가 없으면 다른 테이블에 대한 조인을 제거하면 많은 낭비되는 처리가 절약됩니다.
Suncat2000

열 유형과 전체 테이블 스캔에 대한 잘못된 정보로 인해 다운 보트되었습니다.
igorrs

3

예, PostStatus 테이블이있는 옵션 2를 사용해야합니다.

다른 답변에 언급 된 모든 장점 외에도.

상태를 추가하거나 제거해야한다는 것을 명심하고 PostStatus 테이블에 "사용 가능"열이있을 수 있으므로 상태가 제거 된 경우 "사용 가능"열을 "N"으로 표시하면 상태를 추가 또는 제거하면 기존 레코드도 문제없이 유지됩니다.


1

전체 정규화를 위해 엔티티 상태의 변경이 실제로 'statusChange'와 같은 별도의 엔티티로 모델링된다는 통찰력있는 답변에 추가하고 싶습니다.

statusChange 엔터티에 추가 조인이 필요하지만 변경을 수행하는 행위자, 변경이 발생한 이유에 대한 설명, statusChange가 수행 된 날짜 및 가능한 경우와 같은 추가 정보를 추가 할 가능성이 있습니다. 효과적이다.


0

레코드 테이블에서 상태에 텍스트를 사용하면 변경 될 수 있으므로 삽입 / 업데이트에 대한 데이터 무결성 검사를 수행하기가 어려울 수 있습니다. 열거 형 데이터 유형으로 DBMS를 사용하는 경우이를 대신 사용할 수 있습니다 (아마도 성능에 영향을 미치지 않음).

상태에 메타 데이터 (설명, 생성자, 친숙한 이름 등)가 필요한 경우 상태를 별도의 테이블에 저장하고 레코드 테이블에 상태 키가 있어야합니다 (외래 키를 사용해야합니다). ID는 반드시 숫자 일 필요는 없으며 상태 테이블의 PK 일뿐입니다. 또한 상태가 자체 테이블에있는 경우 해당되는 경우 레코드 유형 (테이블)간에 상태를 공유 할 수 있습니다. 상태 테이블에 가입 할 때 발생하는 성능 문제에 대해서는 걱정하지 않습니다.

무엇을하든 마법 상태 (1은 활성, 2는 삭제)를 피해야합니다. 이것은 충분히 큰 타임 라인에서 항상 길을 잃는 경향이있는 문서와 전통에 의존합니다. 숫자 ID를 전혀 사용하지 않는 경우 db 어딘가에 텍스트 연관이 있는지 확인하십시오.


성능에 대해 걱정하지 않는다면 확장 성을 희생 할 가능성이 높습니다. 컴퓨터가 마법 상태를 피하는 것은 불가능합니다. 0과 1은 본질적으로 마법입니다.
Suncat2000

0

데이터베이스 디자인의 목적에 따라 다릅니다.

응용 프로그램 (즉, 객체 (코드)이 모두 마스터)을 지원하도록 데이터베이스를 디자인하는 경우 열거 (또는이를 지원하지 않는 클래스의 의사 열거)를 사용하고 열거의 이름을 저장하면 열거 형을 통해 허용되는 값을 계속 제어하고 원시 데이터를 보도록 강요 할 때 테이블을 조금 더 쉽게 읽을 수 있기 때문에 좋은 생각입니다 (코드가 실제로 모든 규칙을 적용하는 경우는 아닙니다). 그러나 열거가 표시되면 그런 다음 일반적으로 열거 형 값 (정수)을 저장합니다.


-1

상태는 매우 중요합니다. 게시물 정보를 얻을 때마다 상태를 가져 오거나 상태별로 게시물을 필터링해야합니다. 다른 테이블에 상태가있는 경우이 정보를 얻기 위해 조인해야하므로 성능이 저하됩니다. 확실히 당신은 같은 테이블에 상태가 있어야합니다. 그리고 색인을 작성하십시오! 정수를 상태 또는 열거 형 필드로 계속 사용할 수 있습니다.


-2

올바른 솔루션은 CQRS와 함께 이벤트 저장소 / 소스를 사용하거나 블록 체인을 사용하는 것입니다. RDB에서 이벤트를 캡처 할 때의 문제점은 RDB가 단일 이벤트의 스냅 샷을 시간에 저장하고 "상태 / 상태"와 같은 것은 시간이 지남에 따라 변하는 일련의 돌연변이라는 것입니다


당신이 내 게시물을 다운 투표하려고한다면, 사건을 만드십시오. 그렇지 않으면 당신은 상자 밖에 스코프가 거의없는 부드러운 마음의 레밍입니다
LastTribunal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.