Autor Zpráva
JardaB
Profil
Zdravím, je možné zadávat dotazy pomocí reg. výrazu, kdy mám porovnání v UTF-8

Potřebuji vyřešit následující.. ve sloupci regiony mám uloženy podobné řetězce 256|257|280|288|300 ..., kdy jednotlivá čísla odpovídají id regionu. Potřebuji formulovat dotaz tak aby např. následující řetězec dotazu vyhověl tomu v tabulce: 150|280|288|289|300|305

je to reálné nebo bych musel požadavek rozložit na jedlotlivá LIKE, to ale nechci, protože dotaz může obsahovat i 100 regionů. Případně uvítám vhodnější model ukládání a dotazování.

Tímto způsobem ukládám působnosti firem v daných regionech a klient firmy může hledat tak, že buď zadá jeden region, což je snadné, ale chci aby měl možnost zaklikat více nebo většinu regionů ČR, což už je problém..
Joker
Profil
JardaB:
ve sloupci regiony mám uloženy podobné řetězce 256|257|280|288|300
To je častá chyba při návrhu databáze.
Zmeňte způsob ukládání těch dat.
Jestli „už to běží a změnit to by bylo pracné“, vězte, že na problémy jako tenhle budete narážet každou chvíli a čím déle to potrvá, tím to bude horší.
JardaB
Profil
původně to mělo fungovat jen jako dotaz na konkrétní region, což stačilo.. chápu že navrhnout by to šlo jinak.. ale každé jiné řešení obnáší složitější strukturu a větší počty tabulek... Předělat by to ještě nemusel být problém, napadá vás efektivní řešení jak ukládat id regiony pro jednotlivé firmy tak, aby výše uvedené dotazy šlo formulovat jednoduše?
peta
Profil
JardaB:
Normalni propojovaci tabulkou?
id_firma, id_region
1, 150
1, 280
1, 288
...
A pak normalni LEFT JOIN do sql dotazu.
SELECT * ... WHERE id_region IN (150,280,288)

Vyhledavani pomoci like je pomale a pracne pro sql, protoze to vyhledava retezec ('150' = cislo o velikosti 255 na 3) a ne cislo (150 = cislo o velikosti 255 na 1), to je trojnasobek casu jen na jednom cisle.
JardaB
Profil
O tom že LIKE je pomalejší vím, ale tímhle budu mít tabulku navíc s obrovským kvantem záznamů. Ve finále např. 15 tis firem s průměrem 40 regionů na firmu, tedy 600 tis záznamů, to mi také nepřijde moc jako výhra.. Pokud navýším počty regionů, jako že ten úmysl je, tak může daná hodnota vzrůst i na trojnásobek.. Pokud tohle nevadí a vyhledávání tak bude efektivnější a rychlejší tak to předělám v tom problém asi nebude.
Kajman
Profil
Obecně 2 miliony řádků nejsou pro databáze problémem. Jsou na to stavěné. Když tam budete mít vhodné indexy, bude to mnohem svižnější.
peta
Profil
JardaB: Muzes tam pridat dalsi sloupec (kategorii), region priradis prislusne zemi. Indexy funguji urcite rychleji nez vyhledavani na kazdem radku v textu.

Jestli chces LIKE, tak spis reg. vyraz pro vsechny kombinace (pripadne to spoj do jednoho vyrazu, nechce se mi hledat ted, jak se to zapisuje)
nazev REGEXP '^150$'  OR -- sloupec shoduje se se 150
nazev REGEXP '^150,' OR -- sloupec  zacina 150 a pokracuje carkou
nazev REGEXP ',150$' OR -- sloupec konci carkou a 150
nazev REGEXP ',150,'  -- sloupec ma uprostred 150 odelene carkami
Nebo mozna fulltextove vyhledavani.
Ale rucim ti za to, ze to bude desne pomale, proti tabulce s indexy nad 600.000 radky.
http://zaachi.com/2008/03/03/php-mysql-vyhledavani.html
Joker
Profil
JardaB:
ale tímhle budu mít tabulku navíc s obrovským kvantem záznamů
To nevadí, databáze jsou dělané na procházení záznamů v tabulce. Naopak nejsou dělané na analýzu dat uvnitř sloupce.

Myšlenka mít co nejméně databázových tabulek i za cenu slučování různých hodnot v jednom sloupci (anebo připojování nesouvisejících sloupců k tabulce, takže pak různé sloupce tabulky drží údaje, které spolu nemají žádnou logickou souvislost) je od základu špatná.
V extrémní variantě to pak vede k jedné obrovské tabulce, ve které je všechno. A která je strašně pomalá. A taky pak stačí jeden špatný delete dotaz…
JardaB
Profil
mno nemám s tím problém to předělat a přidat jednu tabulku. Původní myšlenka byla vyhledávat jen na jeden region. Nicméně mi to vyhovovalo, protože to bylo i pro mne celkem hodně přehledné. V tabulce mám různé typy firem, kdy každá nevyužije max jednu nebo dvě volby ze všeho, tedy nevidím důvod proč kvůli právě těmto dvěma volbám dělat další tabulky jen proto, že nebudou obsazeny, když jde navíc jen o logický údaj.. Pokud budu mít na každou věc tabulku a udělám nešikovný delete klienta, tak stejně data ztratí návaznost, takže jestli deletnu všechny data nebo jen část bez další návaznosti, tak je to fuk. Stát se to může pravda.. ale od čeho dělám zálohy?
Pokud je předpoklad cca 15 tis záznamů s cca 20 sloupci, tak nevidím problém a nepředpokládám zásadní zpomalení dotazů.
aDAm
Profil
Tak už když byl předpoklad že k jednomu záznamů bude více než jedeno ID nějakého regionu se mělo v návrhu DB zvážit vytvoření velice jednoduché vazební tabulky a né to cpát jako řetězec zvláště pak když se uvažovalo hledání/filtrování nad těmito parametry.
Tori
Profil
JardaB:
Kdybyste jako oddělovač používal čárku, tak můžete vyhledávat funkcí FIND_IN_SET - je to rychlejší než regulár, ale pořád ještě pomalejší než vazební tabulka.
Joker
Profil
JardaB:
jestli deletnu všechny data nebo jen část bez další návaznosti, tak je to fuk
Jasně, v tomhle případě ano. To byla narážka na příběh té firmy, která v jedné nezálohované databázové tabulce držela úplně všechno od webu přes výplaty a účetnictví po stav skladu. A následně kvůli jednomu špatnému SQL dotazu zbankrotovala.

Jinak samozřejmě rozdělení do více tabulek není bezpečnostní opatření proti ztrátě dat.
Smysl toho je úplně jinde. Když řeknu raději normalizace databáze, je smysl zhruba trojí:
- Vůbec možnost některé informace do databáze uložit (u nenormalizované databáze se může stát, že reálný stav který nastal není možné v databázi reprezentovat).
- Vůbec možnost se na některé informace dotázat (to je to, co právě řešíme).
- Odstranění redundance dat a tzv. aktualizačních anomálií (to je stav, kdy je tentýž údaj v databázi na více místech a některé jeho výskyty mají rozdílné hodnoty).
JardaB
Profil
Děkuji všem za výklady... už se maká na předělávce a do budoucna se bude více myslet než konat. V každém případě prvotní záměr byl jak jsem uvedl, tedy nebyl předpoklad složitějších dotazů. Byl to spíš experiment, který se uchytil a má nyní jiné nároky, než se vůbec zamýšlelo.

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: