SORU
27 Mayıs 2011, Cuma


Hangi zaman damgası türü PostgreSQL veritabanı seçmeliyim?

Benim İsim damgaları saklamak için en iyi yöntem çoklu zaman dilimini bir proje kapsamında veritabanı tanımlamak istiyorum.

Edebilirim

  1. TIMESTAMP WITHOUT TIME ZONE seçin ve bu alan için ekleme yaparken kullandığı unutmayın
  2. TIMESTAMP WITHOUT TIME ZONE seçme ve yerleştirme zamanda kullanılan zaman dilimini adını içeren bir alan ekleyin
  3. TIMESTAMP WITH TIME ZONE Ekle zaman buna göre seçin

Seçenek 3 için hafif bir tercih (saat dilimi ile zaman damgası) var ama bu konuda eğitimli bir fikre sahip olmak ister.

CEVAP
27 Mayıs 2011, Cuma


Öncelikle, PostgreSQL zamanı kullanma ve aritmetik harika ve Seçenek 3 genel durum iyi. Ancak, zaman dilimleri ve tamamlanmamış bir görünüm ve takviye edilebilir:

  1. Bir kullanıcı tercihi (örneğin America/Los_Angeles, -0700 değil), bir kullanıcının saat dilimi adı saklayın.
  2. Saat veri referans kendi çerçevesi (UTC -0700 gibi bir uzaklık arasında en sık yerel teslim/kullanıcı olaylar var.
  3. Uygulamada, zaman 10* *TIMESTAMP WITH TIME ZONE bir sütun kullanarak saklı dönüştürmek.
  4. Zaman istekleri bir kullanıcının zaman dilimine yerel (yani America/Los_Angeles 12 *convert) dönüş.
  5. Veritabanı timezone 15 ** ayarlayın.

Bu seçenek, kullanıcının saat dilimi ve dolayısıyla hedge tavsiye almak için sabit basit uygulamalar için TIMESTAMP WITH TIME ZONE kullanmak olabilir, çünkü her zaman işe yaramıyor. Bu, bana daha detaylı bazı arka plan yönleri bu Seçenek 4 açıklamama izin verin. " dedi.

Seçenek 3, WITH TIME ZONE Sebep olan bir şey oldu zaman bir olmasıdırmutlakmoment in time. WITHOUT TIME ZONE verirgörecelisaat dilimi. Asla, asla, asla mutlak ve göreli Zaman karışmaz.

Programlı ve tutarlılık açısından bakıldığında, sağlamak tüm hesaplamaları zaman dilimi olarak UTC kullanılarak yapılır. Bu PostgreSQL bir gereklilik değil, ama diğer programlama dilleri veya ortamlar ile entegre olur. Ayar CHECK sütun emin olmak için yazmak için zaman damgası sütunu olan bir zaman dilimi farkı 0 bir savunma pozisyonu bu engeller bir kaç sınıf böcekler (örneğin, bir komut dosyası veri aktarımları için bir dosya ve bir şey başka türlü zaman verileri kullanarak bir sözcük sıralama). Yine, PostgreSQL tarih hesaplamaları doğru yapmak ya da zaman dilimleri arasında dönüştürme buna ihtiyacı yok (yani PostgreSQL herhangi iki rasgele kez saat dilimleri arasında dönüştürme konusunda çok becerikli. Verileri veritabanı olacak emin olmak için bir sıfır ofset ile saklanır:

CREATE TABLE my_tbl (
  my_timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
  CHECK(EXTRACT(TIMEZONE FROM my_timestamp) = '0')
);
test=> SET timezone = 'America/Los_Angeles';
SET
test=> INSERT INTO my_tbl (my_timestamp) VALUES (NOW());
ERROR:  new row for relation "my_tbl" violates check constraint "my_tbl_my_timestamp_check"
test=> SET timezone = 'UTC';
SET
test=> INSERT INTO my_tbl (my_timestamp) VALUES (NOW());
INSERT 0 1

% 100 mükemmel değil, ama bu veri zaten UTC dönüştürülür emin kılan anti-footshooting yeterince güçlü bir önlem sağlar. Bunun nasıl yapılacağı hakkında görüşler var, ama bu benim deneyim uygulamada en iyi gibi görünüyor.

Eleştiriler veritabanı saat dilimi işleme büyük ölçüde haklı (orada bol veritabanlarına işlemek bu büyük bir beceriksizlik), ancak PostgreSQL ele zaman dilimleri ve oldukça muhteşem (rağmen bir kaç "özellikler" burada ve orada). Örneğin, böyle bir özelliği:

-- Make sure we're all working off of the same local time zone
test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT NOW();
              now              
-------------------------------
 2011-05-27 15:47:58.138995-07
(1 row)

test=> SELECT NOW() AT TIME ZONE 'UTC';
          timezone          
----------------------------
 2011-05-27 22:48:02.235541
(1 row)

AT TIME ZONE 'UTC' saat dilimi bilgi şeritler ve 24 ** bir göreli başvuru hedef çerçeve kullanarak (UTC) oluşturur unutmayın.

TIMESTAMP WITH TIME ZONE, eksik bir zaman dilimi için TIMESTAMP WITHOUT TIME ZONE eksik bir dönüştürme bağlantısı, ahir zaman:

test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT EXTRACT(TIMEZONE_HOUR FROM NOW());
 date_part 
-----------
        -7
(1 row)
test=> SELECT EXTRACT(TIMEZONE_HOUR FROM TIMESTAMP WITH TIME ZONE '2011-05-27 22:48:02.235541');
 date_part 
-----------
        -7
(1 row)

-- Now change to UTC    
test=> SET timezone = 'UTC';
SET
-- Create an absolute time with timezone offset:
test=> SELECT NOW();
              now              
-------------------------------
 2011-05-27 22:48:40.540119 00
(1 row)

-- Creates a relative time in a given frame of reference (i.e. no offset)
test=> SELECT NOW() AT TIME ZONE 'UTC';
          timezone          
----------------------------
 2011-05-27 22:48:49.444446
(1 row)

test=> SELECT EXTRACT(TIMEZONE_HOUR FROM NOW());
 date_part 
-----------
         0
(1 row)

test=> SELECT EXTRACT(TIMEZONE_HOUR FROM TIMESTAMP WITH TIME ZONE '2011-05-27 22:48:02.235541');
 date_part 
-----------
         0
(1 row)

Alt satırında:

  • adında bir etiket (*29 örneğin*) ve UTC (*30 örneğin*) mahsup olarak değil, bir kullanıcının saat dilimi mağaza
  • sıfır olmayan bir mahsup saklamak için zorlayıcı bir neden olmadıkça her şey için UTC kullanın
  • tedavisi olmayan sıfır giriş hata olarak UTC kez
  • hiç karıştırın ve göreli ve mutlak zaman maç
  • ayrıca kullanımı veritabanı timezone UTC

Rastgele bir programlama dili olan not: Python datetime veri türünü çok iyi muhafaza ayrım arasında mutlak vs göreli kat daha da sinir bozucu ilk başlarda kadar ek bir kütüphane gibi PyTZ).


EDİT

Bana vs mutlak biraz daha göreceli arasındaki farkı açıklamama izin verin.

Mutlak zaman bir olay kaydetmek için kullanılır. Örnek: "Kullanıcı 123" veya "2011-05-28 2 PST. mezuniyet törenleri bir başlangıç" oturum Eğer olayın gerçekleştiği teleport eğer yerel zaman dilimi ne olursa olsun, yaşanan olaya şahit olabilir. Veritabanındaki çoğu zaman verileri mutlak (ve bu nedenle TIMESTAMP WITH TIME ZONE ideal bir uzaklık 0 metin ve etiket kuralları, belirli bir zaman dilimini temsil eden yöneten - ofset olmalıdır).

Göreceli bir olay ya da henüz-için-olmak-belli bir zaman dilimi açısından bir kez kayıt zamanlama olurdu. Örnekler: "bizim iş kapıları 9'da sabah 8 de ve Kapat aç.", "hadi haftalık kahvaltılı toplantı için sabah 7'de her Pazartesi görüşürüz," ya akşam saat 8." "Her Cadılar bayramında Genel olarak, göreceli zaman olayları için bir şablon veya bir fabrikada kullanılan ve mutlak zaman hemen hemen her şey için kullanılır. Göreli kat değeri göstermek gerektiğini işaret değer bir istisna var. Hangi şey oluşabilir mutlak zamanı hakkında bir belirsizlik olduğu gelecekte yeterince uzak gelecekteki olaylar için, göreceli bir zaman damgası kullanın. İşte gerçek dünya örneği:

Bu yıl ABD West Coast (35*/PST8PDTyani*) 1 de 2008 yılında 31 Ekim tarihinde bir teslimat planlamak için ihtiyacınız olan 2004 ve olduğunu varsayın. Eğer ABD Hükümeti Energy Policy Act of 2005 geçti çünkü eğer mutlak Zaman Saat 2'de ortaya çıkmış olmalıydı ’2008-10-31 21:00:00.000000 00’::TIMESTAMP WITH TIME ZONE, kullanarak eğer kayıtlı kuralları Yaz Saati yönetim değişti. 2004 yılında teslim edildi planlanan tarih 10-31-2008 olurdu Pasifik Standart Saati ( 8000), ancak başlangıç yılı 2005 saat veritabanları tanıyan 10-31-2008 olurdu Pasifik Yaz Saati ( 0700). Zaman göreceli bir zaman damgası depolamak bölge göreceli bir zaman damgası Kongresi için bağışıklık’ hasta bilgilendirilmiş kurcalama. çünkü doğru bir teslimat takvimi sonuçlanırdı Nerede kesim arasında kullanarak göreli vs mutlak kez zamanlama şeyler, bir bulanık çizgi, ama benim başparmak kuralı olduğunu zamanlama için bir şey gelecekte daha fazla 3-6mo gerektiğini faydalanmak göreli zaman (planlanmış = mutlak vs planlanmış = akraba mı ???).

Göreli zaman başka/geçen yazın INTERVAL. Örnek: "oturum 20 dakikalık bir kullanıcı günlükleri sonra zaman aşımına olur". INTERVAL bir doğru mutlak zaman (TIMESTAMP WITH TIME ZONE) veya göreli zaman (TIMESTAMP WITHOUT TIME ZONE) de kullanılabilir. Söylemek aynı derecede doğru, "kullanıcı oturumu başarılı bir giriş (login_utc session_duration) 20 dk sonra sona eriyor" ya da "sabah kahvaltı toplantımız sadece son 60 dakika (recurring_start_time meeting_length)".

Karışıklık son bit: DATE, TIME, TIME WITHOUT TIME ZONE ve TIME WITH TIME ZONE göreli veri türleri. Örneğin: '2011-05-28'::DATE hiçbir zaman beri göreceli bir tarihi temsil eder gece yarısı tanımlamak için kullanılabilecek dilimi bilgileri. Benzer şekilde, '23:23:59'::TIME her iki saat dilimi veya DATE tarafından temsil bilmiyorsun çünkü görecelidir. Hatta '23:59:59-07'::TIME WITH TIME ZONE ile DATE ne olacağını bilmiyorsun. Ve son olarak, DATE bir zaman dilimini aslında DATE, TIMESTAMP WITH TIME ZONE bir: bir değildir

test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT '2011-05-11'::DATE AT TIME ZONE 'UTC';
      timezone       
---------------------
 2011-05-11 07:00:00
(1 row)

test=> SET timezone = 'UTC';
SET
test=> SELECT '2011-05-11'::DATE AT TIME ZONE 'UTC';
      timezone       
---------------------
 2011-05-11 00:00:00
(1 row)

Veritabanlarında tarih ve saat dilimleri koyarak iyi bir şey, ama öylekolay kurnazca yanlış sonuçlar elde etmek için.En az ek çaba ve zaman bilgileri doğru saklamak için gereklidir ve tamamen, ancak bu ekstra çaba her zaman gerekli olduğu anlamına gelmez.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Defence Videos

    Defence Vide

    13 Mayıs 2013
  • Megan Parken

    Megan Parken

    19 Temmuz 2009
  • ŠĩŗĜŕôŵåɭȍҭҭ

    ŠĩŗĜŕô

    29 Kasım 2009