Küsimus
Vastus (09.10.2025 12:55):
1. PostgreSQLis on eraldi andmetüübid TIMESTAMP (sama, mis TIMESTAMP WITHOUT TIME ZONE) ja TIMESTAMPTZ (sama, mis TIMESTAMP WITH TIME ZONE). Sisemiselt salvestatakse need mõlemad kaheksabaidise täisarvuna, mis näitab mikrosekundites erinevust ajahetkest 2000-01-01 00:00:00. TIMESTAMPTZ korral salvestatakse erinevus ajahetkest 2000-01-01 00:00:00 koordineeritud universaalaja (UTC) järgi.
Selleks, et tagada arvutuste täpsus (nt arvestada suve ja talveajaga) on soovitus salvestada ka ajavööndi info. Kasutajale esitatud andmetes saab ajavööndi peita. Kui salvestada ajavööndi info, siis saab ka näidata kasutajale ajahetke just tema ajavööndi järgi.CREATE TABLE Ajatempel(tempel1 TIMESTAMPTZ(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0));
INSERT INTO Ajatempel(tempel1)
VALUES (DEFAULT);
Siin on päring, mis tagastab sama ajavööndi andmetega ajahetke alusel erineva info. Ajavöönd on ilmutatult välja toodud ainult esimeses veerus olevas väärtuses.
SELECT tempel1 AS ajavöönd_näha,
tempel1::timestamp AS kohalik_ajavöönd_peidetud1,
tempel1 AT TIME ZONE 'Europe/Tallinn' AS kohalik_ajavöönd_peidetud2,
tempel1 AT TIME ZONE 'UTC' AS UTC_aeg,
tempel1 AT TIME ZONE 'America/New_York' AS aeg_USA_idarannikul
FROM Ajatempel;
Määra nii veeru tüübi kui ka vaikimisi väärtuse korral täpsus 0.
tempel1 TIMESTAMPTZ(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0)
Näide:
DROP TABLE IF EXISTS Ajatempel;
CREATE TABLE Ajatempel(tempel1 TIMESTAMPTZ(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
tempel2 TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP(0));
INSERT INTO Ajatempel(tempel1, tempel2)
VALUES (DEFAULT, DEFAULT);
SELECT *
FROM Ajatempel;
Mõlemas väljas on ühesugune väärtus - rea lisamise kuupäev ja kellaaeg ajavööndiga, kuid ilma sekundi murdosadeta.
Veeru tempel1 korral on see saavutatud veeru tasemel deklareeritud kitsendusega, mis ütleb, et veerus sekundi murdosa ei registreerita.
Veeru tempel2 korral on see saavutatud vaikimisi väärtuse leidmise kaudu. Vaikimisi väärtusena registreeritud väärtuse saab teatavasti üle kirjutada.
UPDATE Ajatempel SET tempel2=CURRENT_TIMESTAMP;
Nüüd on veerus tempel2 ka sekundi murdosad. Selles mõttes on veeru tempel1 korral kasutatud lahendus parem.
Ajatempli tüüpi veeru täpsuse muutmiseks on lause:
ALTER TABLE Ajatempel ALTER COLUMN tempel2 SET DATA TYPE timestamptz(0);
Kui sekundi murdosasid pole vaja registreerida, siis ongi parim lahendus selline, kus sekundi murdosade arvu piiratakse nii veeru tüübi kui ka vaikimisi väärtuse deklareerimisel.
Arvestage sellega, et CURRENT_TIMESTAMP(0) tagastab sekundid, ümardades sekundi murdosasid.
Kui kasutan modelleerimiseks ja SQL koodi genereerimiseks Enterprise Architect 12 või 16 modelleerimisvahendeid, siis saan seal PostgreSQL andmebaasi disaini mudelis määrata TIMESTAMP ja TIMESTAMP WITH TIME ZONE tüüpi veeru korral pikkuse (length) 0, kuid vaikimisi kasutatavate koodi genereerimise mallide korral sellega koodi genereerimisel ei arvestata.