날짜별로 레코드를 식별 할 수있는 경우 데이터베이스에 ID가 필요합니까?


17

Android 용 첫 번째 응용 프로그램을 작성 중이며 SQLite 데이터베이스를 사용하므로 가능한 한 크기를 제한하려고 시도하지만 질문은 일반적으로 데이터베이스 디자인에 적용됩니다.

텍스트와 작성 날짜가있는 레코드를 저장할 계획입니다. 이 앱은 독립 실행 형 앱입니다. 즉, 인터넷에 연결되지 않으며 한 명의 사용자 만 업데이트하므로 지정된 날짜에 둘 이상의 항목이있을 가능성은 없습니다.

내 테이블에 여전히 ID 열이 필요합니까? 그렇다면, 날짜가 아닌 ID를 레코드 식별자로 사용하면 어떤 이점이 있습니까?


정수 PK를 지정하지 않으면 SQLite는 항상 rowid에 대한 정수 열을 만듭니다. 따라서 공간을 절약하기위한 방법으로 "ID"열이없는 것으로 생각하지 마십시오.
Codism

안드로이드에서는 일부 클래스가 작동하려면 _id 열이 있어야하는 테이블이 필요하다고 덧붙입니다. 이 SO 답변에 대한 자세한 정보 .
bigstones

5
전화 자체에서 날짜를 가져오고 사용자가 이전 시간대로 이동 한 경우 (및 / 또는 전화가 자동으로 시간을 업데이트하는 경우) 동일한 타임 스탬프가 두 번 이상 나타날 수 있습니다.
유진

답변:


22

IMHO에서는 날짜 열을 기본 키로 사용하지 않는 것이 가장 좋습니다.

날짜 필드가 기본 키로 사용되는 시스템에서 작업했으며 날짜 필드로 작업하는 경우 데이터 하위 집합을 가져 오는 쿼리를 작성하는 것은 약간의 드래그입니다.

고려해야 할 다른 사항들 :

특정 시점이 고유하다고 생각할 수도 있지만 날짜 열의 세분성에 따라 다릅니다. 분, 초, 밀리 초 등 입니까? 기본 키 위반이 발생하지 않을 것이라고 절대 확신 할 수 있습니까?

마지막으로 데이터베이스를 다른 플랫폼으로 마이그레이션하려는 경우 플랫폼간에 날짜 데이터의 단위가 다른 문제가 발생할 수 있습니다.

물론 당신은 당신이해야 할 일과 이상의 균형을 맞춰야합니다. 공간이 실제로 그렇게 큰 관심사라면 날짜 열을 사용하는 것이 두 가지 악의 적은 것이 될 수 있습니다. 그것은 당신이 결정해야 할 디자인 결정입니다.

편집하다:

나는 결코이가있는 표시한다는 것을 지적한다 가난한 디자인 결정을. 문제의 RDBMS의 실용성에 문제가있을 수 있습니다.


SQLite 쿼리를 작성한 이후로 시간이 지났지 만 바인딩 값에 대한 더 자세한 선언을 제외하고 정수로 필터링하는 것과 동일한 날짜로 필터링하지 않습니까?
DougM

더 장황하고 일부 RDBMS에서는 DB가 미국 형식으로 설정된 경우 일 및 월 요소가 반전되는 문제가 발생합니다.
Robbie Dee

고마워, 이것들은 모두 좋은 대답이지만, 직장에서의 경험은 거래를 확실히 봉인했습니다.
Nieszka

이것에 대한 포스트 스크립트로서 : 오늘만 나는 두 클라이언트 장치 사이의 시간 차이로 인해 직원 번호 및 액세스 날짜 / 시간 PK에 대한 주요 키 위반이 발생하는 응용 프로그램 감사 테이블에 대한 지원 문제를 겪었습니다. ..
Robbie Dee

13

아니요, 중복 날짜가 없음을 보장 할 수있는 경우 스키마에 정의 된 ID 열이 반드시 필요하지는 않습니다.

그러나 ...

어쨌든 그것을 사용할 수도 있습니다. 여기서 작은 비밀은 SQLite에 이미 ROWID라는 모든 테이블에 대해 고유 한 자동 증가 ID가 있다는 것입니다. 테이블에서 자동 증분 정수 열을 PK로 선언하면 SQLite는 새 열을 만들지 않으며 기존 ROWID 열의 별칭을 지정합니다.

