Kiedy Denormalizować projekt bazy danych

Wiem, że normalizacja była szeroko omawiana na temat przepełnienia stosu. Czytałem wiele poprzednich dyskusji. Mam kilka dodatkowych pytań.

Pracuję nad starym systemem z co najmniej 100 tabelami. Baza danych ma pewną unormowaną strukturę, tabele zawierające różne różne dane i inne problemy. Dostałem zadanie ulepszenia go. Nie mogę po prostu zacząć od nowa, ale muszę zmodyfikować istniejące schemat.

W przeszłości zawsze starałem się projektować znormalizowane bazy danych. Teraz pytania. Starszy programista zasugerował, że w niektórych przypadkach nie możemy normalizować:

  1. Z danymi czasowymi. Na przykład powstaje faktura, która łączy się z produktem. Jeśli klient poprosi o kopię tej faktury rok później, musimy być w stanie przedstawić dokładną kopię oryginału. Co zrobić, jeśli cena produktu, nazwa lub opis zostały zaktualizowane? Starszy facet zasugerował, że cena inne informacje o produkcie należy skopiować do tabeli faktur. Myślę, że może powinniśmy mieć inną tabelę, taką jak productPrice, która ma pole daty, abyśmy mogli śledzić zmiany cen w czasie. Potrzebowalibyśmy tego samego do opisu produktu i nazwy, jak sądzę? To skomplikowane. Co o tym myślisz?

  2. Baza danych jest systemem księgowym. Nie znam się na księgowości. W tej chwili niektóre dane sumaryczne są pobierane i przechowywane w bazie danych. Na przykład sprzedaży całkowitej w danym roku. Mój starszy współpracownik powiedział, że księgowi lubią sprawdzać poprawność rzeczy, porównując tę wartość z danymi, które są faktycznie obliczane z faktur itp., aby dać im pewność, że aplikacja działa poprawnie.

Powiedział, że w tej chwili na przykład możemy stwierdzić, czy ktoś omyłkowo usunął fakturę z zeszłego roku, ponieważ sumy nie będą takie same. Zwrócił też uwagę, że można dość wolno wyliczyć te / align = "left" / Oczywiście powiedziałem, że dane nie powinny być powielane i zawsze powinny być obliczane w razie potrzeby. Zasugerowałem, że możemy użyć SQL Reporting Services lub innego rozwiązania, które będzie generować te raporty z dnia na dzień i buforować je. W każdym razie nie jest przekonany. Jakieś uwagi na ten temat?

Author: user207421, 2010-11-29

9 answers

Twój starszy kolega jest programistą, a nie modelerem danych. Lepiej zacząć od zera, bez nich. Normalizacja jest skomplikowana tylko dla tych, którzy nie będą czytać książek. To jest sprawiedliwe, że on sprawia, że myślisz, ale niektóre kwestie są absurdalne.

