En måde at bruge VIEWs på
Jeg har lavet en simpel klasse der repræsenterer en MySQL-tabel. Den er meget simpel, og i constructor’en angiver man tabelnavn og primærnøgle, og så laver den bare en
1 | SELECT * FROM tabelnavn WHERE id = $id; |
Hvor tabelnavn og id er variable. Når man laver en instans af klassen udfra en user-tabel med id 5 laver man en
1 | $user = new User(5); |
Det oversætter min klasse så til:
1 | SELECT * FROM user WHERE userid = 5; |
Hvis jeg vel at mærke har kaldt min tabel user og primærnøglen userid i min klasse. Det der efterfølgende sker er, at klassen hælder alle felterne over i et array, og jeg kan efterfølgende hive feltet "name" ud som $user->getName(), eller gemme via $user->setName('Morten') der udfører en
1 | UPDATE tabel SET name = 'Morten' WHERE userid = 5; |
For at spare nogle databaseopslag kan man som andet argument selv sende felterne med. Fx.
1 2 | $row = mysql_fetch_assoc($result); $user = new User($row['userid'], $row); |
På den måde behøver min klasse ikke lave noget opslag. Det var egentlig ikke klassen jeg ville snakke om. Skriv hvis I vil se noget kode eller høre mere :)
Det jeg ville nævne var en smart finte (synes jeg selv :)). Først laver jeg en tabel til mine brugere:
1 2 3 4 5 6 | CREATE TABLE user ( userid INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, newsletter TINYINT(1) UNSIGNED NOT NULL, PRIMARY KEY (userid) ); |
Så fylder jeg lidt folk i:
1 2 3 4 5 6 | INSERT INTO user (name, gender, newsletter) VALUES ('Alfred', 1), ('Bent', 0), ('Conni', 1), ('Dorthe', 1), ('Else', 0); |
Nu laver jeg et VIEW til folk der abonnerer på nyhedsbrevet:
1 2 | CREATE VIEW newsletter AS SELECT * FROM user WHERE newsletter = 1; |
Det resultat som min VIEW returnerer kan jeg umiddelbart smide direkte over i min MySQL-klasse som:
1 2 3 4 | $result = mysql_query("SELECT * FROM newsletter"); while($row = mysql_fetch_assoc($result)) { $user = new User($row['userid'], $row); } |
Min klasse laver aldrig noget opslag selv, og da den ved hvilken tabel det stammer fra kan jeg også fint gemme. Det er måske nemmere at se det anvendelige hvis mit VIEW var mere kompliceret. Men forestil jer at jeg fx vil sende en e-mail til alle brugere at BedsteVen.dk der har oprettet en annonce, men ikke tilføjet noget billede, og deres annonce udløber om 14 dage, og der er mindre end 10 personer der har set den. Så begynder det at være meget rart at have det som et VIEW.
Toplister med views
Det er tit jeg har en struktur hvor jeg har en tabel med fx annoncer, og så en tabel der gemmer antal visninger. En måde hvorpå man nemt kan arbejde med sin annonce-tabel og samtidig have let adgang til antal visninger er ved at oprette et VIEW.
Først opretter jeg min annonce-tabel:
1 2 3 4 5 | CREATE TABLE item ( itemid INT(10) unsigned NOT NULL auto_increment, name VARCHAR(255) NOT NULL, PRIMARY KEY (itemid) ) ENGINE=MyISAM; |
Så smider jeg lidt data i (ja, det er meget simple annoncer):
1 2 | INSERT INTO item (itemid, name) VALUES (1, 'Peter'), (2, 'Bente'), (3, 'Hans'), (4, 'Grete'); |
Så laver jeg en tabel til at gemme visninger. Jeg gemmer itemid og tidspunktet for visningen:
1 2 3 4 5 | CREATE TABLE item_views ( itemid INT(10) unsigned NOT NULL, viewtime DATETIME NOT NULL, KEY itemid (itemid, viewtime) ) ENGINE=MyISAM; |
Så smider jeg nogle visninger i:
1 2 3 4 5 6 | INSERT INTO item_views (itemid, viewtime) VALUES (1, '2008-09-18 15:06:16'), (1, '2008-09-18 15:06:24'), (1, '2008-09-18 15:06:29'), (1, '2008-09-18 15:06:36'), (1, '2008-09-18 15:06:37'), (3, '2008-09-18 15:06:45'), (3, '2008-09-18 15:06:46'), (3, '2008-09-18 15:06:47'), (4, '2008-09-18 15:06:51'), (4, '2008-09-18 15:06:58'); |
Til sidst kommer mit VIEW
1 2 3 4 5 6 | CREATE VIEW myview AS SELECT item.*, COUNT(item_views.itemid) AS total_views FROM item LEFT JOIN item_views USING (itemid) GROUP BY itemid ORDER BY itemid ASC; |
Tricket med mit VIEW er, at jeg laver en “SELECT item.*” så jeg får hele item-tabellen (annoncer). Så kombinerer jeg det med en COUNT. Jeg får derfor hele item-tabellen og antallet af visninger ud på samme tid.
Bemærk at jeg laver min COUNT på item_views.itemid for at undgå at item-rækken tæller med hvis den ikke optræder i item_views-tabellen.
Laver man nu en:
1 | SELECT * FROM myview; |
Får man følgende:
itemid, name, total_views
1, Peter, 5
2, Bente, 0
3, Hans, 3
4, Grete, 2

Jeg hedder Morten, og jeg har udviklet webapplikationer siden slutningen af 90'erne.