SQLite에서 모든 테이블의 모든 행에는 64 비트 부호있는 정수 ROWID가 있습니다. 각 행의 ROWID는 동일한 테이블의 모든 행에서 고유합니다.

ROWID, ROWID 또는 OID 특수 열 이름 중 하나를 사용하여 SQLite 테이블의 ROWID에 액세스 할 수 있습니다 . 특수 테이블 중 하나를 사용하도록 일반 테이블 컬럼을 선언하는 경우를 제외하고, 해당 이름의 사용은 내부 ROWID가 아닌 선언 된 컬럼을 참조합니다.

테이블에 INTEGER PRIMARY KEY 유형의 열이 포함 된 경우 해당 열은 ROWID의 별명이됩니다. 그런 다음 네 가지 다른 이름, 위에서 설명한 원래 세 가지 이름 또는 INTEGER PRIMARY KEY 열에 지정된 이름 중 하나를 사용하여 ROWID에 액세스 할 수 있습니다. 이 모든 이름은 서로의 별명이며 모든 상황에서 동일하게 작동합니다.

http://www.sqlite.org/autoinc.html

따라서 원하든 원하지 않든 테이블 당 하나를 얻기 때문에 ID 열을 사용하지 않아도 공간을 절약 할 수 없습니다!


9

다음 중 하나에 해당하면 ID 필드를 사용하십시오.

  1. 자연 키가 없습니다 (날짜는 고유하지 않습니다)
  2. 날짜 필드는 자주 변경됩니다
  3. 삽입 시점에 날짜를 알 수 없습니다.
  4. 여러 열 식별자가 3 개의 열을 초과하므로 조인이 너무 장황하게됩니다.

이 질문을 읽으십시오 : “모든 대리자”를 지원하는 정식 출처가 있습니까?

편집하다:

내 의견으로는 위의 내용 중 어느 것도 사실이 아니기 때문에 ID 필드를 사용할 필요 는 없지만 원하는 경우 하나를 사용할 수 있습니다.


1
+1 ID 열은 스키마 코드 냄새로, 데이터가 실제로 관계형 모델에 맞지 않음을 나타냅니다.
로스 패터슨

10
@RossPatterson 확실하지 않습니다. 자연 키가 존재하지 않는 여러 경우를 생각할 수 있지만 데이터는 여전히 관계형 모델에 적합 할 수 있습니다. 내 머리 꼭대기에있는 한 가지 사례 : 살아있는 사람에 대한 정보 저장. 많은 ( 전부가 아니라! ) 국가는 각 시민에게 고유 한 식별자를 할당하지만 해당 식별자를 사용하는 것이 적절하거나 가능하다는 것을 의미하지는 않습니다 (레코드 생성시 알려지지 않았거나 할당되지 않았거나 사용시) 해당 규정에 따라 금지 될 수 있습니다). 데이터가 관계형 모델에 적합하지 않다는 의미입니까? 나는 그렇게 생각하지 않습니다.
CVn

그리고 그러한 고유 한 식별자가있는 곳에서 경찰 등은 때때로 가짜 ID에 이중 체를 사용한다는 재미있는 사실이 거의 없습니다. 의도적이지 않은 경우 사무 오류는 어쨌든 이중성을 보장합니다.
user470365

4
그것이 내장되어 있는지 (la Oracle) 또는 선의의 열로 추가 되든지간에 매우 유용합니다. 울타리 (DBA 및 개발자)의 양쪽에있는 사람은 ID가있는 테이블을 중복 제거하는 것이 훨씬 쉽습니다. 유일합니다.
Robbie Dee

1
@RobbieDee 당신이 맞아요. 주제에서 벗어났습니다.
Tulains Córdova

2

당신은 또한에서 "날짜"열 변경의 의미에 할 수도 있다는 사실을 숙지 created_atupdated_at내가 매우 일반적인 경우로 찾아 그 라인을 따라 다른 변화 나.

경우에 따라 ID 열을 추가하면 디자인 변경시 유연성이 향상됩니다.


+1 date_created 및 date_modified를 테이블에 추가하면 행을 만들고 업데이트 한시기를 추적하는 데 매우 유용합니다. 이는 리포지토리 / 데이터웨어 하우스 업데이트 문제를 조사 할 때 금의 가치가 있습니다.
Robbie Dee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.