Twoje liczby:

  1. Musisz docenić różnice między rzeczywistymi danymi online, a danymi historycznymi; następnie różnicę między potrzebami jedynie historycznymi i archiwalnymi. Wszystkie mają rację. dla konkretnego wymogu biznesowego, a nie dla wszystkich innych, nie ma uniwersalnego dobra i zła.

    • dlaczego nie ma papierowej kopii faktury ? W większości krajów, które byłyby wymogiem prawnym i podatkowym, jaka dokładnie jest trudność wyłudzenia starej faktury ?
    • jeśli baza danych ma wymóg przechowywania zamkniętych faktur, to oczywiście, gdy tylko faktura zostanie zamknięta, potrzebujesz metody przechwytywania, że informacje.
    • ProductPrice (właściwie nazwałbym to ProductDate) to dobry pomysł, ale może nie być konieczny. Ale masz rację, trzeba ocenić walutę danych, w pełnym kontekście całej bazy danych.
    • nie widzę, jak skopiowanie ceny produktu do tabeli faktur pomogłoby (nie ma wielu pozycji liniowych ?)
    • we współczesnych bazach danych, gdzie wymagane jest zwrócenie kopii faktury, zamknięta Faktura jest dodatkowo przechowywana w innym formularz, np. XML. Jeden klient zapisuje pliki PDF jako obiekty BLOB. Więc nie ma żadnych problemów z tym, co cena produktu była pięć lat temu. Ale podstawowe dane do faktur są online i aktualne, nawet w przypadku zamkniętych faktur; po prostu nie można przeliczyć starej faktury za pomocą aktualnych cen.
    • niektórzy używają tabeli archive_invoice, ale to ma problemy, ponieważ teraz każdy segment kodu lub narzędzie do raportowania użytkownika musi szukać w dwóch miejscach (zauważ, że w dzisiejszych czasach niektórzy użytkownicy rozumieją bazy danych lepiej niż większość deweloperzy)
    • w każdym razie, to jest cała dyskusja, dla twojego zrozumienia.
      • baza danych służy celom bieżącym i archiwalnym z jednego zestawu tabel (bez tabel" archiwalnych "
      • Po utworzeniu faktury jest ona dokumentem prawnym i nie może być zmieniona ani usunięta (może być cofnięta lub częściowo zaksięgowana przez nową fakturę, z wartościami ujemnymi). Są one oznaczone IsIssued/IsPaid/Etc
      • Products nie mogą być usunięte, mogą być oznaczone IsObsolete
      • istnieją oddzielne tabele dla InvoiceHeader i InvoiceItem
      • InvoiceItem ma FKs zarówno InvoiceHeader jak i Product
      • z wielu powodów (nie tylko tych, które wymieniasz) wiersz InvoiceItem zawiera NumUnits; ProductPrice; TaxAmount; ExtendedPrice. Oczywiście, wygląda to na "denormalizację", ale tak nie jest, ponieważ ceny, stawki podatkowe itp.mogą ulec zmianie. Ale co ważniejsze, wymogiem prawnym jest to, że możemy odtworzyć starą fakturę na żądanie.
      • [16]} (jeśli można go odtworzyć z plików papierowych, nie jest to wymagane)
    • the InvoiceTotalAmount jest pochodną kolumny, tylko SUM() z faktury
  2. To bzdura. Systemy księgowe, a księgowi nie "pracują" w ten sposób.
    • Jeśli jest to prawdziwy system księgowy, to będzie miał Dziennikarstwo, czyli "podwójny wpis"; to jest to, co kwalifikowane konto jest wymagane (przez prawo).

    • Podwójny wpis nie oznacza podwójnego wpisu; oznacza to, że każda transakcja finansowa (jedna kwota) ma rachunek źródłowy i rachunek docelowy, do którego jest stosowany; nie ma więc "denormalizacji" ani powielania. W bankowej bazie danych, ponieważ transakcje finansowe są na pojedynczych rachunkach, co jest zwykle renderowane jako dwie oddzielne transakcje finansowe (wiersze) w ramach jednej transakcji Db. Zwykłe komercyjne ograniczenia baz danych są używane, aby zapewnić, że każda transakcja finansowa ma dwie "strony".

    • Upewnienie się, że faktury nie są usuwalne jest odrębnym problem, związane z bezpieczeństwem itp. jeśli ktoś ma paranoję na punkcie rzeczy usuwanych z ich bazy danych, i ich baza danych nie została zabezpieczona przez wykwalifikowaną osobę, to ma więcej i różne problemy, które nie mają nic wspólnego z tym pytaniem. Uzyskaj audyt bezpieczeństwa i rób, co ci każą.

    • Wikipedia nie jest wiarygodnym źródłem informacji o normalizacji.

    • Znormalizowana baza danych jest zawsze znacznie szybsza niż Niezanormalizowana baza danych. Bardzo ważne jest więc zrozumienie, czym jest normalizacja i Denormalizacja, a czym nie. proces ten jest bardzo utrudniony, gdy ludzie mają płynne i amatorskie "definicje", prowadzi to po prostu do zamieszania i marnowania czasu na"dyskusje". Kiedy masz ustalone definicje, możesz tego wszystkiego uniknąć i po prostu wziąć się do pracy.

    • Tabele podsumowujące są całkiem normalne, aby zaoszczędzić czas i moc obliczeniową przeliczania informacji, które nie ulegają zmianie, np. za każdy rok, ale w tym roku; suma MTD za każdy miesiąc w tym roku, ale nie w tym miesiącu. "Zawsze przeliczanie" danych jest trochę głupie, gdy (a) informacje są bardzo duże i (b) nie zmienia. Oblicz tylko dla bieżącego miesiąca

      • w systemach bankowych (miliony transakcji dziennie), na koniec dnia, obliczamy i przechowujemy dzienną sumę. Są one nadpisywane przez ostatnie pięć dni, ponieważ Audytorzy wprowadzają zmiany, a dziennikarze przeciwko transakcjom finansowym za ostatnie 5 dni są dozwolone.
      • systemy pozabankowe na ogół nie potrzebują dziennych Sum
    • Tabele podsumowujące nie są " denormalizacją "(z wyjątkiem tych, którzy dopiero co dowiedzieli się o" normalizacji "ze swojego magicznego, ciągle zmieniającego się płynnego" źródła"; lub jako nie-praktycy, którzy stosują proste zasady czarno-białe do wszystkiego). Ponownie, definicja nie jest tu argumentowana; po prostu nie stosuje się do podsumowania stoły.

    • Tabele zbiorcze nie wpływają na integralność danych (zakładając oczywiście, że dane, z których zostały pozyskane, były całkowe).

    • Tabele zbiorcze są dodatkiem do bazy danych, które nie muszą mieć takich samych ograniczeń jak baza danych. Istnieją zasadniczo tabele raportowania lub tabele hurtowni danych, w przeciwieństwie do tabel baz danych.

    • Nie ma anomalii aktualizacyjnych (co jest ścisłą definicją) związanych z Tabele zbiorcze. Nie można zmienić ani usunąć faktury z ubiegłego roku. Anomalie aktualizacyjne dotyczą prawdziwych Denormalizowanych lub Nienormalizowanych danych bieżących.

 48
