Articles

Tipuri de date PostgreSQL: Date, Timestamp și fusuri orare

Posted by admin

continuarea seriei noastre de tipuri de date PostgreSQL astăzivom introduce tipurile de date date, timestamp și interval.

implementarea PostgreSQL a calendarului este foarte bună și vomarată câteva exemple de șoareci despre cât de confuză este această problemă. Timpul zonenotion, în special, este în principal un instrument politic în aceste zile, și-l face nosense pe o inginerie principiu: nu există nici o modalitate de a rezolva în timp zoneproblems de prima mana principii!,

Data/Ora și Zone de Timp

Manipularea datelor și de timp și zone de timp este o chestiune foarte complexă, și peaceasta tema, puteți citi Erik Naggum piesa Lung, Dureros de Istorie timp.

PostgreSQL documentația de capitole cu titluri Data/TimeTypes,Tip de Date FormattingFunctions și Data/Ora de Funcții andOperatorscover tot ce trebuie să știi despre data, ora, marcajele de timp și zone de timp withPostgreSQL.prima întrebare la care trebuie să răspundem aici este despre utilizarea marcajelor de timp cu orfără fusuri orare din aplicațiile noastre., Răspunsul este simplu: utilizați întotdeaunamarcele cu fusuri orare.un mit comun este că stocarea fusurilor orare se va adăuga cu siguranță la amprenta dvs. de stocareși memorie. Chiar nu e cazul:

select pg_column_size(timestamp without time zone 'now'), pg_column_size(timestamp with time zone 'now');
 pg_column_size │ pg_column_size ════════════════╪════════════════ 8 │ 8(1 row)

PostgreSQL implicit la utilizarea bigint pe plan intern pentru a stoca marcajele de timp, și de pe hard disk și memorie de format sunt aceleași cu sau fără timp zonesupport., Aici e tot de tip definiție în PostgreSQL cod sursă(în src/include/datatype/timestamp.h):

typedef int64 Timestamp;typedef int64 TimestampTz;

De la PostgreSQL documentația pentru marcajele de timp, iată cum funcționează:

Pentru timestamp cu fusul orar, pe plan intern, valoarea stocată este întotdeauna în UTC(Timpul Universal Coordonat, în mod tradițional cunoscut ca Greenwich Mean Time,GMT). O valoare de intrare care are specificată o fus orar explicit este convertită la UTC utilizând compensarea corespunzătoare pentru fusul orar respectiv., Dacă nu există fusul orar isstated în șirul de intrare, atunci se presupune a fi în timp zoneindicated de sistem de fus Orar parametru, și este convertit la UTCusing offset pentru zona de fus orar.

PostgreSQL nu stochează fusul orar din care provin cu marca de timp.În schimb se convertește la și de la intrare și de ieșire fusul orar mult likewe ‘ ve văzut pentru text cu client_encoding.

în acest script, ne jucăm cu fusul orar stabilit de client și schimbăm de la o valoare franceză la o altă valoare franceză, deoarece Tahiti este o insulă din Pacific care face parte din Franța., Aici e plin de ieșire, atunci când se runningthis script, atunci când a lansat cu psql -a -f tz.sql:

în Primul rând, vedem că acum() funcția returnează întotdeauna același timestampwithin o singură tranzacție. Dacă doriți să vedeți ceasul care rulează în timp ce se află în atransaction, utilizați în schimb funcția clock_timestamp ().

apoi, vom vedea că atunci când vom schimba setarea client fus orar, PostgreSQLoutputs marcaje de timp cum era de așteptat, în fusul orar selectat., Dacă ați reușit anapplication cu utilizatorii în diferite zone de timp și doriți să se afișeze în propria lor locale fus orar preferat, atunci puteți seta fusul orar în yourapplication cod înainte de a face orice timestamp legate de procesare, și havePostgreSQL face toate munca grea pentru tine.,

în cele din Urmă, atunci când selectarea înapoi de la tstz masă, vom vedea că columntstz își dă seama că atât introdus valorile sunt de fapt același punct intim, dar văzut din diferite locuri din lume, întrucât ts columnmakes este imposibil de a compara intrările și dau seama că actuallyhappened în exact același timp.

Cum am spus înainte, chiar și atunci când utilizați marcajele de timp cu fusul orar, PostgreSQL vanu magazin fusul orar în uz la intrare de timp, astfel încât nu există nici o modalitate de ourtstz masă să știi că intrările sunt, în același timp, dar doar de diferitele locuri.,

