Deno (Wikipedie), běhové prostředí (runtime) pro JavaScript, TypeScript a WebAssembly, bylo vydáno v nové verzi 2.9. Hlavní novinkou je deno desktop pro převod Deno projektu na desktopovou aplikaci. Jedná se o alternativu k frameworkům Electron nebo Tauri.
Od zítra jsou Datové schránky oficiálně na nové adrese datovka.gov.cz. Adresa mojedatovaschranka.cz zůstává funkční do 27. srpna 2026, následně budou uživatelé automaticky přesměrováni na datovka.gov.cz.
Dolphin (Wikipedie), tj. open source multiplatformní emulátor herních konzolí GameCube a Wii od Nintenda, byl vydán ve verzi 2606. S podporou Game Boy Playeru.
Vasudeva Kamath představil utilitu debvulns, alternativu k nativní utilitě debsecan, pro výpis zranitelností v Debianu. Navíc má především možnost výstupu ve strukturovaných formátech JSON a CSV. V plánu je exportér pro Prometheus.
Oficiální český státní eshop s elektronickými dálničními známkami nově najdete na edalnice.gov.cz. Doména gov.cz jasně potvrzuje, že jste na oficiálním státním webu [𝕏].
Byla vydána nová verze 4.8.0 interaktivního shellu fish (friendly interactive shell, Wikipedie). Přehled novinek v poznámkách k vydání.
Byl aktualizován seznam 500 nejvýkonnějších superpočítačů na světě TOP500. Nejvýkonnějším superpočítačem se nově stal čínský LineShine v Národním superpočítačovém centru v Šen-čenu (NSCS) s výkonem 2,198 exaFLOPS. Z prvního místa sesadil americký superpočítač El Capitan s výkonem 1,809 exaFLOPS. Nejvýkonnější český počítač C24 klesl na 215 místo. Karolina, GPU partition klesla na 249. místo a Karolina, CPU partition na 475. místo.
… více »Zemřel průkopník videoherní hudby Bobby Prince (Wikipedie). Složil hudbu pro hry Wolfenstein 3D, Doom, Doom II, Duke Nukem II a Duke Nukem 3D.
Počítačová hra Operace Flashpoint (Arma: Cold War Assault) od společnosti Bohemia Interactive slaví 25 let. Při této příležitosti bylo publikováno bezplatné hratelné Arma: Cold War Assault Remastered Demo a na GitHubu byly zveřejněny zdrojové kódy.
Na trh v České republice přichází HP EliteBoard G1a. Jde o plnohodnotný AI počítač integrovaný přímo do těla klávesnice, tedy zařízení, které na první pohled vypadá jako minimalistická klávesnice, ale ve skutečnosti nahrazuje klasickou počítačovou jednotku.
Řešení dotazu:
Výsledek bude stejný, v podstatě jde jen o syntaktický cukr a stačil by ti kartézský součin a podmínky ve WHERE.
Ale z hlediska čitelnosti má smysl to rozlišovat:
(toho bych se držel – aspoň v takto jednoduchých případech)
SELECT * FROM users LEFT JOIN services ON (services.user_id = users.id AND services.type = 1);
co je rozhodne citatelnejsie (hlavne pre planner) nez toto:
SELECT * FROM users LEFT JOIN (SELECT * FROM services WHERE services.type = 1) AS services ON (services.user_id = users.id);
SELECT * FROM users LEFT JOIN servises ON selrvices.user_id = users.id WHERE services.type = 1?
A také netuším, co myslíte pod "citelnější pro planner". Tomu je to u moderních databází jedno, protože se před optimalizací snaží o flattening (takhle je to nazvané v Postgresu), tj redukci zanořených dotazů, tam kde to jde. Obě dvě ukázky mi přijdou dost obskurní.
WHERE services.type = 1 odfiltruje aj takych users, ktori nemaju servis, kdezto ON (... AND services.type = 1) ich vo vysledku ponecha.
Takze ak by sa mal dodrziavat tento sposob zapisu, musela by ta podmienka vyzerat nejak takto: WHERE (services.type IS NULL OR services.type = 1). A mam skusenost, ze si s tym "OR" uz nie kazdy planner vie efektivne poradit.
WHERE services.type IS NULL OR services.type = 1.
Může se to týkat třeba tabulek, kde jsou verzovaná data a záznamy mají platnost od/do (ať už klasicky jako dva sloupečky nebo jako range). Můžu si chtít přiJOINovat záznamy z jiné tabulky – pokud existují – platné k určitému datu (což může být aktuální okamžik, datum nějakého jiného záznamu, datum zadané uživatelem pro daný dotaz…). A pak dám tu podmínku do ON, což je podle mého čitelnější, nebo ji dám do WHERE, ale tam musím přes OR/NULL ošetřit případy, kdy příslušné záznamy neexistují, což podle mého ten dotaz dost znepřehlední.
Přijde mi, že když je datový model navržený tak, že záznamy neodrážejí jen aktuální stav, ale verzují se (což je často nutnost), tak v té databázi vznikají souvislosti/pravidla, která moc nejde podchytit referenční integritou. Maximálně nějakým triggerem vynutit, že např. záznamy, které jsem provázal přes cizí klíč mají překrývající se platnost. Tzn. např. když zakládám žádost, tak ji nemůžu navázat na adresu, jejíž platnost už skončila.
Nicméně téměř vždy to signalizuje divně navrženou databázi (problémy s normalizací) nebo divně zadanou úlohu.
Je takový datový model tedy špatně? Jak se to dá dělat líp? Kdysi jsem se pokoušel podobná pravidla realizovat pomocí složených klíčů, ale bylo to dost šílené a navíc to vedlo na velkou duplikaci hodnot do více tabulek (ty dodatečné sloupce použité pro složené klíče), takže jsem od toho nakonec upustil. Prakticky všechny databáze, se kterými jsem se potkal, mají určité zákonitosti/pravidla, která nejsou explicitně vyjádřená referenční integritou a datovým modelem, takže DBMS o nich neví – řeší se to až na aplikační úrovni.
Dneska to jde řešit líp, i v Postgresu, což mě těší. Díky za tu prezentaci, myslím, že už jsem ji někde zahlídnul, ale teď jsem ji nemohl najít, teď pro jistotu ukládám na disk a do záložek :-) Vypadá to super. Ne všude je tohle k dispozici, ale verzovat se musí, takže se to řeší tím, co je.1
Já na tenhle problém narazil hlavně u různých bankovních systémů a jde o věci, které vznikaly před 20+ lety a od té doby jsou v produkci, průběžně se to sice rozvíjí, ale na nějaký přepis nebo větší změnu datového modelu v podstatě nikdo nemá odvahu. Naopak lidem straší v hlavě vzpomínky na pokusy, které nedopadly…
[1] většinou se tam narvou sloupečky valid_from a valid_to, případně se občas historie odlívá do samostatné tabulky, ale psát nad tím dotazy je ještě větší peklo
SELECT * FROM A LEFT JOIN B on (A.ISIN_CODE = B.ISIN_CODE and A.TRANS_START_DT <= B.TRAS_END_DT)
create table a(id int, x int); create table b(id int, y int); insert into a values(1, 10); insert into b values(1, 10); insert into b values(1, 0); postgres=# Select a.x/b.y from a join b on b.id = a.id where b.y <> 0; ┌──────────┐ │ ?column? │ ╞══════════╡ │ 1 │ └──────────┘ (1 row)Tak proč to nespadlo? Samozřejmě, že dnešní optimalizátory, tam kde to jde (sémanticky) napřed aplikují filtry z WHERE a teprve potom provedou spojení. Popravdě, řekl bych, že se tak chovají posledních 30 let.
postgres=# explain Select a.x/b.y from a join b on b.id = a.id where b.y <> 0 ; ┌───────────────────────────────────────────────────────┐ │ QUERY PLAN │ ╞═══════════════════════════════════════════════════════╡ │ Nested Loop (cost=0.00..2.05 rows=1 width=4) │ │ Join Filter: (a.id = b.id) │ │ -> Seq Scan on a (cost=0.00..1.01 rows=1 width=8) │ │ -> Seq Scan on b (cost=0.00..1.02 rows=1 width=8) │ │ Filter: (y <> 0) │ └───────────────────────────────────────────────────────┘ (5 rows)Jinak, kdybych chtěl ošetřit skutečně bezpečně dělení nulou a podobné limitní případy, tak bych měl použít CASE. Když se někde potkáme, tak za pivko (ve vašem případě za dvě), vám můžu vysvětlit, jak fungují databáze. Když byste měl zájem.
Když se někde potkáme, tak za pivko (ve vašem případě za dvě), vám můžu vysvětlit, jak fungují databáze. Když byste měl zájem.Samozřejmě že nemá, on to přece ví. JOIN je FOR cyklus, WHERE je IF podmínka.
select a.x/b.y from a join b on b.id = a.id where b.y <> 0; select a.x/b.y from a join b on (b.id = a.id and b.y <> 0); explain select a.x/b.y from a join b on b.id = a.id where b.y <> 0; explain select a.x/b.y from a join b on (b.id = a.id and b.y <> 0);dává v obou případech
A.X / B.Y 1s plánem
SELECT
("A"."X" / "B"."Y")
FROM "PUBLIC"."B"
/* PUBLIC.B.tableScan */
/* WHERE B.Y <> 0 */
INNER JOIN "PUBLIC"."A"
/* PUBLIC.A.tableScan */
ON 1=1
WHERE ("B"."Y" <> 0)
AND ("B"."ID" = "A"."ID")
select a.x/b.y from a join b on b.id = a.id where b.y <> 0 Select a.x/b.y from a join b on (b.id = a.id and b.y <> 0)Takovým databázím doporučuji se vyhnout (a určitě nejsem jediný). Některé "databáze" pak skutečně mohou i "vygenerovat" rozdílné výsledky, možná i dokonce "SORRY VOLE ERROR". V těchto případech je doporučeno dodržet bezpečnou vzdálenost a při dotyku provést očistu postižených míst na disku:
Každopádně je dobré si chování dané databáze v těchto případech vyzkoušet.
.
WHERE, tj. vaše varianta B. Variantu A výjimečně používám, pokud je ten dotaz složitější a je potřeba zdůraznit to, že spojuji se službami typu 1 – když to pomáhá pochopení dotazu.
Tiskni
Sdílej: