MYSQL datetime külön oszlopban

MYSQL datetime külön oszlopban
2019-06-17T10:17:50+02:00
2019-06-19T08:17:20+02:00
2022-10-15T21:35:28+02:00
smile_221
Sziasztok!

Bele ütköztem egy egyszerűnek tűnő problémába, de nem tudom megoldani.

Külön tárolom adatbázisban a dátumot (Y-m-d formátumban) és külön tárolom az időt is (H:i:s formátumban). legyen date és time a mezők neve. A beállításuk date illetve time típusú.

Nem tudok  olyan feltételt létrehozni amiben egyszerre a dátum és az idő is megfelelő lekérdezést adna.

Adatbázisban mondjuk ez a két érték szerepel:
date = 2015-08-13
time = 09:14:12

date >= '2015-08-12' AND time >= '11:02:14' 

A keresési feltétel nem teljesül, mert az időt ugye külön kezelem és nem tudok erre semmilyen megoldást, hogy úgy működjön, mintha ez egy datetime mező lenne.

PHP-ban próbáltam CONCAT al megoldani, de nem jött össze. Tudtok valami tippet adni merre induljak el?
Mutasd a teljes hozzászólást!
Szia!
Pedig a concat megoldás lenne, de utána cast-olni kell datetime típusra, mert a concat stringet ad.
Vagyis:

