Apakah saya perlu ID dalam database saya jika catatan dapat diidentifikasi berdasarkan tanggal?


17

Saya menulis aplikasi pertama saya untuk Android dan akan menggunakan database SQLite sehingga akan berusaha membatasi ukuran sebanyak mungkin, tapi saya pikir pertanyaannya berlaku secara umum untuk desain database.

Saya berencana untuk menyimpan catatan yang akan memiliki teks dan tanggal pembuatan. Aplikasi ini adalah aplikasi yang berdiri sendiri, yaitu tidak akan terhubung ke internet dan hanya satu pengguna yang akan memperbaruinya, sehingga tidak ada kemungkinan bahwa akan ada lebih dari satu entri dengan tanggal tertentu.

Apakah meja saya masih membutuhkan kolom ID? Jika demikian, apa keuntungan menggunakan ID sebagai pengidentifikasi catatan dibandingkan dengan Tanggal?


SQLite akan selalu membuat kolom integer untuk rowid jika Anda tidak menentukan PK integer. Jadi jangan mengandalkan kolom "ID" sebagai cara untuk menghemat ruang.
Codism

Saya akan menambahkan bahwa di Android beberapa kelas membutuhkan tabel agar kolom _id berfungsi. Info lebih lanjut di jawaban SO ini .
bigstones

5
Jika Anda mendapatkan tanggal dari telepon itu sendiri dan pengguna melakukan perjalanan ke zona waktu sebelumnya (dan teleponnya memperbarui waktu secara otomatis) maka ada sedikit peluang bahwa Anda bisa mendapatkan cap waktu yang sama lebih dari satu kali.
Eugene

Jawaban:


22

IMHO, menggunakan kolom tanggal sebagai kunci utama sebaiknya dihindari.

Saya telah bekerja pada sistem di mana bidang tanggal digunakan sebagai kunci utama dan menulis kueri untuk menarik kembali himpunan bagian dari data sedikit membosankan jika Anda bekerja dengan bidang tanggal.

Beberapa poin lain yang mungkin ingin Anda pertimbangkan:

Anda mungkin berpikir bahwa suatu titik waktu adalah unik, tetapi itu tergantung pada rincian kolom tanggal. Apakah ini menit, detik, milidetik, dll. Bisakah Anda benar - benar yakin bahwa Anda tidak akan pernah mendapatkan pelanggaran kunci utama?

Terakhir, jika Anda ingin memindahkan basis data ke platform lain, Anda dapat kembali mengalami masalah di mana rincian data tanggal berbeda di antara platform tersebut.

Anda tentu harus menyeimbangkan yang ideal dengan apa yang harus Anda kerjakan. Jika ruang benar-benar sangat memprihatinkan, menggunakan kolom tanggal bisa lebih kecil dari dua kejahatan. Itu adalah keputusan desain yang harus Anda buat.

Edit:

Saya harus menunjukkan bahwa ini tidak menunjukkan bahwa ini adalah keputusan desain yang buruk . Hanya saja mungkin ada masalah dengan kepraktisan RDBMS yang dimaksud.


sudah beberapa saat sejak saya menulis query SQLite, tetapi bukankah menyaring berdasarkan tanggal identik dengan penyaringan dengan bilangan bulat, selain dari deklarasi nilai pengikatan yang lebih verbose?
DougM

Itu hanya lebih verbose dan juga pada beberapa RDBMS Anda mendapatkan masalah di mana elemen hari dan bulan dibalik jika DB telah diatur dalam format AS.
Robbie Dee

Terima kasih, ini semua adalah jawaban yang baik, tetapi pengalaman Anda di tempat kerja pasti menyegel kesepakatan.
Nieszka

Sebagai tambahan untuk ini: Hanya hari ini saya telah diberikan masalah dukungan untuk tabel audit aplikasi di mana mereka mendapatkan pelanggaran kunci utama untuk nomor karyawan dan tanggal akses / PK waktu karena perbedaan waktu antara 2 perangkat klien. ..
Robbie Dee

13

Tidak, Anda tidak benar-benar membutuhkan kolom ID yang ditentukan dalam skema Anda jika Anda dapat menjamin bahwa tidak akan pernah ada tanggal duplikat.

TAPI ...

... yang mengatakan, Anda sebaiknya menggunakannya. Rahasia kecil di sini adalah bahwa SQLite sudah memiliki ID peningkatan otomatis yang unik untuk setiap tabel yang disebut ROWID. Jika Anda mendeklarasikan kolom bilangan bulat peningkatan-otomatis di tabel Anda sebagai PK, SQLite tidak akan membuat kolom baru - itu hanya akan alias kolom ROWID yang sudah ada sebelumnya.

Dalam SQLite, setiap baris dari setiap tabel memiliki ROWID integer bertanda 64-bit. ROWID untuk setiap baris unik di antara semua baris dalam tabel yang sama.

Anda dapat mengakses ROWID dari tabel SQLite menggunakan salah satu nama kolom khusus ROWID, ROWID , atau OID. Kecuali jika Anda mendeklarasikan kolom tabel biasa untuk menggunakan salah satu dari nama-nama khusus itu, maka penggunaan nama itu akan merujuk pada kolom yang dideklarasikan bukan ke ROWID internal.

Jika tabel berisi kolom bertipe INTEGER PRIMARY KEY, maka kolom itu menjadi alias untuk ROWID. Anda kemudian dapat mengakses ROWID menggunakan salah satu dari empat nama yang berbeda, tiga nama asli yang diuraikan di atas atau nama yang diberikan ke kolom KUNCI UTAMA INTEGER. Semua nama ini adalah alias untuk satu sama lain dan berfungsi sama baiknya dalam konteks apa pun.

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

Jadi, Anda tidak akan menghemat ruang apa pun dengan tidak menggunakan kolom ID karena Anda mendapatkan satu per tabel apakah Anda menginginkannya atau tidak!


9

Gunakan bidang ID jika salah satu dari yang berikut ini benar:

  1. Tidak ada kunci alami (tanggal tidak akan unik)
  2. Bidang tanggal akan sering berubah
  3. Tanggal mungkin tidak diketahui pada saat penyisipan.
  4. Pengidentifikasi multi kolom melebihi tiga kolom, yang akan membuat gabungan terlalu bertele-tele.

Baca pertanyaan ini: Apakah ada sumber kanonik yang mendukung "semua-pengganti"?

Edit:

Karena, menurut pendapat saya, tampaknya tidak ada yang di atas berlaku, Anda tidak perlu menggunakan dan bidang ID, tetapi Anda dapat menggunakannya jika Anda mau.


1
+1 kolom ID adalah bau kode skema, menunjukkan bahwa data Anda tidak benar-benar cocok dengan model relasional.
Ross Patterson

10
@ RossPatterson Saya tidak begitu yakin. Saya bisa memikirkan sejumlah kasus di mana tidak ada kunci alami mungkin ada, tetapi data masih dapat sesuai dengan model relasional. Hanya satu kotak di bagian atas kepala saya: menyimpan informasi tentang orang yang masih hidup. Banyak ( tidak semua! ) Negara menetapkan pengidentifikasi unik untuk setiap warga negara, tetapi itu tidak berarti bahwa menggunakan pengenal itu sesuai atau bahkan mungkin (itu mungkin tidak diketahui pada saat pembuatan catatan, mungkin tidak ditugaskan, atau penggunaannya mungkin dilarang misalnya dengan peraturan yang berlaku). Apakah itu berarti bahwa data tidak sesuai dengan model relasional? Saya kira tidak.
CVn

Dan ada sedikit fakta lucu bahwa di mana ada pengidentifikasi unik seperti itu, polisi (dll) kadang-kadang menggunakan duplikat untuk ID palsu mereka. Dan ketika tidak disengaja, kesalahan klerikal akan memastikan adanya duplikasi.
user470365

4
Apakah itu dibangun di (ala Oracle) atau ditambahkan sebagai kolom bonafid, mereka sangat berguna. Sebagai seseorang yang telah berada di kedua sisi pagar (DBA & pengembang), jauh lebih mudah untuk membuat tabel dengan id yang dapat Anda jamin akan unik.
Robbie Dee

1
@RobbieDee Anda benar. Ini di luar topik.
Tulains Córdova

2

Ingatlah bahwa Anda mungkin juga ingin mengubah arti kolom "tanggal" dari created_atmenjadi updated_atatau perubahan lain di sepanjang baris tersebut, yang menurut saya merupakan kasus yang sangat umum.

Menambahkan kolom id dalam beberapa kasus akan memberi Anda lebih banyak fleksibilitas ketika desain Anda berubah.


+1 menambahkan date_created dan date_modified to tables sangat berguna untuk dilacak ketika baris dibuat dan diperbarui. Ini sepadan dengan bobotnya dalam emas ketika menyelidiki masalah pembaruan gudang data / gudang.
Robbie Dee
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.