レコードが日付で識別できる場合、データベースにIDが必要ですか?


17

私はAndroid向けの最初のアプリケーションを作成しており、SQLiteデータベースを使用するため、できるだけサイズを制限しようとしていますが、この質問は一般的にデータベース設計に当てはまると思います。

テキストと作成日を含むレコードを保存する予定です。このアプリはスタンドアロンアプリです。つまり、インターネットにリンクせず、1人のユーザーのみが更新するため、特定の日付に複数のエントリが存在する可能性はありません。

テーブルにはまだID列が必要ですか?その場合、日付ではなくIDをレコード識別子として使用する利点は何ですか?


整数PKを指定しない場合、SQLiteは常にrowidの整数列を作成します。そのため、スペースを節約する方法として「ID」列がないことに頼らないでください。
コーディズム

Androidでは、一部のクラスが動作するために_id列を持つテーブルが必要であることを追加します。このSO回答の詳細情報。
ビッグストーン

5
電話自体から日付を取得していて、ユーザーが以前のタイムゾーンに移動した場合(および電話が自動的に時刻を更新した場合)、同じタイムスタンプを複数回取得できる可能性がわずかにあります。
ユージン

回答:


22

私見では、日付列を主キーとして使用することは避けるのが最善です。

日付フィールドを主キーとして使用するシステムで作業しており、日付フィールドを使用している場合、データのサブセットをプルバックするクエリを作成するのは少しドラッグです。

あなたが考慮したいかもしれない他のいくつかのポイント:

ある時点は一意であると考えるかもしれませんが、それはむしろ日付列の粒度に依存します。分、秒、ミリ秒などです。主キー違反が発生しないことを絶対に確認できますか?

最後に、データベースを別のプラットフォームに移行する場合、日付データの粒度がプラットフォーム間で異なるという問題が再び発生する可能性があります。

もちろん、理想と仕事のバランスをとる必要があります。スペースが本当にそれほど重要な場合、日付列を使用することは、2つの悪の少ない方です。それはあなたがしなければならない設計上の決定です。

編集:

これは、設計上の決定が不十分であることを示すものではありません。問題のRDBMSの実用性に問題があるかもしれません。


SQLiteクエリを作成してからしばらく経ちましたが、バインディング値のより冗長な宣言は別として、日付によるフィルタリングは整数によるフィルタリングと同じではありませんか?
ダグ

それはより冗長であり、また、DBが米国形式で設定されている場合に日と月の要素が逆になるという問題が発生するRDBMSもあります。
ロビーディー

おかげで、これらはすべて良い答えですが、職場での経験は間違いなく契約を結び付けました。
ニースカ

これへの追記として:今日だけ、2台のクライアントデバイス間の時間差のために従業員番号とアクセス日時PKの主キー違反を取得しているアプリケーション監査テーブルのサポート問題を手渡しました。 ..
ロビーディー

13

いいえ、日付が重複しないことを保証できる場合、スキーマでID列を厳密に定義する必要はありません。

しかし ...

...とにかく、とにかくそれを使うかもしれません。ここでの小さな秘密は、SQLiteにはROWIDと呼ばれるすべてのテーブルに固有の自動インクリメントIDが既にあるということです。テーブル内の自動インクリメント整数列をPKとして宣言した場合、SQLiteは新しい列を作成しません。単に既存のROWID列をエイリアスします。

SQLiteでは、すべてのテーブルのすべての行に64ビット符号付き整数ROWIDがあります。各行のROWIDは、同じテーブル内のすべての行で一意です。

特別な列名ROWID、ROWID、またはOID を使用して、SQLiteテーブルのROWIDにアクセスできます。これらの特別な名前のいずれかを使用する通常のテーブル列を宣言する場合を除き、その名前の使用は、内部ROWIDではなく宣言された列を参照します。

テーブルにINTEGER PRIMARY KEY型の列が含まれている場合、その列はROWIDのエイリアスになります。次に、4つの異なる名前、上記の元の3つの名前、またはINTEGER PRIMARY KEY列に指定された名前のいずれかを使用してROWIDにアクセスできます。これらの名前はすべて相互のエイリアスであり、どのコンテキストでも同等に機能します。

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

したがって、ID列を使用しないことでスペースを節約することはありません。必要かどうかにかかわらず、テーブルごとに1つを取得するからです。


9

次のいずれかに該当する場合は、IDフィールドを使用します。

  1. 自然キーは存在しません(日付は一意ではありません)
  2. 日付フィールドは頻繁に変更されます
  3. 挿入の時点で日付がわからないことがあります。
  4. 複数列の識別子が3列を超えると、結合が冗長になります。

この質問を読んでください:「すべての代理人」をサポートする標準的なソースはありますか?

編集:

私の意見では、上記のいずれも当てはまらないため、IDフィールドを使用する必要ありません必要に応じて使用できます。


1
+1 ID列はスキーマコードの匂いであり、データが実際にリレーショナルモデルに適合しないことを示します。
ロスパターソン

10
@RossPattersonよくわかりません。自然なキーが存在しないかもしれないが、データはまだリレーショナルモデルに適合できる多くの場合を考えることができます。私の頭の上の1つの例:生きている人についての情報を保存します。多くの(すべてではありません!)国は各市民に一意の識別子を割り当てますが、それはその識別子の使用が適切または可能であることを意味しません(レコード作成時に知られていない、割り当てられていない、またはその使用適用される規制などにより禁止されている場合があります)。それは、データがリレーショナルモデルに適合しないことを意味しますか?そうは思いません。
CVn

そして、そのような一意の識別子が存在する場所では、警察などが偽のIDに重複を使用することがあるという、ちょっとおかしい事実があります。そして、それが意図的でない場合、事務的なエラーはとにかく重複を確実にします。
user470365

4
組み込み(Oracleの場合)でも、正真正銘の列として追加しても、非常に便利です。フェンスの両側にいた人(DBAと開発者)として、一意であることを保証できるIDを持つテーブルを重複排除する方がはるかに簡単です。
ロビーディー

1
@RobbieDeeあなたは正しいです。トピック外です。
Tulainsコルドバ

2

また、「日付」列の意味をからに変更created_atupdated_atたり、それらの行に沿って他の変更をしたりすることもあります。これは非常に一般的なケースです。

場合によってid列を追加すると、設計が変更されたときに柔軟性が高まります。


テーブルにdate_createdとdate_modifiedを追加する+1は、行が作成および更新されたときの追跡に非常に役立ちます。リポジトリ/データウェアハウスの更新の問題を調査する場合、これは重要な価値があります。
ロビーディー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.