cast(concat(date, ' ', time) as datetime)
Mutasd a teljes hozzászólást!

  • Külön tárolom adatbázisban a dátumot (Y-m-d formátumban) és külön tárolom az időt is (H:i:s formátumban).

    Szerintem itt van az első hiba. Mi értelme külön tárolni őket, ha külön nincs értelmük? Ebből származik a problémád is, hiszen nem külön a dátumra vagy külön az időre próbálsz feltételt szabni, hanem a kombinációjukra.

    Ha már így alakult, a lekérdezésben összekombinálhatod a két mezőt, és onnan már feltételt is írhatsz rá könnyen. A StackOverflow illetve a MySql doksi alapján valami ilyesmi kell neked:

    WHERE ADDTIME(date, time) >= '2015-08-12 11:02:14'
    De ettől függetlenül ha van rá lehetőséged, én javasolnám a séma átírását, hogy csak egy meződ legyen. Ha egyben van a két mező, akkor rakhatsz rá indexet, és hatékonyabbá válik egy-egy időtartomány lekérdezése.
    Mutasd a teljes hozzászólást!
  • Tákolás jellegű, de a jelenlegi feltételedet zárójelezheted, és hozzácsaphatsz egy OR date > '2015-08-12' részt.

    Amúgy Csaboka2 mindent megírt... szerintem is vond össze 2 mezőt 1 DATETIME-ba és kész!
    Mutasd a teljes hozzászólást!
  • Addig is, amig elkészül az újratervezés:

    ((date = '2015-08-12' AND time >= '11:02:14') OR (date > '2015-08-12'))
    Mutasd a teljes hozzászólást!
  • Szia!
    Pedig a concat megoldás lenne, de utána cast-olni kell datetime típusra, mert a concat stringet ad.
    Vagyis:

    cast(concat(date, ' ', time) as datetime)
    Mutasd a teljes hozzászólást!
  • Hello!

    Azért van külön mezőben, mert néha kísérletezik az ember és mérne olyan teljesítményeket amiket mások még nem mértek le. Kíváncsi vagyok, hogy a hagyományos tárolási módszerekkel szemben, speciális keresési megoldások mennyi időt vesznek igénybe és mennyi egyéb macerával járnak.

    Például ha van mondjuk 100.000 rekord akkor nem mindegy, hogy éppen csak dátumra akarok keresni és egyébként az idő nem is kellene. Kevesebb memóriahasználat, gyorsabb elérés. Míg lehet hogy így valamivel több kapacitás megy el ha idővel is kell lekérdeznem, de ha sokkal kevesebb lekérdezés van amihez idő is kell, akkor lehetséges, hogy megéri egy ilyen tárolási módszer.

    Azért fordultam ide mert gondoltam, hogy vannak hasonló tagok akik már ütköztek hasonló problémába. Szóval nyilván nem szeretném egy mezőbe rakni az adatokat.
    Mutasd a teljes hozzászólást!
  • Jó a CAST, noha próbáltam korábban, de valahogy be került egy felesleges aposztróf pár a tesztelések alatt. Gondolom már fáradt voltam. Köszönöm a rávezetést, jó irányban tapogatóztam csak figyelmetlen voltam. Köszönöm!
    Mutasd a teljes hozzászólást!
  • Például ha van mondjuk 100.000 rekord akkor nem mindegy, hogy éppen csak dátumra akarok keresni és egyébként az idő nem is kellene. Kevesebb memóriahasználat, gyorsabb elérés.

    Ezeket lemérted, vagy csak gondolod? Az ilyen "fejbeli optimalizáció" sokszor félre tud vinni, ha a fejben meglévő modelled nem egyezik a valódi működéssel.

    Például ha nem is vagy kíváncsi az időre egy adott sorból, a diszkről valószínűleg úgy is felolvassa az adatbáziskezelő, mivel hogy diszkről ugye egy-egy szektort lehet egyszerre felolvasni, az egy rekordhoz tartozó értékek pedig egymás mellett lesznek a diszken. Nem tud olyat mondani a háttértárnak, hogy a 28. bájttól a 34. bájtig levő részt inkább ne olvassa be.

    Más részről, ahogy említettem az előző hozzászólásomban, egy kombinált datetime mezőre hatékonyabb indexet tudsz felhúzni. Onnantól konkrét időpontot is tudsz hatékonyan keresni. Ha meg csak a dátum érdekel, az egy tartomány lekérdezése lesz (aznap éjféltől következő nap éjfélig), amit az index megint csak hatékonyan le tud kezelni.

    (Egyébként a javaslatomat kipróbáltad? A szabály az, hogy az első helyes megoldást kell elfogadni, nem pedig a neked leginkább szimpatikusat.)
    Mutasd a teljes hozzászólást!
  • Te nem azt válaszoltad meg ami a probléma volt. Mint írtam, nem akartam egy mezőbe rakni. Sőt azt is írtam, idézem "külön mezőben, mert néha kísérletezik az ember és mérne olyan teljesítményeket amiket mások még nem mértek le". Vagyis jelenleg mérem le a különböző keresési eredményeket.

    Vagyis nem a legszimpatikusabbra adtam választ, hanem a helyes megközelítésre. Ugyanis, ha a post címe az lett volna, hogyan tároljam a dátumot és az időt, akkor nyilván Te kaptad volna a helyes megfejtésért járó "kitüntetést" :)
    Mutasd a teljes hozzászólást!
  • Te nem azt válaszoltad meg ami a probléma volt.

    Na, akkor olvasd el még egyszer azt a hozzászólást!
    Mutasd a teljes hozzászólást!
  • Megnéztem, kipróbáltam elolvastam mit írtak. Számomra nem volt megfelelő. Nem kaptam vissza eredményt az SQL lekérdezésben. Lehet hogy valamit rosszul csináltam, nem tudom.

    A CONCAT megoldást korábban próbáltam és kellett hozzá a CAT ergo nekem az a way volt szimpatikus. Ráadásul mint írtam, eredetileg is jó úton haladtam, csak véletlen bent maradtak aposztrófok ahol nem kellett volna. Mert már valószínű fáradt voltam és erőltettem.

    Nem értem miért megy a terefere egy olyan dologról, ami a számomra a leg optimálisabb kimenetel. Számomra az Ő válasza volt a megfelelő. De ha pesti vagy szívesen meghívlak egy sörre mivel nem lehet 2 embernek adni helyes választ. Ha erre az opcióra igényt tartasz, akkor küldj egy PM-et.

    Az Ő válasza relevánsabb volt a számomra.
    Mutasd a teljes hozzászólást!
  • OK, relax!
    Azt nem említetted korábban, hogy az ADDTIME-os példa nem volt jó, csak azt, hogy nem akarod összevonni a mezőidet!
    Mutasd a teljes hozzászólást!
  • Relaxálok, nincsen gond, nem megy át írásban a nyugalmam. Azért is mondtam, hogy szívesen meghívlak egy sörre.

    Igen nem említettem, elsiklottam efölött.

    Egyébként visszatérve a teljesítményre. Mikor a lekérdezést végrehajtod és mondjuk olyan listát készítesz amiben van 100K rekord válasz, akkor nem mindegy, hogy mennyivel rövidebbek a stringek.

    De ha már szóba elegyedtünk:
    Vagyis a meglátásom szerint, ha az esetek 70%-ban nem kell az időre szűrni sőt még csak nem is kell az az adat, akkor nincsen fölösleges adat a lekérdezésben, amit meg egyébként utólag el kellene távolítani. 100K rekordon végrehajtani a változtatást nem egy borzalmas idő, csak ha mondjuk sokszor kell valamire ez, akkor már nem annyira funny. Így viszont szűrhetsz is rá akár, és nem feltétlen kell vissza adnod lenkérdezésnél ha nincsen szükség rá. A lekérdezési időt meg annyival nem növeli meg mint amennyivel az utófeldolgozás növelné meg, ha nincsen szükséged a dátum vagy az idő paraméterre. És ugye 3 byte-on tárolódik a dátum is meg az idő is, ha az egyik paramétert nem adod vissza a lekérdezésben, akkor az majdnem 1 mega memória megtakarítás.

    Mi a meglátásod erről?
    Mutasd a teljes hozzászólást!
  • Azért is mondtam, hogy szívesen meghívlak egy sörre

    Mármint Csaboka2-t, mert ugye az ő javaslatáról van szó .

    ha az esetek 70%-ban nem kell az időre szűrni...

    Nem értem, akkor ne szűrj idő szerint, csak dátumra...

    sőt még csak nem is kell az az adat, akkor nincsen fölösleges adat a lekérdezésben, amit meg egyébként utólag el kellene távolítani...

    Mysql: DATE_FORMAT(datetime_mezo_neve,'%Y-%m-%d') a selectben... kész (de van pl. EXTRACT is, amivel bármelyik "komponensét" kiszedheted akár egyenként is)

    A lekérdezési időt meg annyival nem növeli meg mint amennyivel az utófeldolgozás növelné meg

    Ugye lekérdezés utáni utófeldolgozásról már nincs szó (az előző pont alapján). A lekérdezés idejével kapcsolatban meg nem tudom mit mondjak... mérted, összehasonlítottad egyáltalán?

    Én most teszteltem egy gyorsat:
    Kicsit több mint 1millió rekordból kiválogattam (2 dátum között) egy DATETIME mező alapján kb. 367ezret úgy, hogy mellé a korábban említett DATE_FORMAT-tal egyszerre lekértem csak a dátum részét is, (simán phpmyadminban):

    Sorok megjelenítése 0-499 (összesen 367294, a lekérdezés 0.0000 másodpercig tartott)
    Annyi, hogy a datetime mezőn index van, enélkül minden bizonnyal valamivel lassabb lenne.
    Mutasd a teljes hozzászólást!
  • Hali,

    Ha a hatékonyság a fontos, esetleg mutatnál egy lekérdezési tervet az elfogadott megoldáshoz? Erős kételyeim vannak, hogy a concat után az adatábázis kezelő az indexet hatékonyan kihasználná, ha db-ben szűröd az adatokat. Ha valami miatt mégsem így lenne, akkor meg tanultam újat ma is.

    Én azt gondolom, hogy NevemTeve által írt irány az, ami tud hatékonyan indexet használni a lekérdezésen ennél a két oszlopos megoldásnál.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd