Autor Zpráva
petrodvedle
Profil *
Dobrý den,
vím že už zde podobné dotazy byli ale nikdy konkrétní.

Budu ukládat do jedné tabulky (cca 15 sloupců) různé údaje včetně stringů, některé i docela dlouhé (1000 znaků) takže jeden řádek výjde na 3-5kB
Pokud by tato tabulka měla např. 2000 záznamů pak její velikost bude takřka 10MB, není to moc? Nebo jí mám nějak rozdělit?
Joker
Profil
petrodvedle:
její velikost bude takřka 10MB, není to moc?
Tabulka má mít tolik, kolik je nutné.
Co do absolutního čísla to moc není, viděl jsem i řádově větší tabulky.
petrodvedle
Profil *
Měl bych ještě další dotaz,
dělám ještě další tabulku, kde bude vlastně takový "kalendář" čili 365 sloupců, není to nešikovné? Drtivá většina sloupců bude typu boolean takže to nebude zabírat moc velkou kapacitu. Řádků (záznamů) pak bude max. 5 000
co se týče kapacity tak to na moc nevychází. Potřebuji zkrátka udělat jen to, jestli se v daný den něco uskuteční nebo nikoliv.

Další řešení mě např. napadlo že bych do jednoho sloupce umístil např. celý měsíc v zápisu 10101010...... a pak načetl jen určitý člen z celého řetězce.
Joker
Profil
petrodvedle:
dělám ještě další tabulku, kde bude vlastně takový "kalendář" čili 365 sloupců, není to nešikovné?
Ano, je. Ne kvůli obsazenému místu, ale kvůli neuvěřitelné složitosti některých dotazů. Mimochodem, těch sloupců by mělo být 366.¨

Řekněme tedy, že tabulka má 366 sloupců typu bool, každý určuje "true" nebo "false" pro jeden den roku.
Zkuste si udělat třeba následující dotazy:
- Vybrat všechny záznamy týkající se července.
- Vybrat záznamy, u kterých není "true" žádný den v roce.
- Vybrat záznamy, které mají "true" u více než dvou dní v roce.
- Seřadit záznamy sestupně podle počtu "nastavených" dní.
- Kterého měsíce se týká nejvíc záznamů?

Další řešení mě např. napadlo že bych do jednoho sloupce umístil např. celý měsíc v zápisu 10101010
To je stejně špatné řešení.

Správné řešení je:
- Pokud se k záznamu může vztahovat jen jeden den, udělat sloupec typu datum
- Pokud se k jednomu záznamu může vztahovat více dní, udělat si další tabulku: id záznamu | datum
petrodvedle
Profil *
Joker:
Správné řešení je:
- Pokud se k záznamu může vztahovat jen jeden den, udělat sloupec typu datum
- Pokud se k jednomu záznamu může vztahovat více dní, udělat si další tabulku: id záznamu | datum

Asi jsem to špatně vysvětlil.

Jsou pouze dvě hodnoty (0,1) a potřebuji databázi na jednotlivé dny jestli je tam 0 nebo 1.

-----------------------------------
město -1.1.-2.1.-3.1.-4.1.- atd....
-----------------------------------
praha - 0 - 1 - 1 - 1
bratislava - 1 - 0 - 0 - 1

doufám, že je zřejmé o co mi jde
Joker
Profil
petrodvedle:
Jsou pouze dvě hodnoty (0,1) a potřebuji databázi na jednotlivé dny jestli je tam 0 nebo 1.
Fajn, tak:
Praha | 2.1.
Praha | 3.1.
Praha | 4.1.
Bratislava | 1.1.
Bratislava | 4.1.

...samozřejmě kdyby tam kromě města a data byly ještě jiné informace, tak by tohle byla zvláštní tabulka, která by obsahovala je ID záznamu a datum.
spartan13
Profil
Joker:
Dělám (dělal jsem) velice podobnou věc, akorát se týče obsazení ubytování-kdy je chata volná.
A řešil jsem to také stylem, že jsem udělal tabulku na jeden měsíc a 30 sloupců a boolean-tinyint pak mám ještě v prvním ID ubytování a v druhém popis ubytování.

Příjde mi, že kdybych to předělával jak píšete tak tabulka bude mít "zbytečně" větší objem ale zase bude univerzálnější a vlastně by mi stačila jen jedna a mohl bych pak třeba starší záznamy vymazávat, co vy na to?

Na druhou stranu bych pak musel udělat skript, který by např. každý den dělal tuto práci a mazal by zbytečná data.
Ale i tak mi příjde Vaše řešení pro moji DB složitější k programování. Musel bych pak asi udělat tabulku:

ID- Datum1 - Datum2 - Datum3 - Datum4 ....
1-
2-
3-
4-

a další tabulku, kde bych k ID přiřazoval popisky. Nebo dle Vašeho návrhu pro petra jste myslel udělat tabulku

ID Datum
1 3.2
2 3.2
3 6.4.
1 4.2.
2 atd..

----------------------
teď jsem to měl udělané takto:

ID(int)-popisek(text)- 1.3(bool). - 2.3(bool). - ................
přičemž jsem měl podle měsíce sloupců 30 až 33 a když už byli údaje neaktuální (celý měsíc) tak jsem ji prostě smazal ručně.
Joker
Profil
spartan13:
Musel bych pak asi udělat tabulku
Nevím, jestli to chápete správně.
Dám příklad:
Mám záznam s popiskem třeba "jednička" a třeba nějakými dalšími údaji a ten je "obsazený" třeba 1.2. a 2.2. Pak by to vypadalo:
tabulka se záznamy:
ID | Popis     | (další sloupce)
1  | Jednička  | ...

tabulka obsazenosti:
IDzáznamu | Datum
1         | 1.2.
1         | 2.2.

Příjde mi, že kdybych to předělával jak píšete tak tabulka bude mít "zbytečně" větší objem
Nebude to zbytečně. Tabulka typu:
id | název      | obsazenost_leden
1  | "Jednička" | "1110000000000000000000000000000"

anebo:
id | název      | 1.1. | 2.1. | 3.1. | 4.1. | 5.1. | ...
1  | "Jednička" | 1    | 1    | 1    | 0    | 0    | ...

budou dobře fungovat s některými typy dotazů, zatímco na jiných si dost vylámete zuby. Když dám příklad, navrhněte, jak byste dělal následující:
1. Návštěvník zadá interval od-do a dostane seznam chat, které jsou v tom termínu volné (= nemají žádný den v tom intervalu rezervovaný)
2. Chtěl bych vědět, jak jsme na tom s kapacitou, zjistěte mi obsazenost chat (= 100 * počet obsazených dní / počet dní celkem) za poslední dva měsíce?
3. Poptávka po ubytování bude dost kolísat... udělejte mi seznam dní seřazených podle toho, kolik jsme v ty dny měli volných míst.

Dodatková otázka: Fajn, uděláte tedy v té tabulce X sloupců... to vystačí na X dní, třeba na rok. A co po tom roce? Všechno smažete a jedete zase odznova? V tom případě zrovna u toho ubytování (IMHO) přicházíte o dost cenná data- zrovna mít přehled o tom jaká byla obsazenost za minulý rok, kdy bývá pravidelně hodně plno a kdy naopak bývá málo lidí se podle mě může dost hodit.
spartan13
Profil
Joker:
1) načetl bych id=x a pak ověřil, jestli v daných sloupcích jsou jen 0.
2)100/60*x; kde do x bych musel projít sloupec od nějakého sloupce k nějakému jinému sloupci a přidat do x jedničku v případě, že =1.

příjde mi naopak, že řešení s datumy by bylo první 2 úkoly vyřešit větší problém.

Fajn, uděláte tedy v té tabulce X sloupců... to vystačí na X dní, třeba na rok. A co po tom roce?
Máte pravdu, ačkoliv ty tabulky by mohli mít více sloupců.. ale pokud budu data pořád ukládat dál a dál tak to bude náročné na databáze.
spartan13
Profil
spartan13:
Mám např. tabulku kde je mnoho sloupců(50) které by šli rozložit. Např. pro přihlášení by stačilo jen heslo a pak id chaty a nepotřebují tam být další údaje jako je e-mail, ... mám tedy spíše tabulku rozložit podle toho, kdy potřebuji informace použít? (pokud současně, aby byli v jedné tabulce)
Alphard
Profil
spartan13:
Před chvílí jsem v jiném vlákně odkazoval Teorii relačních databází: Normalizace. Není to dogma, občas se záměrně provádí denormalizace, ale často je to nejlepší možný návrh.
spartan13
Profil
Alphard:
Děkuji, to vypadá že bude to co jsem potřeboval, navíc v češtině!
Joker
Profil
spartan13:
načetl bych id=x a pak ověřil, jestli v daných sloupcích jsou jen 0.
Jak id=x? Máte najít všechny chaty, které jsou ve všechny předané dny volné.
V první řadě budete mít problém už s tím ze kterých sloupců vlastně vybírat- musíte nějak konvertovat interval zadaný uživatelem na seznam sloupců v databázi.
Ve druhé řadě budete muset dát dohromady tu where podmínku - "sloupec1=0 and sloupec2=0 and sloupec3=0 and..."

100/60*x; kde do x bych musel projít sloupec od nějakého sloupce k nějakému jinému sloupci a přidat do x jedničku v případě, že =1.
Jednak dva měsíce nemají vždycky 60 dní a jednak, jak na tohle chcete sestavit SQL dotaz?
Nebo chcete udělat: SELECT * FROM tabulka, pak si to celé načíst do PHP a tam už to z těch dat nějak vydolovat?

příjde mi naopak, že řešení s datumy by bylo první 2 úkoly vyřešit větší problém.
Začnu 2. - tak buď si můžu jedním dotazem zjistit seznam chat a počtů obsazených dní v nich za dané období ($datum_od až $datum_do):
SELECT ch.nazev, COUNT(o.id) as pocet FROM chaty ch JOIN obsazenost o ON o.id_chaty = ch.id WHERE o.datum BETWEEN '$datum_od' AND '$datum_do' GROUP BY ch.id
...a procenta si spočítám v PHP, nebo to můžu celé udělat přímo v databázi, jen o něco složitějším dotazem:
SELECT ch.nazev, (100*COUNT(o.id) / (DATEDIFF('$datum_do', '$datum_od') + 1)) as obsazenost_procent FROM chaty ch JOIN obsazenost o ON o.id_chaty = ch.id WHERE o.datum BETWEEN '$datum_od' AND '$datum_do' GROUP BY ch.id

1. jsem si nechal jako druhé, protože ve 2. jsem napsal dotaz na zjištění počtu obsazených dní v daném intervalu, který vpodstatě řeší i tohle. Stačí mi jen vybrat chaty, který mají počet obsazených dní nulový:
SELECT ch.nazev FROM chaty ch JOIN obsazenost o ON o.id_chaty = ch.id WHERE o.datum BETWEEN $datum_od AND $datum_do GROUP BY ch.id HAVING COUNT(o.id)=0

3. Tohle je s těmi ostatními návrhy tabulky docela oříšek, s tím "mým" by to pro začátek byl nějaký takovýhle dotaz:
SELECT datum, COUNT(id) as pocet_obsazenych FROM kalendar_udalosti GROUP BY datum ORDER BY pocet_obsazenych
...dny seřazené od toho, kdy bylo nejvíc plno. Jediný problém může být s tím, že v tomhle výpisu nebudou dny, kdy bylo úplně prázdno (tj. 0 obsazených).
ninja
Profil
spartan13: Nechte si poradit od Jokera, radí vám dobře.
spartan13
Profil
ninja:
O tom nepochybuji, jen se snažím pochopit proč jsou mé postupy špatné...
Joker:
Z těchto příkladů mi to už snad trošku došlo, já bych vlastně využíval z databáze jen její "část" jsem zvyklý pracovat hodně s php a nevyužívám tak plný potenciál databází.
Děkuji za cenné rady.
Nebo chcete udělat: SELECT * FROM tabulka, pak si to celé načíst do PHP a tam už to z těch dat nějak vydolovat?
jak už jsem psal tohle je moje velká chyba..

budu mít tedy databázi, kde se budou moci přihlašovat lidé podle jejich id a hesla.

Měla by tabulka tedy vypadat spíše:
id  |  heslo  |  jméno  |  e-mail  |  ....


nebo spíše (takto si myslím, že by to mělo být)
prihlaseni
id  |  heslo


kontakty
id  |  jméno  |  e-mail  |  icq  |  telefon

-u těchto dvou mi jde spíše o to, že je spojovat nemá smysl, celkově takhle zaberou více místa ale dá se s nimi pracovat jednotlivě-nikdy nepotřebuji najednou všechna data. A pak by mohla být rychlost větší, ačkoliv velikost by byla také větší.


pak samozřejmě ještě spousta dalších tabulek jako už avizované termíny,...
spartan13
Profil
Joker:
ještě kdybych tedy udělal obsazenost, tak jak jste navrhoval - 1 řádek s ID, druhý řádek s datumem a nechal bych záznamy třeba na 2 roky → až 700 možných řádků na jedno ubytování taková tabulka by mohla mít strašně velké rozměry (v případě cest. kanceláří apod. které jsou už zaběhlé tak např. 2000x700=1 400 000 řádků a odhadem kolem 10MB což by asi takový problém nebyl ale počet řádků mi příjde astronomický.)
ninja
Profil
spartan13: Nevidím důvod rozdělovat tabulku prihlaseni a kontakty. Mělo by to význam pouze v případě, že by se jednalo o obrovskou a velmi nerovnoměrně využívanou tabulku.

Počet řádek v databázi není problém, jen je potřeba nastavit dostatečně velký typ čísla pro sloupec id. A vhodné indexy.
spartan13
Profil
ninja:
Počet řádek v databázi není problém, jen je potřeba nastavit dostatečně velký typ čísla pro sloupec id. A vhodné indexy.
jelikož id bude označovat pouze id ubytování tak bohatě postačí integer se svými 16 bity, dle mého.
Není přeci potřeba dávat tam nějaké další id když se tam budou pouze ukládat datumy, které jsou obsazené.

Ono v té tabulce bude ještě dost dalších záznamů takže jeden řádek bude mít mezi 5-10kB a to přihlašování bude potřeba jen málokdy
spartan13
Profil
tak snad už poslední dotaz. Nyní mám tabulku, kde je dáno id ubytování, heslo,nějaké druhy kontaktu a dalších informací-asi 8 sloupců každý cca 40B , 4 typy popisů-celkem 4kB, cca 10 popisků do 50 znaků a cca 10 booleanů ve kterých je uvedeno, co v ubytování je či není. (Další tabulka bude na volné termíny.)

Ptám se, jestli je rozumné udělat takto velkou tabulku (přes 30 sloupců a velikost řádku asi 7kB) budu tuto tabulku používat k vyhledávání vhodného ubytování, nebo mám raději udělat jednu tabulku, kde budou všechny věci, co se budou moci zadat do vyhledávání a popisky apod. dát do jiné? Také budu dělat vyhledávání podle obsazení termínů na styl jak radil JOKER.
Alphard
Profil
Na můj vkus moc počítáte velikost a nedostatečně promýšlíte strukturu. Rezervační systém je podle mě jedna z nejtěžších věcí, které se na webu mohou objevit. Horší jsou už snad jen eshopy a různé sportovní tabulky (internetové bankovnictví apod. řadím do úplně jiné kategorie).

cca 10 popisků do 50 znaků a cca 10 booleanů ve kterých je uvedeno, co v ubytování je či není.
Je vážně vše unikátní, nešlo by třeba rozdělit výbavu do několika skupin? Kdyby se logicky nazvaly, bylo by to přehlednější i pro klienty.
Do jedné tabulky patří údaje na sobě závislé a patřící k sobě. Je na sobě id ubytování, heslo a popis nějaké chaty závislý? Odpovězte si sám, já neznám situaci, ale moc se mi to nezdá.
V rozsáhlejších systémech bývají i desítky tabulek, to není chyba.
Viděl bych to minimálně na tabulku klientů, chatek, a rezervací (tj. kdo, kde, kdy).
spartan13
Profil
Alphard:
Nyní jsem předělal svůj přeběžný návrh na celkových 7 tabulek kde 3 tabulky jsou na vyhledávání-hlavní (4 parametry) potom rozšířené vyhledávání (boolean- je přítomno-není) a nakonec podle volných termínů.

Další 4 tabulky jsou informační (info pro mě, kontakty pro zákazníky, info o chatě a poslední tabulka další informace o místě)
tiso
Profil
spartan13: najprv by si si mal prečítať teóriu návrhu databázových štruktúr, pochopiť ju, a až potom vymýšľať tabuľky. Fakt. Bez toho to nepôjde.
spartan13
Profil
tiso:
můžete uvést třeba zdroj, kde je to dobře popsáno? (v češtině, anglicky umím málo)

zkoušel jsem vyhledávat ale "nic" moc co by mi objasnilo danou problematiku jsem nenašel. Ale aspoň jsem si přečetl o indexování-rychlosti vyhledávání apod.
tiso
Profil
spartan13: http://www.martinus.sk/?uItem=24744

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: