Společnost ARM představila platformu Arm Lumex s Arm C1 CPU Cluster a Arm Mali G1-Ultra GPU pro vlajkové chytré telefony a počítače nové generace.
Unicode Consortium, nezisková organizace koordinující rozvoj standardu Unicode, oznámila vydání Unicode 17.0. Přidáno bylo 4 803 nových znaků. Celkově jich je 159 801. Přibylo 7 nových Emoji.
Apple představil (YouTube) telefony iPhone 17 Pro a iPhone 17 Pro Max, iPhone 17 a iPhone Air, sluchátka AirPods Pro 3 a hodinky Watch Series 11, Watch SE 3 a Watch Ultra 3.
Realtimová strategie Warzone 2100 (Wikipedie) byla vydána ve verzi 4.6.0. Podrobný přehled novinek, změn a oprav v ChangeLogu na GitHubu. Nejnovější verzi Warzone 2100 lze již instalovat také ze Snapcraftu a Flathubu.
Polské vývojářské studio CD Projekt Red publikovalo na Printables.com 3D modely z počítačové hry Cyberpunk 2077.
Organizátoři konference LinuxDays 2025 vydali program a zároveň otevřeli registrace. Akce se uskuteční 4. a 5. října na FIT ČVUT v pražských Dejvicích, kde vás čekají přednášky, workshopy, stánky a spousta šikovných lidí. Vstup na akci je zdarma.
Uživatelé komunikátoru Signal si mohou svá data přímo v Signalu bezpečně zálohovat a v případě rozbití nebo ztráty telefonu následně na novém telefonu obnovit. Zálohování posledních 45 dnů je zdarma. Nad 45 dnů je zpoplatněno částkou 1,99 dolaru měsíčně.
Server Groklaw, zaměřený na kauzy jako právní spory SCO týkající se Linuxu, skončil před 12 lety, resp. doména stále existuje, ale web obsahuje spam propagující hazardní hry. LWN.net proto v úvodníku připomíná důležitost zachovávání komunitních zdrojů a upozorňuje, že Internet Archive je také jen jeden.
Jakub Vrána vydal Adminer ve verzi 5.4.0: "Delší dobu se v Admineru neobjevila žádná závažná chyba, tak jsem nemusel vydávat novou verzi, až počet změn hodně nabobtnal."
V Německu slavnostně uvedli do provozu (en) nejrychlejší počítač v Evropě. Superpočítač Jupiter se nachází ve výzkumném ústavu v Jülichu na západě země, podle německého kancléře Friedricha Merze otevírá nové možnosti pro trénování modelů umělé inteligence (AI) i pro vědecké simulace. Superpočítač Jupiter je nejrychlejší v Evropě a čtvrtý nejrychlejší na světě (TOP500). „Chceme, aby se z Německa stal národ umělé inteligence,“ uvedl na
… více »Ř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:
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: