Saya ingin menyimpan waktu dalam tabel database tetapi hanya perlu menyimpan jam dan menit. Saya tahu saya bisa saja menggunakan DATETIME dan mengabaikan komponen tanggal lainnya, tetapi apa cara terbaik untuk melakukan ini tanpa menyimpan lebih banyak info daripada yang sebenarnya saya butuhkan?
sql-server
database
database-design
datetime
Matthew Dresser
sumber
sumber
Jawaban:
Anda dapat menyimpannya sebagai bilangan bulat dari jumlah menit lewat tengah malam:
misalnya.
Namun Anda perlu menulis beberapa kode untuk mengatur ulang waktu, tetapi itu seharusnya tidak rumit.
sumber
Jika Anda menggunakan SQL Server 2008+, pertimbangkan
TIME
tipe data. Artikel SQLTeam dengan lebih banyak contoh penggunaan.sumber
Saya mohon Anda untuk menggunakan dua nilai DATETIME sebagai gantinya, diberi label seperti event_start dan event_end .
Waktu adalah urusan yang kompleks
Sebagian besar dunia sekarang telah mengadopsi sistem metrik berbasis pemandangan untuk sebagian besar pengukuran, benar atau salah. Ini bagus secara keseluruhan, karena setidaknya kita semua bisa sepakat bahwa ag, adalah ml, adalah cm kubik. Setidaknya kira-kira begitu. Sistem metrik memiliki banyak kekurangan, tetapi setidaknya secara internasional selalu cacat.
Namun seiring waktu, kami memiliki; 1000 milidetik dalam satu detik, 60 detik hingga satu menit, 60 menit hingga satu jam, 12 jam untuk setiap setengah hari, kira-kira 30 hari per bulan yang bervariasi menurut bulan dan bahkan tahun yang bersangkutan, setiap negara memiliki waktu yang berbeda dari yang lain , format waktu di setiap negara berbeda-beda.
Banyak yang harus dicerna, tetapi panjang dan pendeknya tidak mungkin skenario serumit itu memiliki solusi sederhana.
Beberapa sudut dapat dipotong, tetapi ada yang lebih bijaksana untuk tidak melakukannya
Meskipun jawaban teratas di sini menunjukkan bahwa Anda menyimpan bilangan bulat menit lewat tengah malam mungkin tampak masuk akal, saya telah belajar untuk menghindari melakukannya dengan cara yang sulit.
Alasan untuk menerapkan dua nilai DATETIME adalah untuk peningkatan akurasi, resolusi, dan umpan balik.
Ini semua sangat berguna ketika desain menghasilkan hasil yang tidak diinginkan.
Apakah saya menyimpan lebih banyak data dari yang dibutuhkan?
Awalnya mungkin tampak seperti lebih banyak informasi disimpan daripada yang saya butuhkan, tetapi ada alasan bagus untuk menerima serangan ini.
Menyimpan informasi tambahan ini hampir selalu menghemat waktu dan tenaga saya dalam jangka panjang, karena saya pasti menemukan bahwa ketika seseorang diberitahu berapa lama sesuatu berlangsung, mereka juga akan ingin tahu kapan dan di mana acara itu terjadi juga.
Itu adalah planet yang sangat besar
Di masa lalu, saya bersalah karena mengabaikan bahwa ada negara lain di planet ini selain negara saya. Sepertinya ide yang bagus pada saat itu, tetapi ini SELALU mengakibatkan masalah, sakit kepala, dan waktu yang terbuang di kemudian hari. SELALU pertimbangkan semua zona waktu.
C #
Sebuah DateTime merender dengan baik ke string di C #. Metode ToString (format string) ringkas dan mudah dibaca.
Misalnya
Server SQL
Juga jika Anda membaca database Anda secara terpisah dari antarmuka aplikasi Anda, maka dateTimes menyenangkan untuk dibaca sekilas dan melakukan penghitungan pada mereka sangatlah mudah.
Misalnya
Standar tanggal ISO8601
Jika menggunakan SQLite maka Anda tidak memiliki ini, jadi gunakan bidang Teks dan simpan dalam format ISO8601 mis.
"2013-01-27T12: 30: 00 + 0000"
Catatan:
Ini menggunakan format 24 jam *
Bagian offset waktu (atau +0000) dari ISO8601 memetakan langsung ke nilai bujur koordinat GPS (tidak memperhitungkan pergeseran waktu siang hari atau seluruh negara).
Misalnya
... dimana ± mengacu pada arah timur atau barat.
Oleh karena itu perlu dipertimbangkan apakah perlu menyimpan bujur, lintang dan ketinggian bersama dengan datanya. Ini akan bervariasi dalam penerapannya.
ISO8601 adalah format internasional.
Wiki sangat bagus untuk detail lebih lanjut di http://en.wikipedia.org/wiki/ISO_8601 .
Tanggal dan waktu disimpan dalam waktu internasional dan offset dicatat tergantung di mana di dunia waktu itu disimpan.
Menurut pengalaman saya, selalu ada kebutuhan untuk menyimpan tanggal dan waktu penuh, terlepas dari apakah saya pikir ada saat saya memulai proyek. ISO8601 adalah cara yang sangat bagus dan futureproof untuk melakukannya.
Saran tambahan gratis
Ada baiknya juga mengelompokkan acara bersama seperti sebuah rangkaian. Misalnya, jika merekam balapan, seluruh acara dapat dikelompokkan berdasarkan pembalap, sirkuit_balap, titik pemeriksaan sirkuit, dan sirkuit_lap.
Menurut pengalaman saya, adalah bijaksana juga untuk mengidentifikasi siapa yang menyimpan catatan tersebut. Baik sebagai tabel terpisah yang diisi melalui pemicu atau sebagai kolom tambahan dalam tabel asli.
Semakin banyak Anda memasukkan, semakin banyak Anda keluar
Saya sepenuhnya memahami keinginan untuk menjadi seefisien mungkin dengan ruang, tetapi saya jarang melakukannya dengan mengorbankan informasi yang hilang.
Aturan praktis dengan database adalah seperti judulnya, database hanya dapat memberi tahu Anda sebanyak yang ada datanya, dan bisa sangat mahal untuk kembali melalui data historis, mengisi celah.
Solusinya adalah memperbaikinya pertama kali. Ini tentu lebih mudah diucapkan daripada dilakukan, tetapi Anda sekarang harus memiliki wawasan yang lebih dalam tentang desain database yang efektif dan kemudian memiliki peluang yang jauh lebih baik untuk melakukannya dengan benar pada kali pertama.
Semakin baik desain awal Anda, semakin murah biaya perbaikannya nanti.
Saya hanya mengatakan semua ini, karena jika saya bisa kembali ke masa lalu maka itulah yang akan saya katakan pada diri saya sendiri ketika saya sampai di sana.
sumber
Simpan saja tanggal waktu biasa dan abaikan yang lainnya. Mengapa menghabiskan waktu ekstra untuk menulis kode yang memuat int, memanipulasinya, dan mengubahnya menjadi datetime, ketika Anda bisa memuat datetime?
sumber
DATETIME
Tipe data membutuhkan 4 byte untuk disimpan, sementaraSMALLINT
misalnya, hanya membutuhkan seperempat dari itu. Tidak ada perbedaan besar jika Anda hanya memiliki beberapa ribu baris, tetapi jika Anda memiliki jutaan baris seperti yang dimiliki banyak perusahaan, maka penghematan ruang Anda akan sangat besar.karena Anda tidak menyebutkannya sedikit jika Anda menggunakan SQL Server 2008 Anda dapat menggunakan tipe data waktu jika tidak menggunakan menit sejak tengah malam
sumber
SQL Server sebenarnya menyimpan waktu sebagai pecahan hari. Misalnya, 1 whole day = nilai 1. 12 hours adalah nilai 0.5.
Jika Anda ingin menyimpan nilai waktu tanpa menggunakan tipe DATETIME, menyimpan waktu dalam bentuk desimal akan sesuai dengan kebutuhan itu, sementara juga membuat konversi ke DATETIME sederhana.
Sebagai contoh:
Menyimpan nilai sebagai DECIMAL (9,9) akan memakan 5 byte. Namun, jika presisi tidak terlalu penting, REAL hanya akan mengkonsumsi 4 byte. Dalam kedua kasus, penghitungan agregat (yaitu waktu rata-rata) dapat dengan mudah dihitung pada nilai numerik, tetapi tidak pada jenis Data / Waktu.
sumber
Saya akan mengubahnya menjadi integer (HH * 3600 + MM * 60), dan menyimpannya seperti itu. Ukuran penyimpanan kecil, dan masih cukup mudah untuk dikerjakan.
sumber
Jika Anda menggunakan MySQL, gunakan jenis bidang TIME dan fungsionalitas terkait yang disertakan dengan TIME.
00:00:00 adalah format waktu unix standar.
Jika Anda harus melihat ke belakang dan meninjau tabel dengan tangan, bilangan bulat bisa lebih membingungkan daripada stempel waktu yang sebenarnya.
sumber
Coba waktu kecil. Ini mungkin tidak memberikan apa yang Anda inginkan tetapi akan membantu kebutuhan Anda di masa depan dalam manipulasi tanggal / waktu.
sumber
Apakah Anda yakin Anda hanya membutuhkan jam dan menit? Jika Anda ingin melakukan sesuatu yang berarti dengannya (seperti misalnya rentang waktu komputasi antara dua titik data) tidak memiliki informasi tentang zona waktu dan DST dapat memberikan hasil yang salah. Zona waktu mungkin tidak berlaku dalam kasus Anda, tetapi DST pasti akan berlaku.
sumber
Alih-alih menit lewat tengah malam kami menyimpannya sebagai format 24 jam, sebagai SMALLINT.
09:12 = 912 14:15 = 1415
saat mengonversi kembali ke "bentuk yang dapat dibaca manusia" kami hanya menyisipkan titik dua ":" dua karakter dari kanan. Kiri-pad dengan nol jika perlu. Menyimpan matematika dengan cara apa pun, dan menggunakan beberapa byte lebih sedikit (dibandingkan dengan varchar), ditambah penegakan bahwa nilainya adalah numerik (bukan alfanumerik)
Cukup konyol ... seharusnya sudah ada tipe data TIME di MS SQL selama setahun sudah IMHO ...
sumber
Apa yang saya pikir Anda minta adalah variabel yang akan menyimpan menit sebagai angka. Ini dapat dilakukan dengan berbagai jenis variabel integer:
Kemudian, dalam program Anda, Anda cukup melihat ini dalam bentuk yang Anda inginkan dengan menghitung:
Masalah muncul ketika Anda meminta efisiensi untuk digunakan. Tapi, jika Anda kekurangan waktu, gunakan saja BigInt nullable untuk menyimpan nilai menit Anda.
Nilai null berarti waktu belum direkam.
Sekarang, saya akan jelaskan dalam bentuk perjalanan pulang pergi ke luar angkasa.
Sayangnya, kolom tabel hanya akan menyimpan satu jenis. Oleh karena itu, Anda perlu membuat tabel baru untuk setiap jenis sesuai kebutuhan.
Sebagai contoh:
Jika MinutesInput = 0 .. 255 maka gunakan TinyInt (Ubah seperti dijelaskan di atas).
Jika MinutesInput = 256 .. 131071 maka gunakan SmallInt (Catatan: Nilai min SmallInt adalah -32,768. Oleh karena itu, negasikan dan tambahkan 32768 saat menyimpan dan mengambil nilai untuk menggunakan jangkauan penuh sebelum mengonversi seperti di atas).
Jika MinutesInput = 131072 .. 8589934591 kemudian gunakan Int (Catatan: Negasikan dan tambahkan 2147483648 seperlunya).
Jika MinutesInput = 8589934592 .. 36893488147419103231 kemudian gunakan BigInt (Catatan: Tambahkan dan hapus 9223372036854775808 seperlunya).
Jika MinutesInput> 36893488147419103231 maka saya pribadi akan menggunakan VARCHAR (X) meningkatkan X seperlunya karena char adalah byte. Saya harus meninjau kembali jawaban ini di kemudian hari untuk menjelaskan ini secara lengkap (atau mungkin rekan stackoverflowee dapat menyelesaikan jawaban ini).
Karena setiap nilai pasti memerlukan kunci unik, efisiensi database hanya akan terlihat jika kisaran nilai yang disimpan adalah campuran yang baik antara sangat kecil (mendekati 0 menit) dan sangat tinggi (Lebih dari 8589934591).
Sampai nilai yang disimpan benar-benar mencapai angka yang lebih besar dari 36893488147419103231 maka Anda mungkin juga memiliki satu kolom BigInt untuk mewakili menit Anda, karena Anda tidak perlu membuang Int pada pengenal unik dan int lain untuk menyimpan nilai menit.
sumber
Penghematan waktu dalam format UTC dapat membantu lebih baik seperti yang disarankan Kristen.
Pastikan Anda menggunakan jam 24 jam karena tidak ada meridian AM atau PM yang digunakan dalam UTC.
Contoh:
Ini masih lebih disukai untuk menggunakan format empat digit standar.
sumber
Simpan
ticks
sebagai along
/bigint
, yang saat ini diukur dalam milidetik. Nilai yang diperbarui dapat ditemukan dengan melihatTimeSpan.TicksPerSecond
nilainya.Kebanyakan database memiliki tipe DateTime yang secara otomatis menyimpan waktu sebagai tick di belakang layar, tetapi dalam kasus beberapa database misalnya SqlLite, menyimpan tick dapat menjadi cara untuk menyimpan tanggal.
Kebanyakan bahasa memungkinkan konversi yang mudah dari
Ticks
→TimeSpan
→Ticks
.Contoh
Di C # kodenya adalah:
Berhati-hatilah, karena dalam kasus SqlLite, yang hanya menawarkan sejumlah kecil tipe berbeda, yaitu;
INT
,REAL
danVARCHAR
Jumlah kutu perlu disimpan sebagai string atau duaINT
sel yang digabungkan. Ini, karenaINT
adalah nomor bertanda 32bit sedangkanBIGINT
nomor bertanda 64bit.Catatan
Preferensi pribadi saya bagaimanapun, akan menyimpan tanggal dan waktu sebagai
ISO8601
string.sumber
IMHO apa solusi terbaik tergantung sampai batas tertentu pada bagaimana Anda menyimpan waktu di sisa database (dan sisa aplikasi Anda)
Secara pribadi saya telah bekerja dengan SQLite dan mencoba untuk selalu menggunakan stempel waktu unix untuk menyimpan waktu absolut, jadi ketika berhadapan dengan waktu hari (seperti yang Anda minta) saya melakukan apa yang ditulis Glen Solsberry dalam jawabannya dan menyimpan jumlah detik sejak tengah malam
Saat mengambil pendekatan umum ini, orang-orang (termasuk saya!) Membaca kode tidak terlalu bingung jika saya menggunakan standar yang sama di mana-mana
sumber