MySQL Question

2 отговора 177 прегледа
#1

MySQL Question

imam slednata tablica:
========
downloadID int(11)
productID int(11)
isUpdate enum('yes','no')
timestamp timestamp(14)
========
tablicata se indeksira po downloadID. triabva da izmislia dve zaiavki, koito praviat slednoto:

1) ot vsichki elementi s isUpdate = 'yes' da vzima poslednia za vseki razlichen productID, t.e. rezultatat ot zaiavkata triabva da e s spisak ot downloadID's, za koito isUpdate = 'yes' pri tova productID na vseki element ne se povtariat. pri tova,
tozi edin element, triabva da e poslednia po timestamp za opredelenia productID

2) vzima vsichki elementi s isUpdate = 'no', za koito niama drugi elementi v tablicata sas sashtoto productID i isUpdate = 'yes', kato gi podrejda po timestamp.

Rabotata e tam, che MySQL ima izvestni (GOLEMI mai) ogranichenia kato lipsa na Subqueries ... :(

Blagodaria predvaritelno

Отговор
в отговор на exodus #2

Re: MySQL Question

А стига бе. Допреди малко обяснявах точно този случай на един в IRC

Значи решенията са 2
1. TEMPORARY TABLE - доста приятно работят в MySQL
2. Денормализирана структура със втора таблица - там пък трябва да се грижиш за синхронизацията, но пък е значително по-бърз вариант при големи таблици.
Малко забележки преди това:
* Избягвай да използваш резервирани думи като timestamp за имена на колони - просто като стил на писане. Спестява главоболия
* Препоръчвам ти enum('no', 'yes') вместо y, n - enum в някои ситуазии може да работи като масив с индекс от 0 . т.е. ще получиш 0->no, 1->yes
* Задължително индексирай timestamp, а също и productID - EXPLAIN ще ти каже защо :)


1. всъщност симулира работата на subselect

1. create temporary table temp select downloadID, productID, max(timestamp) as ts where isUpdate = yes group by productID;

select ... Ами тука се надявам да се сетиш как да направиш join между твоята таблица и temp :)

подсказка select ... from temp, tbl where temp.ts = tbl.timestamp ...;

2. Същото това нещо на практика обаче със "постоянна" таблица
наречена примерно snapshot (downloadID, productID, timestamp)

И всеки път когато правиш INSERT в твоята си таблица (тя вече се превръща в чиста История на Промените)
правиш и REPLACE в Snapshot-a

Това определено печели време

А ако искаш да събереш двата резултата един след друг това не не работа за subselect а за UNION какъвто вече се подържа в mysql 4.0.x :)

Да ти обяснявам ли какво да направиш със 2) или сам ще се сетиш?

Linux is like a wigwam - No Windows, No Gates, Apache inside
Отговор
в отговор на exodus #3

Re: MySQL Question

Do Temp tablitsa mojesh da pribegnesh samo ako niama niakkvo drugo reshenie

Zapochvam s 2. shtoto may po-lesno uspiah da razbera kakvo iskash. A i mi se struva, che printsiput shte varvi i za 1. A printsiput e JOIN sus sebe si.

2. Neka tablitsata ti se kazva krusha

SELECT t1.downloadID, ... FROM krusha t1, krusha t2 WHERE ((t1.productID<>t2.productID AND t2.isUpdate='yes') OR t1.downloadID=t2.downloadID) AND t1.isUpdate='no' ORDER BY t1.timestamp

Отговор