Author: PerformanceDBA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-21 12:08:14

1) to jest archiwum. Wszystko, co w nim jest, nigdy nie powinno być aktualizowane. Poszedłbym za sugestią starszego faceta i niech ta tabela faktur będzie niezależna. Może użyć Bloba dla samej faktury, która zawiera język znaczników?

2) usługi raportowania, tabela magazynowa, która jest aktualizowana, coś, co tworzysz skryptem kiedykolwiek... wszystko byłoby w porządku. Jest to rzeczywiście idealne do normalizacji, ale nie zawsze jest to szybkie. Mam dobrą bazę danych opieki zdrowotnej I zarządzanie, które jest w pełni znormalizowane... a następnie ma szereg de-znormalizowanych tabel z zwijanymi równaniami i powszechnie ciągniętymi polami. Prawie wszystko działa z tego od-znormalizowanego zestawu - po prostu szybciej jest dołączać do nich za pomocą wyzwalacza, gdy pliki są ładowane, niż ciągnąć z różnych tabel za każdym razem, gdy chcę spojrzeć na raport rekordu 100,000.

 11
Author: Jeff Ferland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-29 05:39:37

Podnosisz ważne punkty, jednak nie jesteś do końca jasny co do normalizacji i co to znaczy, np. w

1) twierdzenie, że przechowywanie faktur w stanie, w jakim były, denormalizuje dane, jest całkowicie błędne. Weźmy na przykład cenę - jeśli masz wymóg biznesowy, który stwierdza, że musisz zachować historię cen, a następnie utrzymywanie tylko bieżącej Ceny jest złe i łamie wymagania. I nie ma to nic wspólnego z normalizacją, po prostu nie jest zaprojektowany cóż. Denormalizacja polega na wprowadzeniu możliwości dwuznaczności do modelu (i innych artefaktów) - i w tym przypadku po prostu nie modelujesz poprawnie swojej przestrzeni problemowej.
Nie ma nic złego w modelowaniu bazy danych w celu obsługi danych temporalnych(lub wersjonowania i / lub oddzielania obszarów bazy danych na archive / temporal i zestaw roboczy).

Patrzenie na normalizację bez patrzenia na semantykę (w kategoriach wymagań) nie jest możliwe.

Również, jeśli twój starszy programista nie widzi różnicy, więc chyba nie dostał stażu w rozwoju RDBMS;)

[[2]}2) druga część to rzeczywiście denormalizacja. Jeśli jednak kiedykolwiek natkniesz się na starszego analityka DB, który poważnie głosi normalizację, usłyszysz, że jest całkowicie dopuszczalne denormalizowanie, o ile zrobisz to świadomie i upewnij się, że korzyści z nadwagi braki i anomalie nie ugryzą cię. Będą również powiedzieć, aby normalizować logiczne model i że w modelu fizycznym można odbiegać od ideału do różnych celów(wydajność, konserwacja itp...). W mojej książce głównym celem normalizacji jest to, aby nie mieć ukrytych anomalii (patrz ten artykuł na 5NF na przykład)

Buforowanie wyników pośrednich jest dozwolone nawet w znormalizowanych bazach danych, a nawet przez największych ewangelistów normalizacji - można to zrobić w warstwie aplikacji (jako jakiś cache) lub można to zrobić w poziom bazy danych lub możesz mieć hurtownię danych do takich celów. Wszystkie te wybory są słuszne i nie mają nic wspólnego z normalizacją modelu logicznego.

Również, jeśli chodzi o Twojego księgowego-powinieneś być w stanie przekonać go, że to, co twierdzi, jest , a nie dobrym testem i opracować zestaw testów (może razem z nim), które zautomatyzują testowanie systemu bez interwencji użytkowników i dadzą ci większą pewność, że Twój system jest wolny od błędów.

Na drugiej ręka wiem o systemach, które wymagają od użytkowników wprowadzania zduplikowanych informacji, takich jak wprowadzenie liczby linii na fakturze przed lub po wprowadzeniu faktycznych linii, aby upewnić się, że wpis jest kompletny. Dane te są "zduplikowane" i nie musisz ich przechowywać, jeśli masz procedurę, która poprawi dane wejściowe. Jeśli ta procedura nadejdzie później, dozwolone jest przechowywanie "denormalizowanych" danych-ponownie, semantyka uzasadnia to i można spojrzeć na model jako znormalizowany. (korzystne jest zawijanie twoja głowa wokół tej koncepcji)

EDIT: Termin "denormalized" w (2) nie jest poprawny, jeśli przyjrzymy się formalnej definicji form normalnych i jeśli weźmiemy pod uwagę projekt denormalizowany, jeśli łamie on którąkolwiek z form normalnych (dla niektórych jest to oczywiste i nie ma innego sposobu na to).

Mimo to, może warto przyzwyczaić się do idei, że wiele osób i niepotrzebnych bezużytecznych tekstów będzie używać terminu normalizacja dla każdego wysiłku, który stara się zmniejszyć redundancję w baza danych (jako przykład, znajdziesz artykuły naukowe, przez które nie mówię, że muszą mieć rację, tylko jako ostrzeżenie, że jest powszechne, że pochodne atrybuty nazywają formą denormalizacji, patrz tutaj ).

Jeśli chcesz odnieść się do bardziej spójnych i uznanych autorytetów (znowu, nie uznawanych przez wszystkich), może słowa C. J. Date mogą wyraźnie odróżnić:

Duża część teorii projektowania ma związek z zmniejszenie nadmiarowości; normalizacja zmniejsza redundancję w relvarach, ortogonalność zmniejsza ją w poprzek relvars.

Q z baza danych w głębi: teoria relacyjna dla praktyków

I na następnej stronie

Tak jak brak normalizacji wszystkich sposób zakłada redundancję i może prowadzić do pewne anomalie, więc też może nieprzestrzeganie ortogonalności.

Więc właściwym terminem dla redundancji w relvarach jest ortogonalność (w zasadzie wszystkie normalne formy mówią jeśli chodzi o pojedynczy relvar, więc jeśli przyjrzymy się normalizacji, nigdy nie sugerowałoby to żadnych ulepszeń z powodu zależności między dwoma różnymi relvarami).

W każdym razie, jednym z innych ważnych pojęć, jeśli weźmiemy pod uwagę projektowanie baz danych, jest również różnica między logicznymi i fizycznymi modelami baz danych. Wiele rzeczy, które są przydatne na poziomie fizycznym, takich jak tabele z podlicznikami lub indeksami, nie ma miejsca w modelu logicznym - gdzie próbujesz nawiązać i zbadać relacje pomiędzy koncepcjami, które próbujesz modelować. I dlatego można powiedzieć, że są dopuszczalne i nie psują projektu.

Linie czasami mogą być nieco rozmyte na tym, co jest modelem logicznym, a co modelem fizycznym. Szczególnie dobrym przykładem jest tabela z podlicznikami. Aby uznać to za część fizycznej implementacji i zignorować na poziomie logicznym, musisz:

  • upewnij się, że użytkownicy (i aplikacje) nie mogą aktualizować tabeli subtotal bezpośrednio w sposób, który nie jest zgodnie z ich predykatem (innymi słowy mają błąd w procedurze subtotalling)
  • upewnij się, że użytkownicy (i aplikacje) nie mogą zaktualizować tabeli, od której są one zależne bez aktualizacji subtotal (innymi słowy, że niektóre aplikacje nie usunie wiersza z tabeli szczegółów bez aktualizacji całości)

Jeśli złamiesz którąkolwiek z powyższych zasad, otrzymasz niespójną bazę danych, która dostarczy niespójnych faktów. (W takim przypadku, jeśli chcesz formalnie zaprojektować procedurę naprawienia lub zbadania spowodowanych problemów, nie uznałbyś jej za dodatkową tabelę, istniałaby ona na poziomie logicznym; gdzie nie powinna być).

Ponadto normalizacja zawsze zależy od semantyki i reguł biznesowych, które próbujesz modelować. Na przykład DBAPerformance podaje przykład, w którym przechowywanie TaxAmount w tabeli transakcji nie jest projektem denormalizowanym, ale nie wspomina, że zależy jaki system próbujesz modelować (czy to oczywiste?); na przykład,jeśli transakcja ma inny atrybut o nazwie TaxRate, zwykle będzie denormalizowana, ponieważ istnieje funkcjonalna zależność od zestawu atrybutów innych niż kluczowe (TaxAmount = Amount * TaxRate => FD: Amount, TaxRate- > TaxAmount), a jeden z nich powinien zostać usunięty lub gwarantowany jako spójny.

Oczywiście, można powiedzieć, ale jeśli system, który budujesz, jest dla firmy audytorskiej, to możesz nie mieć zależność funkcjonalna - może to być audyt kogoś, kto korzysta z obliczeń ręcznych lub ma wadliwe oprogramowanie lub musi mieć zdolność do rejestrowania niekompletnych danych i obliczenia mogą być błędne pierwotnie i jako firma audytorska musisz zarejestrować fakt, jak to się stało.

Tak więc semantyka (predykaty), które są określone przez wymagania, będzie miała wpływ, jeśli którakolwiek z form normalnych zostanie złamana-wpływając na zależności funkcyjne (innymi słowy prawidłowo ustalając funkcjonalne zależności jest dość ważną częścią modelowania, gdy dążysz do znormalizowanej bazy danych).

 8
Author: Unreason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 18:15:09

