Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Laatste reacties met titel

Pagina: 1
Acties:

  • Sh4wn
  • Registratie: December 2006
  • Laatst online: 12-11-2017

Sh4wn

Bio-informatica

Topicstarter
Voor mijn site heb ik meerdere onderdelen waarop je kan reageren. Het leek mij niet echt handig om voor elk onderdeel een apart comment tabel te maken, dus heb ik 1 universeel comment tabel. Dat tabel heeft een veld 'type', waarmee ik kan onderscheiden waar welke comment hoort.

Nu kom ik op een probleem: Hoe kan ik efficient de laatste x reacties ophalen, maar ook de titel van het item waarbij de comment hoort. Die titel staat natuurlijk niet in het comment tabel, en ik weet bijna zeker dat dit niet in 1 query gaat lukken.

  • Tukk
  • Registratie: Januari 2002
  • Laatst online: 18-11 16:18

Tukk

De α-man met het ẞ-brein

Vragen:
-Welke database gebruik je?
-Waar staan de titels van de reacties wel?
-Heb jij ergens datumvelden?

Hint:
- Zoeken eens op joinen van tabellen.

Q: How many geeks does it take to ruin a joke? A: You mean nerd, not geek. And not joke, but riddle. Proceed.


  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 17-11 21:22
Dat is niet zo heel moeilijk, als ik het zo uit m'n hoofd doe:

SQL:
1
select * from comment, titel where titel.id=comment.titel_id and titel.id=$id limit...


ervan uitgaande dat titel als sleutel id heeft, en in de comment tabel een foreign key staat naar titel.id met als naam titel_id.

[ Voor 27% gewijzigd door trinite_t op 05-05-2008 14:17 ]

The easiest way to solve a problem is just to solve it.


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
En wat heeft dit met SEA te maken?
Waar hoort mijn topic?

SEA >> PRG

Verder zou het handig zijn als je ons voorziet van info over de tabellen zoals je ze gebruikt en als je eens laat zien wat je al geprobeerd, gezocht en gevonden hebt en wat er dan niet werkt. Hoe ver kom je wel? En waar loopt het dan mis?

Kijk ook eens even in Hoe werken joins? voor handige info die je geheid nodig gaat hebben ;)

[ Voor 63% gewijzigd door RobIII op 05-05-2008 14:21 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • truegrit
  • Registratie: Augustus 2004
  • Laatst online: 18-11 23:46
Aangenomen dat de titels in meerdere tabellen staan, waardoor je ook geen foreign key hebt, zal je toch met IF statements moeten gaan werken binnen SQL, maar daar heb ik zelf nog nooit mee gewerkt dus concrete informatie kan ik niet geven.

hallo


  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Het probleem van TS is waarschijnlijk dat ie alleen de ids en type van de content in z'n reactietabel staan. De vraag is dus heo haal ik zo makkelijk mogelijk de titels (die in verschillende tabellen staan op).

Het makkelijke antwoord: doe voor iedere comment een select.
Het moeilijke antwoord: Doe eerst je comments ophalen, filter dan de ID's eruit per type en haal per type de titels op. Deze merge je dan weer in je PHP.

Nog een mogelijkheid maar niet aan te raden, Join al je tabellen en ga met CASE aan aan de slag.

On track


  • Sh4wn
  • Registratie: December 2006
  • Laatst online: 12-11-2017

Sh4wn

Bio-informatica

Topicstarter
Jongens, zoals ik al zei: Er zijn meerdere 'types' van reacties. De een voor bijv. artikelen, de ander voor nieuws. Een ander type kan bijv. weer voor scripts zijn.

Ik wil dus de laatste x reacties, inclusief het de titel van bijv. het script/artikel/nieuwsbericht. Dat is niet zo simpel op te lossen met een JOIN. De titel van dat nieuws/artikel/etc staat dus in hun eigen tabel. Aangezien de DB structuur van artikelen/scripts etc niet exact hetzelfde is, wordt dat best lastig.

DB Structuur van de comments tabel + bijv. scripts en nieuws.
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
-- phpMyAdmin SQL Dump
-- version 2.11.4
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: May 05, 2008 at 04:41 PM
-- Server version: 5.0.51
-- PHP Version: 5.2.5

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Database: `id0241_main`
--

-- --------------------------------------------------------

--
-- Table structure for table `comments`
--

CREATE TABLE `comments` (
  `comment_id` int(10) unsigned NOT NULL auto_increment,
  `item_id` int(10) unsigned NOT NULL,
  `comment_author` varchar(50) NOT NULL,
  `comment_email` varchar(50) NOT NULL,
  `comment_website` varchar(100) NOT NULL,
  `comment_text` text NOT NULL,
  `comment_date` int(10) unsigned NOT NULL,
  `comment_type` tinyint(2) NOT NULL,
  `comment_ip` varchar(15) NOT NULL,
  PRIMARY KEY  (`comment_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=153 ;

-- --------------------------------------------------------

--
-- Table structure for table `news`
--

CREATE TABLE `news` (
  `news_id` int(10) unsigned NOT NULL auto_increment,
  `news_title` varchar(150) NOT NULL,
  `user_id` int(11) NOT NULL,
  `news_text` text NOT NULL,
  `news_extended` text NOT NULL,
  `news_date` int(11) NOT NULL,
  PRIMARY KEY  (`news_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=29 ;

-- --------------------------------------------------------

--
-- Table structure for table `scripts`
--

CREATE TABLE `scripts` (
  `script_id` int(10) unsigned NOT NULL auto_increment,
  `script_name` varchar(100) NOT NULL,
  `script_language` varchar(20) NOT NULL,
  `script_desc` text NOT NULL,
  `script_date` int(11) unsigned NOT NULL,
  PRIMARY KEY  (`script_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
Het moeilijke antwoord: Doe eerst je comments ophalen, filter dan de ID's eruit per type en haal per type de titels op. Deze merge je dan weer in je PHP.
Aan zo iets zat ik ook te denken :)

[ Voor 4% gewijzigd door Sh4wn op 05-05-2008 16:45 ]


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Gewoon filteren op type en joinen. Je kan ook die type conditie in de join on clause zetten, is het des te duidelijker dat die bepaalde relatie enkel bij dat type opgaat.

Sim-pel.
WouZz schreef op maandag 05 mei 2008 @ 16:11:
Het makkelijke antwoord: doe voor iedere comment een select.
Het moeilijke antwoord: Doe eerst je comments ophalen, filter dan de ID's eruit per type en haal per type de titels op. Deze merge je dan weer in je PHP.
...
Bah. Nofi, maar adhv de startpost zie ik niet waarom het met meerdere queries en omslachtige constructies gedaan moet worden. ;) Jouw 'moeilijke antwoord' is gewoon een PHP versie van iets dat je met een join hoort te doen. Een join schrijven is, vooropgesteld dat je de moeite wil nemen om te leren hoe joins werken (wat uberhaupt wel heel nuttige kennis is :> ), echt 10x eenvoudiger.
Sh4wn schreef op maandag 05 mei 2008 @ 16:41:
Aan zo iets zat ik ook te denken :)
Niet doen, want met deze tabel structuur kan je gewoon joinen.

(maar een beter datamodel is altijd de beste oplossing)

[ Voor 12% gewijzigd door Voutloos op 05-05-2008 17:11 ]

{signature}


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Begrijp ik nou goed dat "item_id" een FK is die naar verschillende tabellen kan verwijzen aan de hand van "comment_type"?

Dat lijkt me niet echt een mooie oplossing. Zo kan je ook geen goede constraints meer op je FK leggen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • remmelt
  • Registratie: Januari 2001
  • Laatst online: 09-04 12:25
Volgens mij werkt het niet met een simpele join. Je moet dan sowieso left joinen omdat niet elk comment.item_id een corresponderende script_id oid heeft in elke gejoinde tabel, bovendien heb je dan resultsets die er zo uit zien:

comment_id, comment_*, script_id, news_id, etc, waar alle *_id dingen leeg zijn behalve 1, tenzij je item_id in meerdere tabellen voorkomt wat in dit geval best mogelijk zou kunnen zijn.

Je zult dus inderdaad moeten filteren op item_type. Je kan natuurlijk wel 4 verschillende selects doen, elk met een simpele join, en wel zo:
code:
1
select * from comment c join script s on s.id=c.id where c.type='script'
(pseudocode) en dat dan per item type.

Persoonlijk vind ik dit niet een hele beste oplossing omdat je geen foreign keys kan maken. Foreign keys zijn je vriend! Als je je commentstabel wil generaliseren, kan je eraan denken ook je overige content algemeen te maken. Een cms als Drupal doet dat ook. Dit maakt je code wel veel moeilijker...

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
remmelt schreef op maandag 05 mei 2008 @ 17:00:
Persoonlijk vind ik dit niet een hele beste oplossing omdat je geen foreign keys kan maken. Foreign keys zijn je vriend! Als je je commentstabel wil generaliseren, kan je eraan denken ook je overige content algemeen te maken. Een cms als Drupal doet dat ook. Dit maakt je code wel veel moeilijker...
Je kan idd gewoon een Item tabel maken waar elk NewsItem of ScriptItem dan naar verwijst. Elk Comment verwijst dan weer naar een Item.

Alle overeenkomstige attributen van NewsItem en ScriptItem ( Naam?, PostDatum?, Poster? ) kan je dan in de Item tabel stoppen.

Een andere oplossing is gewoon een Comment Tabel maken en per type Item een aparte koppel tabel. Maar een variabele FK is gewoon niet echt elegant.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • dusty
  • Registratie: Mei 2000
  • Laatst online: 14-10 13:38

dusty

Celebrate Life!

De oplossing die je zoekt: Joins en Unions gecombineerd.

Resultaat is een query en alle resultaten die je wilt hebben.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Voutloos schreef op maandag 05 mei 2008 @ 16:45:
Gewoon filteren op type en joinen. Je kan ook die type conditie in de join on clause zetten, is het des te duidelijker dat die bepaalde relatie enkel bij dat type opgaat.

Sim-pel.
[...]
Niet doen, want met deze tabel structuur kan je gewoon joinen.

(maar een beter datamodel is altijd de beste oplossing)
Dus jij stelt het volgende voor:

SQL:
1
2
3
4
5
6
7
8
9
SELECT 
  comment_id,
  IF(news.title <> NULL, news.title, IF (
    script.title <> NULL, scripts.tile, 'no title'
  ) AS title
FROM
   comments AS c
LEFT JOIN news AS n ON (c.type = 1 AND c.item_id = n.news_id)
LEFT JOIN scripts AS s ON (c.type = 2 AND c.item_id = s.script_id)


Doe je dit ook zodra je 10 verschillende types hebt?

On track


  • remmelt
  • Registratie: Januari 2001
  • Laatst online: 09-04 12:25
Nee, dat laatste kan niet. Stel je voor, je script tabel heeft een script met id 1 en je news tabel heeft een news met id 1. Dit kan gewoon, het zijn tenslotte auto_increments die van elkaar niks weten. Stel je zoekt de titel voor een comment met item_id 1. Deze laatste select kiest dan altijd voor de news.title, terwijl in de item_type bijvoorbeeld script staat. Verder is coalesce misschien beter.

Nog even een opmerking terzijde: ik zie dat je myisam gebruikt. Ga over op innodb en je kan ook foreign keyen! Lekker is dat. Voorts raad ik je aan om utf8 te gebruiken voor alles. Vergeet latin1. Dat wordt hard huilen bij de eerste umlaut die je tegenkomt, laat staan bij hele andere tekensets zoals Chinees oid.

dusty's oplossing is met de gegeven datastructuur inderdaad het best:
code:
1
2
3
select c.*, s.titel from comment c join script s on s.id=c.id where c.type='script'
union
select c.*, n.titel from comment c join news n on n.id=c.id where c.type='news'

(pseudocde)

Het is niet geweldig maar het doet wel wat je wil.

  • trinite_t
  • Registratie: Maart 2003
  • Laatst online: 17-11 21:22
Waarom niet gewoon een goede database structuur opzetten?

Volgens mij, als ik nu het probleem nu zo lees, heb je iets met nieuwsitems met verschillende types, en comments die bij een bepaald nieuwsitem horen. Als ik dat zou moeten bouwen zou ik zelf het volgende doen:

3 tabellen (kolommen zijn hetgeen tussen haakjes):
types(id, naam)
nieuws(id, type_id, titel, text, enz)
comments(id, nieuws_id, text, enz)

dan zet je op alle id kolommen een primairy key, type_id is dan een foreign key van types.id en nieuws_id is een foreign key van nieuws.id.

(voor de foreign keys moet je wel innodb als db gebruiken).

Met deze structuur ben je volgens mij veel flexibeler en kun je gewoon joins gebruiken om de goede data te krijgen.

The easiest way to solve a problem is just to solve it.


  • remmelt
  • Registratie: Januari 2001
  • Laatst online: 09-04 12:25
Precies, dat is natuurlijk een cleanere oplossing. Zoals ik al zei: content algemeen maken. Je kan dit zo ver doorvoeren als je zelf wilt, want alles is een content-ding. Dan maak je nog een aparte tabel met relaties en relatietypes en dan heb je alweer een heel cms bij elkaar geprogrammeerd...

Succes!

  • Sh4wn
  • Registratie: December 2006
  • Laatst online: 12-11-2017

Sh4wn

Bio-informatica

Topicstarter
Hmm dat is inderdaad wel een goede oplossing. Mag ik wel weer flink veel dingen gaan veranderen, maar goed :)

  • remmelt
  • Registratie: Januari 2001
  • Laatst online: 09-04 12:25
Maak je gebruik van een ORM laag?
Pagina: 1