deschiderea acestei secțiuni se leagă de istoria lungă și dureroasă a timpului și, dacă nu ați citit-o încă, poate că este un moment bun. Permiteți-mi să citez o parte relevantă a articolului aici:

problema De bază cu oră este că trebuie să-și exprime atât timp andplace ori de câte ori vrem să loc un eveniment în timp și spațiu, dar avem tendinta sa presupunem coordonatele spațiale chiar mai mult decât presupunem temporalcoordinates, iar în caz de timp în obișnuite de comunicare, se issimply omis în întregime., În ciuda existenței unor zone de timp și strangedaylight saving time regimurile din întreaga lume, cei mai mulți oameni sunt blithelyunaware de propriile lor zone de timp și, desigur, de modul în care aceasta se referă la standardreferences. Cei mai mulți oameni sunt la fel de conștienți că prin alegerea unui notationthat este aproape de vorbit sau de exprimare scrisă de date, se face itmeaningless pentru oameni care nu pot împărtăși cultura, dar poate mai citesti ceva de limbă., Este puțin probabil că oamenii se vor schimba suficient pentru a pune theseissues să se odihnească, așa că responsabil de calculator oamenii au nevoie pentru a se adresa problemelor rezista altfel copleșitoare nevoia de a abrevia și dropcontext.

Mai multe opțiuni sunt disponibile pentru a introduce valorile timestamp în PostgreSQL. Cel mai ușor este să utilizați formatul ISO, așa că dacă codul aplicației dvs. permite acest lucrueste totul setat. În exemplul următor, lăsăm fusul orar afară, cade obicei, este gestionat de parametrul sesiune de fus orar, așa cum se vede mai sus., Dacă e nevoie, desigur, puteți introduce timpul în zona timestamp valuesdirectly:

select timestamptz '2017-01-08 04:05:06', timestamptz '2017-01-08 04:05:06+02';

La inserare sau actualizare de timp, utilizați același literal siruri de caractere fără typedecoration: PostgreSQL știe deja tipul de țintă coloană, și ituses că pentru a analiza valorile literale în DML.unele cazuri de utilizare a aplicațiilor au nevoie doar de dată. Apoi utilizați tipul de date dateîn PostgreSQL., Desigur, este posibil de a compara o data si atimestamp cu zona de timp în interogări SQL, și chiar să adăugați un timeoffset pe partea de sus de data ta de a construi un timestamp.

intervale de timp

PostgreSQL implementează un tip de date interval, împreună cu ora, dateand timestamptz tipuri de date.,rație, cum ar fi o săptămână sau două, sau chiar o milisecundă:

set intervalstyle to postgres;select interval '1 month', interval '2 weeks', 2 * interval '1 week', 78389 * interval '1 ms';

implicit PostgreSQL de ieșire arată astfel:

 interval │ interval │ ?column? │ ?column? ══════════╪══════════╪══════════╪══════════════ 1 mon │ 14 days │ 14 days │ 00:01:18.389(1 row)

mai Multe intervalstyle valori sunt posibile, și settingpostgres_verbose este destul de frumos pentru interactive psql sesiuni:

set intervalstyle to postgres_verbose;select interval '1 month', interval '2 weeks', 2 * interval '1 week', 78389 * interval '1 ms';

de Această dată vom obține un user-friendly de ieșire:

 interval │ interval │ ?column? │ ?column? ══════════╪═══════════╪═══════════╪═════════════════════ @ 1 mon │ @ 14 days │ @ 14 days │ @ 1 min 18.389 secs(1 row)

Cât de mult este de o lună?, Ei bine, depinde pe ce lună, și PostgreSQL knowsthat:

atunci Când atașați un interval de o data sau timestamp în PostgreSQL apoi de numărul de zile în care interval se adapteaza la calendar specific entryyou-am ales. În caz contrar, un interval de o lună este considerat a fi de 30zile. Aici vedem că calcularea ultimei zile a lunii februarie este foarte ușoară:

concluzie

implementarea calendarului PostgreSQL este foarte bună, deci folosiți-o!,

Acest articol este un extras din cartea mea Stăpânirea PostgreSQL în ApplicationDevelopment, care învață SQL todevelopers, astfel încât acestea pot înlocui mii de linii de cod cu foarte simple interogări. Cartea are un capitol complet despre tipurile de date din PostgreSQL,verificați-l!

Leave A Comment