Zgadzam się z Twoim maturzystą co do (1). Wiersz tabeli transakcji musi przechwytywać cały stan w momencie transakcji. Kropka. To, co sugerujesz, nie rejestruje prawdziwych danych, więc jest niedopuszczalne. Zgadzam się również z (2). Cokolwiek biznes chce poprzez crosschecking, musisz wdrożyć. Księgowość opiera się na sprawdzaniu krzyżowym, podwójnym wpisie, zwijaniu ksiąg itp. Musisz to zrobić. To tak fundamentalne, że nie należy nawet patrzeć na to jak na denormalizację, tak jak realizacja wymagań biznesowych.

 5
Author: user207421,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-29 05:48:04

1) nie wymaga denormalizacji. Musisz tylko określić, jaki poziom szczegółowości każdej zmiany potrzebujesz i utrzymać to za pomocą odpowiedniego klucza.

2) nie ma nic wspólnego z denormalizacją. Przechowywanie danych podsumowujących nie powoduje denormalizacji bazy danych. Przechowywanie wyników uzyskanych z atrybutów innych niż kluczowe w tej samej tabeli byłoby przykładem denormalizacji, ale nie wydaje się, że o tym tutaj mówisz.

 5
Author: nvogel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-29 10:32:33

Twój starszy programista daje bardzo ważne punkty. Nauczyłem się tego na własnej skórze, serwisując systemy, które nie de-normalizują danych historycznych.

W pewnym sensie nie jest to dodawanie żadnych kosztów do bazy danych. Tworzysz tabele faktur na podstawie istniejących danych w bazie danych. Faktura jest migawką w czasie. Normalizacja informacji potrzebnych do wystawienia faktury może znacznie ułatwić raportowanie. Kiedy wymagane jest sporządzenie nowego raportu i oczekuje się, że zrobisz to szybko, docenisz de-normalizację.

Pod względem posiadania sumy w bazie danych. To uratowało mi tyłek wcześniej, gdy dokonałem zmiany w aplikacji, która spowodowała, że liczby nie sumują się w ten sam sposób (nie tak trudne, jak może się wydawać). W aplikacji na żywo sumy dały mi określone miejsce do powrotu w celu skorygowania rozbieżności. Pisałem już o tym, możecie przeczytać tutaj: http://jlrand.com/?p=95

 5
Author: Jonathan Rand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-01 18:13:14

Dla #1

Faktura powinna być obliczona na podstawie sprzedaży i płatności. Jeśli nie masz szczegółowych danych dotyczących sprzedaży, w tym ceny/produktu/rabatu/wysyłki/itp.

Dla #2

Zapisanie systemu księgowego do db od podstaw to duży projekt. Upewnij się, że księgowi dają ci zasady biznesowe, dzięki czemu możesz mierzyć dokładność systemów. Ostatnia rzecz, jakiej chcesz, to krok CFO do spotkania DBA i ogłoszenie DB jest nadmierne obciążenie klient, co gorsza jesteś niedoszacowany i wypędzasz firmę z biznesu.

Jeśli masz SQL Server daj Adventure Works db wygląd. Jeśli nienawidzisz MS to spójrz na Adventure Works i nie rób tego w ten sposób.

 1
Author: RC_Cleland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 00:02:33

Normalizacja bazy danych usuwa duplikaty i sprawia, że zapytania sql do aktualizacji danych są bardziej wydajne (i daje kilka innych ulepszeń).

Ale jeśli większość zapytań jest używana do wyboru danych i zapytania select łączą się z kilkoma tabelami w tym czasie, można rozważyć denormalizację tych tabel. Zwiększy to ilość miejsca na dysku potrzebnego na dane, czas wykonywania zapytań SQL update, ale poprawi zapytania select.

 0
Author: Alexandr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-29 05:52:12

Wydaje się, że jeśli rozważasz raczej czy nie powinieneś utworzyć hurtownię danych. Nigdy nie należy denormalizować bazy danych do celów sprawozdawczości historycznej. Utworzenie archiwum i przechowywanie informacji w hurtowni danych spowoduje zarówno denormalizację większości informacji, jak i utrzymanie historii danych.

 0
Author: Lesly Revenge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-05 23:48:00